吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9156|回复: 4
收起左侧

[系统底层] x64下KeSystemDescriptorTable(SSDT)地址的获取原理

  [复制链接]
msx2009 发表于 2014-11-28 20:40
本帖最后由 msx2009 于 2014-11-28 20:42 编辑

win32KeSystemDescriptorTable的地址已经由ntoskrnl.exe导出,直接 extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable 即可获取SSDT的地址。
win64下,KeSystemDescriptorTable的地址没有被导出,不能通过win32下的方法获取地址。
Win64下,我们可以通过msr寄存器获取 KiSystemCall64函数的地址,在这个函数开始地址向下搜索0x150字节左右,在通过特征码4c8d15,就能获取KeServiceDescriptorTable的地址。
Windgb下看一下
uf KiSystemCall64

kd> uf KiSystemCall64
Flow analysis was incomplete, some code may be missing
nt!KiSystemCall64:
fffff800`03ecfbc0 0f01f8          swapgs
fffff800`03ecfbc3 654889242510000000 mov   qword ptr gs:[10h],rsp
fffff800`03ecfbcc 65488b2425a8010000 mov   rsp,qword ptr gs:[1A8h]
fffff800`03ecfbd5 6a2b            push    2Bh
fffff800`03ecfbd7 65ff342510000000 push    qword ptr gs:[10h]
fffff800`03ecfbdf 4153            push    r11
……
nt!KiSystemServiceRepeat:
fffff800`03ecfcf2 4c8d15478c2300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`04108940)]
fffff800`03ecfcf9 4c8d1d808c2300  lea     r11,[nt!KeServiceDescriptorTableShadow (fffff800`04108980)]
fffff800`03ecfd00 f7830001000080000000 test dword ptr [rbx+100h],80h
fffff800`03ecfd0a 4d0f45d3        cmovne  r10,r11
fffff800`03ecfd0e 423b441710      cmp     eax,dword ptr [rdi+r10+10h]
fffff800`03ecfd13 0f83e9020000    jae     nt!KiSystemServiceExit+0x1a7 (fffff800`03ed0002)

注意蓝色字节内容, KiSystemCall64的开始地址是fffff800`03ecfbc0 , 第二个蓝色标记处发现了KeServiceDescriptorTable,这条指令地址是fffff800`03ecfcf2,对应的字节为4c8d15478c2300Lea的对应字节为4c8d15所以后边的字节478c2300为偏移地址,注意地址是反过来的,真正偏移地址是 00238c47,偏移地址是针对这条指令最后一个字节的地址的偏移,所以需要在加7字节,由此可得KeServiceDescriptorTable地址为:
fffff800`03ecfcf2 +00238c47 + 7 = fffff800`04108940。

我们可以dd KeServiceDescriptorTable看一下地址
kd> dd KeServiceDescriptorTable
fffff800`04108940  03ed1800 fffff800 00000000 00000000
fffff800`04108950  00000191 00000000 03ed248c fffff800
可以看出上述计算是正确的。

编程实现以下,主要代码如下(引用别人的代码):
//获取SSDT地址
ULONGLONG MyGetKeServiceDescriptorTable()
{
        PUCHAR StartSearchAddress =(PUCHAR)__readmsr(0xC0000082);
        PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
        PUCHAR i = NULL;
        UCHAR b1=0,b2=0,b3=0;
        ULONG templong=0;
        ULONGLONG addr=0;

        for(i=StartSearchAddress;i<EndSearchAddress;i++)
        {
                if(MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+1))
                {
                        b1=*i;
                        b2=*(i+1);
                        b3=*(i+2);
                        if(b1==0x4c && b2==0x8d && b3==0x15) //4c8d15
                        {
                                memcpy(&templong,i+3,4);
                                addr = (ULONGLONG)templong + (ULONGLONG)i +7;
                                return addr;
                        }
                }
        }
        return 0;
}

可以在驱动入口打印出地址
DbgPrint("[method 1]SSDT: %llx",MyGetKeServiceDescriptorTable())

免费评分

参与人数 1热心值 +1 收起 理由
arryboom + 1 对曾经的32位转向64位HIPS驱动很有帮助

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

icqw 发表于 2016-3-12 17:44
刚接触这个 如果楼主能看到我的问题的话,我想问问__readmsr(0xC0000082);是什么原理
cct123 发表于 2016-3-16 17:23
wen9508 发表于 2016-3-20 11:26 来自手机
beatit 发表于 2016-4-25 11:59
支持新人贴
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-26 12:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表