APCInjection

自从上一篇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
2
3
4
function: hook:
push esp jmp offset trampolin
mov ebp, esp ----->
sub esp, 20h xxxxx

为了控制指令长度,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到目标线程。