DLL注入

1 使用注册表来注入DLL

在注册表路径HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersioin\Windows\下,AppInit_Dlls键的值可能会包含一个DLL的文件名活一组DLL的文件名(通过空格或逗号分隔)。将自己写的DLL文件的路径值写入AppInit_Dlls中,再创建一个名为LoadAppInit_Dlls,类型为DWORD的注册表项,并将其值设为1.当User32.dll被映射到一个新的进程时,会受到DLL_PROCESS_ATTACH通知。当User32.dll对它进行处理的时候,会获取上述注册表键的值,并调用LoadLibrary来载入这个字符串中指定的每个DLL。

2 使用Widows挂钩来注入DLL

调用函数SetWindowsHookEx来安装钩子,此函数的声明如下:

HHOOK WINAPI SetWindowsHookEx(

In  int idHook,

In  HOOKPROC lpfn,

In  HINSTANCE hMod,

In  DWORD dwThreadId

);

idHook表示要安装的挂钩的类型,lpfn是一个函数的地址,在窗口即将处理一条消息的时候,系统应该调用这个函数,hMod标识一个DLL,这个DLL包含了lpfn函数,dwThreadId表示要给哪个线程安装挂钩。如果这个参数传0,表示要给系统中所有GUI线程安装挂钩。

例如进程A使用SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInstDll,0)函数安装挂钩后:

  • 进程B中的一个线程准备向一个窗口派送一条消息
  • 系统检查该线程是否安装了WH_GETMESSAGE挂钩
  • 系统检查GetMsgProc所在的DLL是否已经被映射到进程B的地址空间中,如果DLL尚未被映射,那么系统会强制将该DLL映射到进程B的地址空间中,并将进程B中该DLL的锁计数器递增
  • 由于DLL的hInstDll是在进程B中映射的,因此系统会对他进行检查,看他在进程A中的位置是否相同,如果相同,那么在两个进程空间中,GetMsgProc函数位于相同的位置,系统就可以直接在进程A的地址空间中调用GetMsgProc。如果不相同,那么系统必须确定GetMsgProc函数在进程B的地址空间中的虚拟内存地址。使用公式GetMsgProc B=hInstDll B+(GetMsgProc A-hInstDll A)获得
  • 系统在进程B中递增该DLL的锁计数器
  • 系统在进程B的地址空间中调用GetMsgProc函数
  • 当GetMsgProc返回的时候,系统递减该DLL在进程B中的锁计数器

3 使用远程线程来注入DLL

  • 使用函数VirtualAllocEx在远程进程的地址空间中分配一块内存
  • 使用函数WriteProcessMemory函数把DLL的路径名复制到第一步分配的内存中
  • 使用函数GetProcAddress得到LoadLibrary函数的实际地址
  • 使用函数CreateRemoteThread函数在远程进程中创建一个线程,让新线程调用正确的LoadLibrary函数并在参数中传入第一步分配的内存地址。现在远程进程中有一块内存,它是在第一步分配的,DLL也还在远程进程的地址空间中。为了对它进行清理,需要在远程线程退出之后执行后续步骤
  • 使用函数VirtualFreeEx释放第一步分配的内存
  • 使用函数GetProcAddress来得到FreeLibrary函数的实际地址
  • 使用函数CreateRemoteThread在远程进程中创建一个线程,让该线程调用FreeLibrary函数并在参数中传入远程DLL的

4 动态库劫持

简单来说就是DLL文件替换。通俗说法如下:

A.exe想要调用B.dll,并且使用里面的FunC函数,这样的话我们把B.Dll改名BB.Dll(有的不用,直接根据路径劫持),然后我们自己写一个B.Dll(假的)里面有一个FunC这个函数,然后我们在这个函数里加载BB.Dll(原B.Dll),并且调用里面的FunC函数,之后我们在干一些自己的事,对于A.exe来说通常没什么异常感觉,这样我们的目的就达到了,记住此时的你,也就是B.dll(假的)的权限和内存归属都是A的,也即是你和A是一家的了,类似于代码注入之后直接修改内存一样。

WIndows上的Dll加载有一个默认的规则,就是先在主程序目录下查找B.dll,如果没有就在系统路径下找,如果还没有,就去环境变量路径里找,就因为这个我们可以轻松的在相应的位置给做劫持,然后问题就是如果实现劫持,就要知道B.Dll里面的所有函数名字以及函数参数,这个地方比较不好搞,此地不考虑。

5 APC注入

APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:

1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断。

2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。

3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的。

6 使用CreateProcess注入代码

  • 用CreateProcess以CREATE_SUSPENDED的方式启动目标进程
  • 找到目标进程的入口
  • 将目标进程入口的代码保存起来
  • 在目标进程的入口写LoadLibrary(MyDll)实现Dll注入
  • 用ResumeThread运行目标进程
  • 目标进程就运行了LoadLibrary(MyDll),实现DLL的注入
  • 目标进程运行完LoadLibrary(MyDll)后,将原来的代码写回目标进程的入口
  • 目标进程jmp到原来的入口,继续运行程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值