mhxueshan
驱动牛犊
驱动牛犊
  • 注册日期2008-06-12
  • 最后登录2011-02-20
  • 粉丝2
  • 关注0
  • 积分8分
  • 威望52点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3010回复:7

初学Rootkit,有几个基础问题想搞明白

楼主#
更多 发布于:2008-07-17 13:46

买了本《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); 这个函数的主要作用是什么?

小弟初学,想学精点,还望大牛们赐教
Artist
mhxueshan
驱动牛犊
驱动牛犊
  • 注册日期2008-06-12
  • 最后登录2011-02-20
  • 粉丝2
  • 关注0
  • 积分8分
  • 威望52点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-07-17 16:53
  我刚调试了一下,MappedSystemCallTable 这个变量是指向新的内存,但是内存里面的内容和SSDT是一样的,这个意思好像是新分配了块内存可以修改了
  但是我想老的SSDT还不是没有动,这相当于把SSDT的内容复制过来了,但是系统服务调用时会访问这块新的内存吗
Artist
mhxueshan
驱动牛犊
驱动牛犊
  • 注册日期2008-06-12
  • 最后登录2011-02-20
  • 粉丝2
  • 关注0
  • 积分8分
  • 威望52点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-07-22 17:46
通过几天的努力还是搞明白了,自己来解答下吧

__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable 导入全局变量 KeServiceDescriptorTable
 
   MDL的作用是分配一起新的内存,但是通过对新内存的修改可以安全影响到原内存
Artist
xyc2323
驱动牛犊
驱动牛犊
  • 注册日期2007-01-27
  • 最后登录2010-11-24
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望16点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-09-05 12:56
应该是这样的。

1。第一个问题你写过VC下使用DLL的时候的导入函数是一样的,驱动需要从外部导入这个表,这个表是以变量的形式被 ntoskrnl.exe 导出的。双核为 ntpa....(忘了怎么写的了)。驱动从外部导入这个表。导入原理跟EXE导入DLL差不多。

2.第二个问题就好理解了,既然是从外部导入的所以自然是有内容的。(有些人可能又误区,DLL不但能导出函数还能导出变量,甚至是类)。

3。第三个跟你说的差不多,因为SSDT默认是只读的,(不过我实际测试XP SP2下可以写,不过网上说只读,还是保险起见)因为是只读,所以修改SSDT的时候要让他可以写,一般常见方法是修改 CR0 寄存器,修改内存的写保护位,还有个比较常用的方法就是使用内存描述符表。也就是MDL
学海无涯
caseshadow
驱动牛犊
驱动牛犊
  • 注册日期2008-04-08
  • 最后登录2009-02-06
  • 粉丝1
  • 关注0
  • 积分4分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-12-04 11:34
楼上住哪呢,想拜访拜访,我经常蓝屏蓝恼火了。
win32fan
驱动牛犊
驱动牛犊
  • 注册日期2008-03-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望39点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-12-30 10:20
感谢楼主!有些人在论坛上发贴请教,自己搞明白后只是说一句“这个问题解决了”楼主把解决方法贴出来,好!
webxeyes
驱动牛犊
驱动牛犊
  • 注册日期2008-04-02
  • 最后登录2010-07-01
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望92点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2009-08-31 10:07
想想你在remoteThread注入时一些函数地址是真么获取的

想想模块计数这个名词时啥,一切问题就解决了
webxeyes
Steven Wang
驱动牛犊
驱动牛犊
  • 注册日期2008-01-24
  • 最后登录2010-06-27
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望76点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2009-09-21 20:58
第三个问题的个人理解,MmCreateMdl 申请一个新的虚拟地址空间来映射它,并且这个新的地址空间是用结构体MDL来描述的。这样,我们修改这个MDL时,SSDT也就受到影响了。
游客

返回顶部