SSDT的全称是System Services DescriptorTable,系统服务描述符表 在ntoskrnl.exe导出KeServiceDescriptorTable 这个表
typedefstructServiceDescriptorTable{
PVOID ServiceTableBase; //System Service DispatchTable的基地址
PVOIDServiceCounterTable(0);
//包含着SSDT中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices;//由ServiceTableBase 描述的服务的数目。
PVOID ParamTableBase;//包含每个系统服务参数字节数表的基地址-系统服务参数表
}
打开双击调试
dd KeServiceDescriptorTable
80553fa0 80502b8c 00000000 0000011c 80503000
80553fb0 00000000 00000000 00000000 00000000
80553fc0 00000000 00000000 00000000 00000000
80553fd0 00000000 00000000 00000000 00000000
80553fe0 00002710 bf80c0b6 00000000 00000000
80553ff0 f8b97a80 f8339b60 8201ca90 806e2f40
80554000 00000000 00000000 00000000 00000000
80554010 3aeb00c0 01cd83a3 00000000 00000000
第一列显示的时内存地址,也就是KeServiceDescriptorTable在内存里面的地址,这个不管
加黑的那个就是这个结构体的第一个值,也就是ServiceTableBase的值,这里存放SSDT的表项
dd 80502b8c (当然也可以 ddpoi[KeServiceDescriptorTable])
80502b8c 8059a948 805e7db6 805eb5fc 805e7de8
80502b9c 805eb636 805e7e1e 805eb67a 805eb6be
80502bac 8060cdfe 8060db50 805e31b4 805e2e0c
80502bbc 805cbde6 805cbd96 8060d424 805ac5ae
80502bcc 8060ca3c 8059edbe 805a6a00 805cd8c4
80502bdc 80500828 8060db42 8056ccd6 8053600e
80502bec 806060d4 805b2c3a 805ebb36 8061ae56
80502bfc 805f0028 8059b036 8061b0aa 8059a8e8
这里就是表项了..
命令ddpoi[KeServiceDescriptorTable]+0n17*4 l 1
80502bd0 8059edbe
这个是查看序号17的值,0n表示17是十进制表示,l 1表示只列出一个
这个17嘛就是索引号了。。
如何获取每个函数的索引号?(一般来说XP系统的索引号都不会变)
1.使用KD工具直接查看。
2.使用OD查看传入EAX的值就是索引号。比如openprocess就是7A=122 ZwOpenProcess
3.windbg直接u ZwOpenProcess
804ff720b87a000000 mov eax,7Ah
804ff725 8d542404 lea edx,[esp+4]
804ff729 9c pushfd
804ff72a 6a08 push 8
804ff72ce850ed0300 call nt!KeReleaseInStackQueuedSpinLockFromDpcLevel+0x95d(8053e481)
804ff731 c21000 ret 10h
nt!ZwOpenProcessToken:
804ff734b87b000000 mov eax,7Bh
804ff739 8d542404 lea edx,[esp+4]
NTKERNELAPI PVOID MmGetSystemRoutineAddress( IN PUNICODE_STRING SystemRoutineName );
代码
UNICODE_STRING Old_NtOpenProcess;
ULONG Old_Addr;
Old_Addr=(ULONG)MmGetSystemRoutineAddress(&Old_NtOpenProcess);//取得NtOpenProcess的地址
KdPrint(("取得原函数NtOpenProcess的值为 %x",Old_Addr));
如何获取当前的SSDT中的地址?
RtlInitUnicodeString(&Old_NtOpenProcess,L"NtOpenProcess");//当然
NtOpenProcess一定是一个到处函数
代码