公式: [[KeServiceDescriptorTable]+index(索引)*4] 

例如要读取 NtOpenProcess [[KeServiceDescriptorTable]+0x7A*4] 

 

1. 纯汇编读取

WinDbg推导公式 : dd poi[KeServiceDescriptorTable] + 0x7A*4 L 1

mul是无符号乘法
imul是带符号乘法

.cls 清屏

r ebx 读取寄存器的值

运行结果一致, 这样就读出了 NtOpenPorcess 的当前地址, 代码如下

 

 1         ULONG SSDT_NtOpenProcess_Cur_Addr;
 2     KdPrint(("驱动成功被加载...OK++++++++\n\n"));
 3     //读取SSDT表中 NtOpenProcess当前地址 KeServiceDescriptorTable
 4     // [[KeServiceDescriptorTable]+0x7A*4] 
 5 
 6     __asm
 7     {    
 8         int 3
 9         push ebx
10         push eax
11         mov ebx, KeServiceDescriptorTable
12         mov ebx, [ebx]
13         mov eax, 0x7A
14         imul eax, 4    // shl eax, 2
15         add ebx, eax
16         mov ebx,[ebx]
17         mov SSDT_NtOpenProcess_Cur_Addr, ebx
18 
19         pop eax
20         pop ebx        
21     }
22 
23     KdPrint(("SSDT_NtOpenProcess_Cur_Addr=%x\n\n",SSDT_NtOpenProcess_Cur_Addr));
View Code


2. 指针方法

定义一个KeServiceDescript结构

typedef struct _ServiceDescriptorTable {
    PVOID ServiceTableBase; //System Service Dispatch Table 的基地址  
    PVOID ServiceCounterTable;
    //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
    unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
    PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable;  
extern PServiceDescriptorTable KeServiceDescriptorTable;

调用指针, 获取基地址

    LONG *SSDT_Adr,SSDT_NtOpenProcess_Cur_Addr,t_addr; 
    KdPrint(("驱动成功被加载中.............................\n"));
    //读取SSDT表中索引值为0x7A的函数
    //poi(poi(KeServiceDescriptorTable)+0x7a*4)
    t_addr=(LONG)KeServiceDescriptorTable->ServiceTableBase;
    KdPrint(("当前ServiceTableBase地址为%x \n",t_addr));
    SSDT_Adr=(PLONG)(t_addr+0x7A*4);
    KdPrint(("当前t_addr+0x7A*4=%x \n",SSDT_Adr)); 
    SSDT_NtOpenProcess_Cur_Addr=*SSDT_Adr;    
    KdPrint(("当前SSDT_NtOpenProcess_Cur_Addr地址为%x \n",SSDT_NtOpenProcess_Cur_Addr));

运行截图如下:

 

 

 源码下载

运行环境 VS2010 

 

 

posted on 2014-01-10 16:53  萝卜哥  阅读(602)  评论(0编辑  收藏  举报