首页
社区
课程
招聘
[原创]Win10 X64下SSDT表中的函数地址计算公式
发表于: 2018-12-2 04:15 9652

[原创]Win10 X64下SSDT表中的函数地址计算公式

2018-12-2 04:15
9652
想在Win10 x64下看下SSDT表中的函数,记得以前看雪上,某个前辈发了一篇x86下的Windbg脚本来显示SSDT函数。
今天需要使用的时候,翻出了这个脚本。但是需要修改下,但是网络上找到的公式,不适合Win10 x64系统。
自己逆向了下。

uf KiSystemServiceStart下的某一段代码, 不确定位置是否正确,但是经过验证,公式是正确的。
rax: 是索引值
r10: 是KeServiceDescriptorTable->KiServiceTable
nt!KiSystemServiceRepeat+0x35:
fffff801`12fc8c09 4d8b143a        mov     r10,qword ptr [r10+rdi]
fffff801`12fc8c0d 4d631c82        movsxd  r11,dword ptr [r10+rax*4]
fffff801`12fc8c11 498bc3          mov     rax,r11
fffff801`12fc8c14 49c1fb04        sar     r11,4
fffff801`12fc8c18 4d03d3          add     r10,r11
fffff801`12fc8c1b 83ff20          cmp     edi,20h
fffff801`12fc8c1e 7550            jne     nt!KiSystemServiceGdiTebAccess+0x49 (fffff801`12fc8c70)

翻译成代码如下:代码未经过测试。
ULONG64 SSDT_GetPfnAddr(ULONG dwIndex)
{
    PULONG lpBase  = KeServiceDescriptorTable->KiServiceTable;
    ULONG dwCount  = KeServiceDescriptorTable->Count;
    ULONG64 lpAddr = NULL;

    ULONG dwOffset = lpBase[dwIndex];

    // SAR这个指令, 以及右移4位, 决定了0xF0000000这个值。
    if ( dwOffset & 0x80000000 )
        dwOffset = (dwOffset >> 4) | 0xF0000000;
    else
        dwOffset >>= 4;

    lpAddr = (ULONG64)((PUCHAR)lpBase + (LONG)dwOffset);

    return lpAddr;
}
用这个公式,Windbg的脚本测试结果:


有不正确的地方,请指点下。
uf KiSystemServiceStart下的某一段代码, 不确定位置是否正确,但是经过验证,公式是正确的。
rax: 是索引值
r10: 是KeServiceDescriptorTable->KiServiceTable
nt!KiSystemServiceRepeat+0x35:
fffff801`12fc8c09 4d8b143a        mov     r10,qword ptr [r10+rdi]
fffff801`12fc8c0d 4d631c82        movsxd  r11,dword ptr [r10+rax*4]
fffff801`12fc8c11 498bc3          mov     rax,r11
fffff801`12fc8c14 49c1fb04        sar     r11,4
fffff801`12fc8c18 4d03d3          add     r10,r11
fffff801`12fc8c1b 83ff20          cmp     edi,20h
fffff801`12fc8c1e 7550            jne     nt!KiSystemServiceGdiTebAccess+0x49 (fffff801`12fc8c70)


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (8)
雪    币: 793
活跃值: (75)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
正在学习中,第一次在看雪抢个沙发。
2018-12-2 10:25
1
雪    币: 9
活跃值: (379)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
mac,小弟也暴搜kisevicetab一波,可里面的数组值很诧异
2018-12-2 18:12
0
雪    币: 6588
活跃值: (4032)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
有没有研究 名取 索引号。?
2018-12-4 00:18
0
雪    币: 244
活跃值: (174)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主脚本呢?
2018-12-5 17:14
0
雪    币: 515
活跃值: (3272)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wem
6
楼主,下面没有了?
2019-6-11 19:31
0
雪    币: 121
活跃值: (121)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
补充下对应脚本:
aS ufLinkS "<u><col fg=\\\"emphfg\\\"><link name=\\\"%p\\\" cmd=\\\"uf 0x%p\\\">";
aS ufLinkE "</link></col></u>";
 
r $t1 = nt!KeServiceDescriptorTable;
r $t2 = poi(@$t1 + 0x10);
r $t1 = poi(@$t1);
 
.printf "\n\nKeServiceDescriptorTable->KiServiceTable:  %p\nKeServiceDescriptorTable->Count: %d\n", @$t1, @$t2;
.printf "\nOrd   Address   fnAddr   Symbols\n";
.printf "--------------------------------\n\n";
 
.for (r $t0 = 0; @$t0 != @$t2; r $t0 = @$t0 + 1)
{
    r @$t3 = (poi(@$t1 + @$t0 * 4)) & 0x00000000`FFFFFFFF;
    $$.printf "2. %p\n", @$t3;
       
    .if ( @$t3 & 0x80000000 )
       {
               r @$t3 = (@$t3 >> 4) | 0xFFFFFFFF`F0000000;
               r @$t3 = 0 - @$t3;
               r @$t3 = @$t1 - @$t3;
       }
       .else
       {
           r @$t3 = (@$t3 >> 4);
               r @$t3 = (@$t1 + @$t3);
       }
       
    .printf /D "[%3d] ${ufLinkS}%p${ufLinkE} (%y)\n", @$t0, @$t3, @$t3, @$t3, @$t3;
}
 
.printf "\n- end -\n";
2019-8-9 11:46
0
雪    币: 121
活跃值: (121)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
补充下对应脚本:
aS ufLinkS "<u><col fg=\\\"emphfg\\\"><link name=\\\"%p\\\" cmd=\\\"uf 0x%p\\\">";
aS ufLinkE "</link></col></u>";
 
r $t1 = nt!KeServiceDescriptorTable;
r $t2 = poi(@$t1 + 0x10);
r $t1 = poi(@$t1);
 
.printf "\n\nKeServiceDescriptorTable->KiServiceTable:  %p\nKeServiceDescriptorTable->Count: %d\n", @$t1, @$t2;
.printf "\nOrd   Address   fnAddr   Symbols\n";
.printf "--------------------------------\n\n";
 
.for (r $t0 = 0; @$t0 != @$t2; r $t0 = @$t0 + 1)
{
    r @$t3 = (poi(@$t1 + @$t0 * 4)) & 0x00000000`FFFFFFFF;
    $$.printf "2. %p\n", @$t3;
       
    .if ( @$t3 & 0x80000000 )
       {
               r @$t3 = (@$t3 >> 4) | 0xFFFFFFFF`F0000000;
               r @$t3 = 0 - @$t3;
               r @$t3 = @$t1 - @$t3;
       }
       .else
       {
           r @$t3 = (@$t3 >> 4);
               r @$t3 = (@$t1 + @$t3);
       }
       
    .printf /D "[%3d] ${ufLinkS}%p${ufLinkE} (%y)\n", @$t0, @$t3, @$t3, @$t3, @$t3;
}
 
.printf "\n- end -\n";
2019-8-9 11:46
0
雪    币: 184
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢分享,刚刚试验了下可以成功查看
2020-9-13 00:07
0
游客
登录 | 注册 方可回帖
返回
//