系列索引
【原创】TP驱动保护分析系列一 定位TenProtect保护
【原创】TP驱动保护分析系列二 代码定位内核函数
【原创】TP驱动保护分析系列三 SSDT定位内核函数
媒介
前面在【原创】TP驱动保护分析系列二 代码定位内核函数 中介绍了通过驱动函数MmGetSystemRoutineAddress直接定位和特征码定位法两种定位方式。接下来继续介绍代码定位内核函数的方法:SSDT定位法
SSDT定位内核函数
SSDT
既然要通过SSDT来定位,起首就要知道什么是SSDT
SSDT是什么
SSDT全称System Service Descriptor Table或System Service Dispatch Table,即系统服务描述表或系统服务分派表。一般被称作系统服务描述表居多,但要了解它和系统服务分派表是同一个东西
SSDT本质是32位操作系统内核routine的地点数组 ,或是64位操作系统相同routine的相对偏移量数组
这里的routine是指SSDT函数,如NtOpenProcess
也就是说:SSDT本质是32位操作系统SSDT函数的地点数组 ,或是64位操作系统相同SSDT函数的相对偏移量数组
简单来说:SSDT是个数组 ,这个数组在32位系统存储SSDT函数的地点 ;在64位系统存储SSDT函数的相对偏移量
SSDT是Service Descriptor Table内存结构的第一个成员,结构如下:
typedef struct tagSERVICE_DESCRIPTOR_TABLE { SYSTEM_SERVICE_TABLE nt; //现实上是指向SSDT本身的指针 SYSTEM_SERVICE_TABLE win32k; SYSTEM_SERVICE_TABLE sst3; //指向内存地点的指针,该地点包含表中定义了多少个SSDT函数 SYSTEM_SERVICE_TABLE sst4;} SERVICE_DESCRIPTOR_TABLE;PS:由于先前在WINDOWS XP上各种SSDT HOOK等修改内核的操作被大家玩得飞起,导致微软为后来的x64系统引入了PatchGuard机制。该机制会检测系统内核是否被修改,若发现被修改就无情地BSOD蓝屏,以此来对抗SSDT HOOK
通过SSDT可以干什么
通过前面的介绍,不难发现SSDT存储着和SSDT函数地点相关的数据,32位系统直接存储的就是地点,64位系统则是相对偏移量。因此通过SSDT就能够定位到SSDT函数
以NtOpenProcess为例,定位该函数的过程可简略为:
(SSDT 和 NtOpenProcess的索引)某种运算→ NtOpenProcess
关于怎样获取SSDT函数对应的索引和运算的方法放在本篇的后面介绍
定位SSDT
既然知道了通过SSDT可以定位到SSDT函数,就得想办法定位SSDT
前面提到了SSDT是Service Descriptor Table内存结构的第一个成员,而我们可以通过KeServiceDescriptorTable得到Service Descriptor Table内存结构的地点
通过windbg可以通过下面的指令直接查看:
dps nt!keservicedescriptortable L4dqs指令是将每qword(8字节)视为一个符号进行解析并表现出来,L4表示表现4个qword的长度
除此之外另有dds和dps,dds是每dword(4字节),dps是根据当前处置惩罚器架构来选择最合适的长度
查看得到:
即:
kd> dps nt!keservicedescriptortable L48055d700 80505570 nt!KiServiceTable8055d704 000000008055d708 0000011c8055d70c 805059e4 nt!KiArgumentTable这里得到的数据分别对应先前的结构体,填入对应的结构得到:
值对应结构说明nt80505570nt!KiServiceTableSSDT的首地点为80505570win32k00000000sst30000011cSSDT函数一共有0x11c=284个sst4805059e4nt!KiArgumentTable拿到SSDT的首地点后让我们尝试从SSDT中打印出几个值
在windbg中输入指令:
dd /c1 KiServiceTable L2/c? 指定表现中利用的列数。如果省略,则默认的列数取决于表现范例;这里为指定表现利用列数为1
查看得到:
即:
kd> dd /c1 KiServiceTable L280505570 805a566480505574 805f23ea因为测试的情况为Windows XP 32位,所以SSDT存储的直接就是SSDT函数的地点
PS:关于64位系统怎样通过偏移量得到对应的SSDT函数,这里不做说明,感兴趣的可以查看下面的参考链接中的第一个参考链接,内里有说明
这里得到的就是头两个SSDT函数的地点,为了验证这一点,分别查看对应地点的反汇编:
u 805a5664u 805f23ea查看得到:
得到了前两个SSDT函数:NtAcceptConnectPort和NtAccessCheck
对应并验证了SSDT表中存储着SSDT函数的地点
获取SSDT函数对应索引
想要定位到SSDT函数,起首要获取SSDT函数对应的索引
下面以NtOpenProcess为例,介绍怎样获取对应的索引
起首要载入ntdll.dll模块,该模块中有SSDT函数相关的调用,RING3也是通过该模块调用SSDT函数的
具体的内容不展开,留做之后的系统调用再做讲解(挖坑`(<em>>﹏DriverUnload = DriverUnload; return STATUS_SUCCESS;}运行效果
运行效果如下图所示:
可以看到输出的NtOpenProcess地点为:0x805CC486
验证效果
利用Windbg验证效果:
u 0x805CC486查看得到:
验证完毕o(^▽^ )┛
总结
代码实现SSDT其实并没有什么难点,直接声明后引入KeServiceDescriptorTable,然后通过之前的公式计算出对应的SSDT函数地点即可
在WINDOWS XP系统下由于KeServiceDescriptorTable有直接导出,所以实现起来相对简单。若要在WIN7和WIN7之后的系统定位SSDT函数,则需要留意要先定位KeServiceDescriptorTable,且SSDT存储的是相对偏移,计算方式略有差异。其他方面,原理都差不多,想实现的朋侪可以自己研究研究,这里就不再赘述≡(▔﹏▔)≡
附件
附上本篇编译出的打印NtOpenProcess地点的驱动文件,想试验能不能用的可以测试下╰( ̄ω ̄o)
PS:情况肯定要是WINDOWS XP 32位
差别版本系统的SSDT函数对应的索引号不肯定相同,留意查看要编写驱动情况的ntdll.dll文件中的索引号
如果本篇提供的成品中打印的地点不对,是其他的SSDT函数的地点,可能就是由于索引号不相同导致的
附件下载地点:点我下载
本篇中用到的其他工具可回首:【原创】TP驱动保护分析系列二 代码定位内核函数 的附件部分
参考链接
System Service Descriptor Table - SSDT - Red Teaming Experiments (ired.team)
SSDT-System-Service-Descriptor-Table - aldeid
d, da, db, dc, dd, dD, df, dp, dq, du, dw (Display Memory) - Windows drivers | Microsoft Docs
dds, dps, dqs (Display Words and Symbols) - Windows drivers | Microsoft Docs
.reload (Reload Module) - Windows drivers | Microsoft Docs
lm (List Loaded Modules) - Windows drivers | Microsoft Docs
process - Windows drivers | Microsoft Docs
.process (Set Process Context) - Windows drivers | Microsoft Docs
</strong>getSSDTFunc.zip
2.37 KB, 下载次数: 7, 下载积分: 吾爱币 -1 CB
论坛备份,土豪专属通道
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
楼主热帖