windows注入
本文内容引述至《windows核心编程》
注入引入需求:
- 从另一个进程创建的窗口派生子类窗口
- 需要一些方式来辅助调试,比如确定另一个进程正在使用哪些DLL
- 对另一个进程Hook
窗口派生
User32.dll被映射到进程A的地址空间中,负责对发到和发往进程A的任何窗口的消息进行接收和派发。当User32.dll检测到一个消息的时候,会先确定该窗口的WndProc的地址,然后调用它并在参数中传入窗口句柄、消息、以及wParam和lParam。当WndProc处理完消息后,User32.dll会进入下一轮循环并等待对下一条窗口消息进行处理。
如果进程B想要从进程A创建的一个窗口派生子类窗口,FindWindow可以得到想要的窗口,但是在SetWindowLongPtr函数执行时,系统会检查一个进程试图修改的WndProc地址是否属于另一个进程创建的窗口,如果是这样的,函数会直接忽略调用。
考虑轻易地调用SetWindowLongPtr,并把MySubclassProc在进程A中的地址传给它。我们将这个技术称为DLL“注入”到进程的地址空间中。
注册表实现注入DLL
HKEY_MECHINE\Software\Microsoft\window NT\CurrentVersion\Windows\
如下图所示
- AppInit_Dlls 键值包含一个DLL的文件名或一组DLL的文件名,添加我们的DLL路径,如 C:\MyLib.dll
- 创建一个名为LoadAppInit_Dlls,类型为DWORD的注册表项,并将它的值设为1.
当User32.dll被映射到一个新的进程时,会收到DLL_PROCESS_ATTACH的通知,当User32.dll对它进行处理时,会取得上述注册表键的值,并调用LoadLibrary来载入这个字符串中指定的每个DLL。系统载入每个DLL的时候,会调用它们的DllMain函数并将参数fdwReason的值设为DLL_PROCESS_ATTACH,这样每个DLL就能够对自己进行初始化。
缺点:
- 大多数GUI的程序,会调用User32.dll,而基于CUI的应用程序都不会使用它;
- DLL会被映射到每个GUI应用程序,导致“容器”进程奔溃的可能性也就越大。
- DLL会被映射到每个基于GUI的应用程序中,在程序退出前,它将一直存在于进程的地址空间中
使用windows的Hook注入DLL
引入例子,进程A为了查看系统中各窗口处理了那些消息,安装了一个WH_GETMESSAGE挂钩。这个挂钩是通过调用SetWindowsHookEx来安装的。
HHOOK hHook =</