2024年4月11日发(作者:)
【原创】SSDT HOOK拦截远线程的创建(上)
/logs/
ml
2009-04-12
分类:内核编程
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
/logs/
注:本文已发表在2009年第3期《黑客防线》,转载请注明来源。
在ring3的API HOOK中,怎样迫使目标进程调用我们的傀儡DLL是我们非常重视的一个
问题。在多数情况下,我们都喜欢使用CreateRemoteThread在目标进程中创建一个远程线程
来迫使它加载我们的DLL。
因为CreateRemoteThread的使用方法并不复杂,而且与其他方式相比,它可以称得上是一
种相当“优雅”的做法。各种因素的汇集就导致了这种方法的泛滥,致使很多具备主动防御或行为
监控的安全软件都加强了对这个函数的照顾。
最近在自己的毕业设计中也要用到这个功能,阻止一些简单地调用CreateRemoteThread
注入到我们要保护的进程中,就对这个问题稍微学习了下。
根据我们的思维惯性,很显然我们应该HOOK CreateRemoteProcess函数,这在ring3
下非常容易实现,但是如果这样的话我们的保护也太没有强度可言了。正好最近正在学习SSDT
HOOK,就使用这个方法吧,算是在实战中磨炼自己,吼吼~~
第一部分:SSDT HOOK的使用方法
关于什么是SSDT等基本概念我就不再赘述了,网上有很多文章,而且黑防以前的杂志上
也有不少详细介绍,这里我推荐一篇李马的《城里城外看SSDT》,确实不错。我一开始是修改
《Rootkits——Windows内核的安全防护》关于SSDT的示例代码,它给出了一个挂钩
ZwQuerySystemInformation来隐藏进程的示例。
很不幸的是,当我照本宣科地把ZwQuerySystemInformation修改成ZwCreateThread
(第二部分会介绍,这里只要知道CreateRemoteThread是最终调用ZwCreateThread)后,
编译器报错:“error LNK2019: unresolved external symbol
__imp__ZwCreateThread@32 referenced in function _DriverEntry@8”。这个错误令我
诧异了很久,在尝试解决问题的过程中,偶然发现了出现问题的原因,原来ZwCreateThread
函数没有被导出(使用depends看看就知道了)。
与之同时,我们在函数中用到了几个宏,它们的详细定义如下:
#define SYSTEMSERVICE(_Function)
eTableBase[ *(PULONG)((PUCHAR)_Fu
nction+1)]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig )
_Orig = (PVOID) InterlockedExchange( (PLONG)
&MappedSystemCallTable
[SYSCALL_INDEX(_Function)], (LONG) _Hook)
#define UNHOOK_SYSCALL(_Function, _Hook,
_Orig) InterlockedExchange((PLONG)
&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)
_Hook)
而SYSTEMSERVICE宏是采用由导出的Zw*函数地址,并返回对应的Nt*
函数在SSDT中的地址,SYSCALL_INDEX采用Zw*函数地址并返回它在SSDT中相应的索
引号。
由于ZwCreateThread没有被导出,所以这时我们就无法直接使用上述的
宏,只能另想他法。
这时候最常规的方法就是从ntdll中动态获取地址,不过我不想那么麻烦。昨天在群里问了
下,iceboy大牛给出了一种猥琐的方法,因为ZwCreateThread在SSDT中的前后两个函数
都被导出了,分别是ZwCreateSymbolicLinkObject和ZwCreateTimer。
这时候我们就可以分别获取这两个函数的索引,判断它们的索引之差是否为2,如果是,则
它们中间的函数就是ZwCreateThread,代码如下所示:
a = SYSCALL_INDEX(ZwCreateSymbolicLinkObject);
b = SYSCALL_INDEX(ZwCreateTimer);
c = b - a;


发布评论