自从上一篇Windows APC
之后,对整个APC过程算是有了一个比较清晰的认识了。打算在这篇文章介绍一下如何实现APC Injection
APC Injection
之前在写Windows Driver 初探
这篇文章的时候,我提到过说想要做一个当创建新的进程的时候,获取其创建时的函数调用链功能的模块。当时使用的是修改注册表的AppCertDLLS
的思路,但是这个思路我后来发现会被很多程序绕过,于是这里打算采用APC Inject的方式来试一下。
Inject/hook
为了实现获取创建进程时,函数调用链这个思路,首先要意识到这个地方有两个步骤:
- 为了能够得到调用链,需要hook对应的函数,例如
CreateProcess
- 要进入到调用进程创建的函数所在的进程中,这样才有机会去hook对应的函数
也就是说,为了实现这个类似于monitor
的功能,我们需要有两个模块共同工作,才有可能将当前程序中的CreatProcess给抓取下来。
Hook
这个模块我在毕设的时候差不多也算是实现了,用了一个叫做mhook
的库,可以实现一个inline hook
的效果。
inline hook:
原理非常简单,就是将当前函数的前五个字节修改成jmp
指令,从而劫持程序流。具体为了组织函数调用,恢复上下文等,可能会有不同的处理方法。mhook会让当前的程序跳转到一个自己申请到的地址上,然后重新组织寄存器等,之后再跳转到我们自己程序中定义的函数,从而实现一次hook。
1 | function: hook: |
为了控制指令长度,mhook
会使用一种叫做trampolin
的技术,也就是jmp
的地址并不是直接跳转到我们给出的函数地址(因为担心那个地址可能距离hook的函数过远,导致需要用到长跳转,此时5个字节内并不能完成),而是跳转到一个自己申请的一个可读可写可执行的地址空间中,这个地址称为trampolin
。跳转至trampolin
后,再重新组织传参等问题,然后正式跳转到我们自己的函数上。
Injection
当初实现Injection的时候,用的是之前提到过的AppCertDLLS
。这是一个Windows的特性,就是说如果往注册表中的HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls
中添加一个dll
的路径,那么此时的dll将会在调用CreateProcess,CreateProcessAsUser,CreateProcessWithLogonW,CreateProcessWithTokenW和WinExec
这几个函数的时候被自动加载。
这个思路最初我觉得没什么问题,但是测试了一段时间发现还是有一些根本问题的。最初做这个的时候,是想着要监控一些异常程序的,但是dll的注入的时机总是太慢了,导致捕捉不到调用链。于是这一次,打算使用APC Injection
的方式试着写一个注入程序
Apc Injection
这个模块的关键在于,要在能够监控进程的启动。同时,启动之后要能够完成将带有mhook
模块的程序加载————为了能够加载到其他进程中,最好的模块就是一个dll。因此,需要做到尽可能早的加载dll到目标线程。