阅读:3086回复:7
初学Rootkit,有几个基础问题想搞明白买了本《ROOTKITS -Windows内核的安全防护》 看了前面几章,想亲手写几个HOOK API做下实验,里面有个例子是HideProcessHookMdl 有部分代码如下: #pragma pack(1) typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; //Used only in checked build unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; #pragma pack() __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)] ...... ...... ...... NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { // Register a dispatch function for Unload theDriverObject->DriverUnload = OnUnload; // Initialize global times to zero // These variables will account for the // missing time our hidden processes are // using. m_UserTime.QuadPart = m_KernelTime.QuadPart = 0; // save old system call locations OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation)); // Map the memory into our domain so we can change the permissions on the MDL g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); if(!g_pmdlSystemCall) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(g_pmdlSystemCall); // Change the flags of the MDL g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); // hook system calls HOOK_SYSCALL( ZwQuerySystemInformation, NewZwQuerySystemInformation, OldZwQuerySystemInformation ); return STATUS_SUCCESS; } 有几个疑问: 1. __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; 为什么要以DLL导出变量形式,而我在PE段里面没有看到导出的变量 2. 当定义了KeServiceDescriptorTable 之后,它的初始化在哪里完成的? 是不是下面几句初始化的? g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); if(!g_pmdlSystemCall) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(g_pmdlSystemCall); 3. MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); 这个函数的主要作用是什么? 小弟初学,想学精点,还望大牛们赐教 |
|
|
沙发#
发布于:2008-07-17 16:53
我刚调试了一下,MappedSystemCallTable 这个变量是指向新的内存,但是内存里面的内容和SSDT是一样的,这个意思好像是新分配了块内存可以修改了
但是我想老的SSDT还不是没有动,这相当于把SSDT的内容复制过来了,但是系统服务调用时会访问这块新的内存吗 |
|
|
板凳#
发布于:2008-07-22 17:46
通过几天的努力还是搞明白了,自己来解答下吧
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable 导入全局变量 KeServiceDescriptorTable MDL的作用是分配一起新的内存,但是通过对新内存的修改可以安全影响到原内存 |
|
|
地板#
发布于:2008-09-05 12:56
应该是这样的。
1。第一个问题你写过VC下使用DLL的时候的导入函数是一样的,驱动需要从外部导入这个表,这个表是以变量的形式被 ntoskrnl.exe 导出的。双核为 ntpa....(忘了怎么写的了)。驱动从外部导入这个表。导入原理跟EXE导入DLL差不多。 2.第二个问题就好理解了,既然是从外部导入的所以自然是有内容的。(有些人可能又误区,DLL不但能导出函数还能导出变量,甚至是类)。 3。第三个跟你说的差不多,因为SSDT默认是只读的,(不过我实际测试XP SP2下可以写,不过网上说只读,还是保险起见)因为是只读,所以修改SSDT的时候要让他可以写,一般常见方法是修改 CR0 寄存器,修改内存的写保护位,还有个比较常用的方法就是使用内存描述符表。也就是MDL |
|
|
地下室#
发布于:2008-12-04 11:34
楼上住哪呢,想拜访拜访,我经常蓝屏蓝恼火了。
|
|
5楼#
发布于:2008-12-30 10:20
感谢楼主!有些人在论坛上发贴请教,自己搞明白后只是说一句“这个问题解决了”楼主把解决方法贴出来,好!
|
|
6楼#
发布于:2009-08-31 10:07
想想你在remoteThread注入时一些函数地址是真么获取的
想想模块计数这个名词时啥,一切问题就解决了 |
|
|
7楼#
发布于:2009-09-21 20:58
第三个问题的个人理解,MmCreateMdl 申请一个新的虚拟地址空间来映射它,并且这个新的地址空间是用结构体MDL来描述的。这样,我们修改这个MDL时,SSDT也就受到影响了。
|
|