首页
社区
课程
招聘
[翻译]系统范围内挂钩Native API控制进程创建(SSDT HOOK)
发表于: 2010-12-15 11:38 17561

[翻译]系统范围内挂钩Native API控制进程创建(SSDT HOOK)

2010-12-15 11:38
17561

作者:Anton Bassov
原文地址:http://www.codeproject.com/KB/system/soviet_protector.aspx
作者:LeoF
时间:2010-12-15

简介
最近我偶然看到一款叫作Sanctuary的安全产品的介绍,这个产品非常有趣.它可以阻止任何程序的的运行,只要在特定机器的"允许运行软件列表"中没有这个软件.因此,PC用户就可以对抗间谍插件,蠕虫和木马--即使一些恶意软件可以存在于电脑中,但是它却没有机会来运行,所以也没有机会来对机器造成破坏.当然,我发现这个功能非常有趣,一点思考之后自己把它做了出来.因此,该文介绍如何通过挂钩native API来在系统范围内用程序监控进程的创建.

该文做了一个大胆的假设,假设目标进程在用户模式下被创建(shell函数,CreateProcess(),手动进程创建作为native API调用的一个顺序等等).尽管理论上一个进程可以在内核模式下被创建,这种可能是有特定目的的,可以忽略不计,不用去担心它.为什么???试着想一下-要在内核模式下创建一个进程,一个程序必须要加载一个驱动,这样的话就意味着首先要执行一些用户模式的代码.因此,要阻止未授权的程序运行,我们可以安全地缩小范围到在系统内控制用户模式的创建就可以了.

制定我们的策略
首先,我们要决定欲在系统内监控一个进程创建我们必须做什么.
进程创建是一件相当复杂的事情,它牵扯到大量的工作(如果你不信我,可以反汇编CreateProcess(),你可以亲眼看到).为了启动一个进程,要做以下的步骤:
1.可执行文件被打开(FILE_EXECUTE访问权限)
2.可执行映像(Executable image)被加载到内存中
3.建立进程执行对象(Process Executive Object,EPROCESS,KPROCESS和PEB结构)
4.为新创建的进程分配地址空间
5.建立进程的主线程的线程执行对象(Thread Executive Object,ETHREAD,KTHREAD和TEB结构)
6.建立主线程的堆栈
7.建立主线程的执行上下文(Execution context)
8.通知Win32子系统新进程信息

对于这些步骤中任何一步的成功执行,所有之前的步骤都必须被成功完成(你不可以还没有一个 executable section的句柄就建立Executive Process Object;你也不可以还没有一个文件句柄就要映射executable section等等).因此,如果我们决定终止这些步骤中的任何一步,接下来的操作也同样会失败,这样进程创建就会被终止.所有这些步骤都要调用对应的native API函数,这是很容易理解的.所以,为了监控进程创建,我们需要做的就是挂钩这些API函数不让启动一个新进程的代码通过.

我们需要挂钩哪个native API函数?尽管NtCreateProcess()似乎是最明显的答案,但是它确实是错的--不通过这个函数创建一个进程是有可能的.比如说,CreateProcess()建立一个进程相关的内核模式结构而不通过NtCreateProcess().所以挂钩NtCreateProcess()对我们来说没用. 

为了监视进程创建,我们可以挂钩NtCreateFile()和NtOpenFile(),也可以挂钩NtCreateSection()--一个可执行文件运行而不调用这些函数是绝不可能的.如果我们决定监视NtCreateFile()和NtOpenFile(),我们不得不区分进程创建和正常的文件IO操作.这个任务不怎么容易.例如,如果一个可执行文件用FILE_ALL_ACCESS属性来打开,我们应该怎么办???它是一个IO操作呢还是它是进程创建的一部分???在这点上面很难做判断--我们需要看看调用线程下一步将要做什么.因此,挂钩NtCreateFile()和NtOpenFile()不是最好的选择.

挂钩NtCreateSection()是更合理的--如果有一个映射可执行文件作为映像(SEC_IMAGE属性)的请求,我们拦截了这个请求对NtCreateSection()调用,再结合具有可执行属性的页的请求,我们可以确定进程是将要被启动.在这个时候我们可以做决定,如果我们不希望进程被创建,那就让NtCreateSection()返回STATUS_ACCESS_DENIED.因此,为了获得在机器上面全面监控进程创建的权力,我们要做的就是在系统上挂钩NtCreateSection().

和其他的函数(stub这里翻译成了函数)一样,NtCreateSection()把函数的服务索引号放进EAX中,让EDX指向函数的参数,然后执行转到内核函数KiDispatchService()(这一步在windows NT/2000下通过INT 0x2E指令,在windows XP下是SYSENTER实现).在检查过参数的有效性之后,KiDispatchService()把执行权转到实际的服务实现处,在SSDT(System Service Descriptor Table)中这个服务的地址是有效的(ntoskrnl.exe导出的KeServiceDescriptorTable变量指向这个表,因此对于内核驱动它可以使用).SSDT描述见下面的结构:

struct SYS_SERVICE_TABLE { 
    void **ServiceTable; 
    unsigned long CounterTable; 
    unsigned long ServiceLimit; 
    void **ArgumentsTable; 
};
//open device
device=CreateFile("\\\\.\\PROTECTOR",GENERIC_READ|GENERIC_WRITE, 
       0,0,OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM,0);

// get index of NtCreateSection, and pass it to the driver, along with the
//address of output buffer
DWORD * addr=(DWORD *)
   (1+(DWORD)GetProcAddress(GetModuleHandle("ntdll.dll"), 
                                     "NtCreateSection"));
ZeroMemory(outputbuff,256);
controlbuff[0]=addr[0];
controlbuff[1]=(DWORD)&outputbuff[0];
DeviceIoControl(device,1000,controlbuff,256,controlbuff,256,&dw,0);

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 1259
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu
2
不错啊,讲得很详细。
2010-12-15 12:22
0
雪    币: 106
活跃值: (276)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
哈哈,今天刚刚需要这样的文章,看雪又刚刚发这篇文章,看来这个时代,真的和我同步啊......
2010-12-15 13:38
0
雪    币: 249
活跃值: (25)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
13人下载,2人回复...
2010-12-20 18:04
0
雪    币: 1149
活跃值: (888)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
5
好文章。。。。。
2010-12-20 19:00
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
下了就要回帖~~~~~~
像我这样的好男人不多了
2011-1-3 11:09
0
雪    币: 236
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢楼主分享,学习学习。
2011-1-4 08:33
0
雪    币: 431
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
谢谢分享~~~
2011-1-4 09:53
0
雪    币: 266
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好文 顶一下啊
2011-1-4 10:30
0
雪    币: 249
活跃值: (25)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
2011-1-4 14:51
0
雪    币: 38
活跃值: (52)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
恩,感谢lz
2011-1-7 12:02
0
雪    币: 53
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
嗯。很不错。加油。
2011-1-8 12:33
0
雪    币: 116
活跃值: (316)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
很不错额,正在学习
2011-1-12 11:08
0
游客
登录 | 注册 方可回帖
返回
//