Hook函数在进程操作中的应用

2015-10-18 02:16琚,张
天津科技 2015年1期
关键词:数组调用线程

王 琚,张 伟

(1. 国家计算机病毒应急处理中心 天津 300457;2. 天津市公安局公共信息网络安全监察总队案件支队 天津 300020)

Hook(钩子)实际上是 1个消息处理的程序段,它通过系统调用实现挂入系统。钩子程序总能先于目的程序率先截获原本发往该地的消息,从而率先得到控制权。随后钩子函数可以对消息进行修改,或放行接着传递,或直接结束该消息。

Hook程序与消息紧密相关,其主要功能是对消息进行监听。Hook根据要截获的消息可以分为若干类。但无论何种消息,Hook对“对象的搭接”不是硬性的,它是一种柔性连接,一经接触,Hook的搭钩立刻能“化”进监听的线路中,即Hook的代码能变成对象进程的一部分。原本用户进程间彼此互相独立,互不联系,而 Hook机制提供了操纵特定程序行为的方法。

1 对API实现Hook

Hook程序想发挥更大的作用,要找到一种系统内置函数,最佳的目标为 API。API函数是用户应用程序需求的接收者和工作的完成者。API Hook的基本思想是由 Hook“套”到API的入口点,把它的地址指向自定义函数地址。

谈Hook获得API入口点,要从内存空间中的PE可执行文件说起。

PE文件头的格式为:

其中“IMAGE_FILE_HEADER”与“MAGE_OPTIONAL_HEADER32”这 2个结构,分别对 PE文件的属性进行定义,两者共同构造了 PE文件的结构。在后者的结构中拥有不下30个字段的描述,最后一条是:

IMAGE_DATA_DIRECTORY,这个 DataDirectory是一个结构数组,有16个成员,它们的结构是相同的,均为:

根据 winnt.H中的定义,将 DataDirectory结构的数据目录定义列表(见表1)。

表1 Data Directory结构的数据目录定义子表Tab.1 Subtable of Data directory definitions

在 PE文件中查找想要的数据需先从表 1中搜寻对应的信息,如需要找DLL文件中有哪些API函数(导入函数)在运行,则需要查 IMAGE_IMPORT_DESCRIPTOR(导入表),它是1个结构数组,其中的每个元素代表1个动态链接库,而各成员变量则包括了动态链接库导入了哪些函数及这些函数地址的信息。想找到导入表,需要知道它的地址。从表 1中得知导入表对应第 2个目录 IMAGE_DIRECTORY_EN-TRY_IMPORT,即从IMAGE_DATA_DIRECTORY结构数组中查第2个元素的Virtual Address和Size值,从中找到导入表的地址和大小,这里数据的起始地址称为 RVA(RVA是相对虚地址,Relative Virtual Addresses。它是相对于基址 Base address而言。一个 PE文件加载进内存后,就以当前内存地址作为基址,文件中各个模块都以 RVA表示,只要参照基址就能得出各自实际地址)。

成员变量OriginalFirstThunk包含1个IMAGE_THUNK_DATA结构数组的地址,该数组存储着函数序号和名称。成员变量 Name记录的是引入的动态链接库名称,这提醒我们,1个IMAGE_IMPORT_DESCRIPTOR直接对应1个动态链接库。而成员变量FirstThunk包含1个IMAGE_THUNK_DATA结构数组的地址。可以看出,这是两个同名函数。IMAGE_THUNK_DATA数组结构为:

在导入表加载之前,FirstThunk所指向的数组与OriginalFirstThunk指向的数组有相同的内容,都包含了要导入的函数的名称和序号。而在导入表加载之后,FirstThunk所指向的数组所包含的内容就变成了要导入函数的实际地址。

这样,通过 PE文件头,一路找寻,最终找到了 API函数的入口点,从而可以为Hook操作所用。

2 Hook在进程监控的应用

利用进程Hook操作可以实现对特定进程的监控,对目标实现限时、关闭、暂停的操作。监控可以通过定期获得系统当前进程的快照队列完成,而每次将队列中进程名逐个与监控目标进程名作比较,不一致就调用队列的下一个进程;一致则对其进行相应控制。对系统当前进程的掌握可以借助ToolHelp API的几个函数完成。首先是 CreateToolhelp32 Snapshot函数,它的结构是:

参数dwFlags:DWORD根据用户针对的目标类型不同而采取不同设置,对进程、线程、进程的堆列表、进程的模块列表进行信息捕获时分别对应的设置值为:TH32CS_SNAPPROCESS、TH32CS_SNAPTHREAD、TH32CS_SNAPHEAPLIS、TH32CS_SNAPMODULE。

利用以上 2个函数可以实现对系统当前进程队列的遍历,Process32First捕获队列中首个进程的信息,Process32Next则对下一个进程操作。其中参数 hSnapshot返回CreateToolhelp32Snapshot函数建立的当前进程快照的句柄;有了快照,还要设 1个存放它们的所在,于是又有了 1个PROCESSENTRY32结构体来承担这项工作,而参数LPPROCESSENTRY32就充当指向结构 PROCESSENTRY32的指针。

对进程的控制用到OpenProcess函数和TerminateProcess函数。它们的结构分别为:

HANDLE OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId);

BOOL TerminateProcess(HANDLE hProcess;UINT uExit-Code);

OpenProcess函数用来获得要访问进程的句柄,参数dwDesiredAccess存放目标进程的访问权限,参数bInheritHandle表示所得到的目标进程的句柄能否被继承,参数dwProcessId表示目标进程的PID值。

TerminateProcess函数用来无延时地终止特定进程,参数HANDLE hProcess的值即目标进程的句柄,这个值要从Open Process函数获得;参数uExitCode负责接收代码退出值。

在进行进程操作时,先要调用 OpenProcess函数,接着再调用 TerminateProcess函数,一般使用完进程句柄后,应调用CloseHandle函数把它关闭,否则会造成句柄泄漏,降低系统效率。

实际上,如果对 OpenProcess函数进行 Hook操作,能达到进程免杀的效果。在进程的众多属性中,只有 ProcessId值是唯一的,只有它能准确标识进程。当对 OpenProcess函数实施Hook,一旦OpenProcess函数被调用,我们就可以截获它的调用信息,判断被调用的 ProcessId值与设置的进程 ID是否一致,只要一致,就为调用程序返回 1个错误值,这样系统始终无法获得我们的进程句柄,也就无法停止它。这在实现进程监控和植入木马的应用上都是有效方法。

3 远程注入DLL

在进程加载 DLL库的过程中,要涉及到 LoadLibrary(lpFileName)函数,它返回DLL的句柄。而与之经常配合使用的是 GetProcAddress(Hinstance,lpname)函数,其中参数Hinstance获得 LoadLibrary函数返回的句柄,参数 Ipname为文件名,最终的返回值为动态链接库的地址。这2个函数均为动态调用,即只有当需要调用它们时,才将函数实例引入。LoadLibrary函数可以对应不同类型的 DLL 库,而GetProcAddress函数对应不同的实例。一旦调用链接库失败,不影响程序的运行。

但是,当外部进程要调用 LoadLibrary函数以实现加载DLL目的时,因为没有访问权限不能直接使用。这时可以使用CreateRemoteThread函数来建立远程线程,它能够在其他进程地址空间中创建线程。CreateRemoteThread函数不仅实现跨进程地址空间访问的目的,而且它的参数 IpParameter是指向线程操作函数的指针,这与LoadLibrary函数的IpFileName参数有异曲同工的效果,这样在完成远程线程的建立后又可以用LoadLibrary函数实现线程操作。■

[1] Evil. eagle PE文件结构详解(四)PE导入表[EB/OL].http://blog.csdn.net/evileagle/article/details/12357155.2013.

[2] Qxiniu. Windows下 Hook API技术[EB/OL]. http://wenku.baidu.com/link?url=hl3FowyNyM8kIfKfg4ur_vj0rcligYxccbEtCQNpY3dADCH528tYu2n2Ut-9BC9LXTYrqQT7wuVFAznpO3GGXcT2bAQWJnQheUhFUh ZRxK. 2010.

[3] 天堂水. 2009 Windows下Hook API技术小结[EB/OL].http://www.cnblogs.com/heavenwater/articles/1527446.html. 2009.

猜你喜欢
数组调用线程
JAVA稀疏矩阵算法
基于C#线程实验探究
JAVA玩转数学之二维数组排序
基于国产化环境的线程池模型研究与实现
核电项目物项调用管理的应用研究
线程池调度对服务器性能影响的研究*
系统虚拟化环境下客户机系统调用信息捕获与分析①
更高效用好 Excel的数组公式
寻找勾股数组的历程
利用RFC技术实现SAP系统接口通信