0 前言
最近公司要写一个监控explorer创建进程的东西, 所以花了点时间研究了以下, 然后有了以下的成果
1 思路
<1>核心思想:
注入dll, hook创建进程的底层函数, 实现创建创建进程的拦截
<2>需要注入的进程
经研究发现在开启UAC的情况下, 创建受限权限进程的动作是在explorer中由CreateProcessW这个函数执行的.
创建管理员权限的进程却是explorer委托appinfo服务创建, 然后将父进程的pid设置为explorer完成, 执行函数是CreateProcessAsUser
<3>选择hook的函数
调试器跟踪了一下这俩函数的实现, 发现底层有一个公共的函数CreateProcessInternalW, 这是一个不公开的导出函数, 因此选择这个作为hook函数
注意, win7 及win8-win10hook的这个函数位置是有区别的, 前者是在kernel32.dll里, 后者却是在kernelbase.dll
<4>注入方法
常规的CreatRemoteThread loadlibrary组合在注入appinfo时候会失败, 在win7注入explorer中貌似也会失败, 通过测试发现使用更底层的ntdll中函数RtlCreateUserThread LdrLoadDll 是会百分百成功的, 暂时没有细究前面的组合失败的原因,
由于后面的组合需要用到的参数多于1个, 因此必须采用注入一段二进制代码的方式的方式调用这个函数组合, 以此来加载我们要注入的dll, 这其中需要跟踪这些函数的实现来找出函数的原型, 同时注意远程线程函数的的调用约定,
编写二进制代码的方法可以参考我之前引用别人的一篇文章 https://www.cnblogs.com/talenth/p/9141361.html, 不过这个人写的不太好, 个人感觉没有必要调用RtlExitUserThread, 他调用这个估计是怕线程函数可能出现的堆栈不平衡问题
<5>执行注入进程的权限
一般管理员权限+调试权限
<6>卸载注入的dll
也是要使用ntdll中RtlCreateUserThread , LdrUnloadDll 这个组合, 原因跟注入类似, 在此不再赘述
<6>其他一些与主题无关但也比较重要的细节
appinfo属于服务进程, 在win7之后, 服务进程跟桌面进程有会话隔离的, 因此服务创建当前用户会话的进程一个关键点是要找到对应于这个用户的token, 跟踪了一下appinfo的这个过程, 发现他这个token是把自身token拷贝了一份, 然后降权,把自身临时转换成当前用户后实现的, 也就是说, 按照上面说的, 拦截下来的时候, appinfo本身是只有管理员权限的
被注入的进程必须与要注入的dll的平台一致, 也就是说, x86的dll只能注入到x86的进程中, 不能注入到x64的进程中
而执行注入动作的进程可以跟被注入的进程不同, 除了同平台的注入之外, x86注入x64dll到x64进程也是可以的, 不过需要借助wow64ext这个库实现, 另一种没有应用环境, 因此也没有大神去研究,^_^
hook库可以使用MinHook这个库, 稳定高效
原文地址:https://www.cnblogs.com/talenth/p/9241266.html