进程注入的学习(上)
转载请声明出处:http://www.cnblogs.com/predator-wang/p/4792976.html
参考:http://andylin02.iteye.com/blog/459483
进程注入的方法分类如下:
带DLL的注入
利用注册表注入
利用Windows Hooks注入
利用远程线程注入
利用特洛伊DLL注入
不带DLL的注入
直接将代码写入目标进程,并启动远程线程
1. 利用注册表注入(appinit_dll 注入)
AppInit_DLL参考:
https://support.microsoft.com/zh-cn/kb/197571
http://www.2cto.com/Article/201005/47409.html
在Windows NT/2000/XP/2003中,有一个注册表键值HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs。
User32.dll被加载到进程时,会获取AppInit_DLLs注册表项,若有值,则调用LoadLibrary() API加载用户DLL。所以,DLL注册表注入,并不会影响所有进程,只会影响加载了user32.dll的进程.我们可以把自己的代码放在一个DLL中,并加入该键值,这样就可以注入到所有使用User32.dll的进程中了。
修改XP下注册表:
RegDLL.dll的内容如下:
#include <windows.h> #include <tchar.h> #define DEF_PROCESS_NAME "explorer.exe" BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpvRevered) { if (dwReason == DLL_PROCESS_ATTACH) { HANDLE f = CreateFile(L"C://InjectSuccess.txt", FILE_ADD_FILE, FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); CloseHandle(f); } return TRUE; }
当我们重启系统之后,会在C盘下发现:
发现这个DLL被注入到了许多exe中:
2. 利用Windows Hooks注入
Windows系统给我们提供了一些挂钩函数,使得被挂钩的进程可以在自己处理接收到的消息之前,先执行我们的消息处理函数,而这个消息处理函数一般会放在DLL中,这实际上已经达到了注入代码的效果。即,Hook住一个进程,在这个进程接收消息执行之前,抢先于它去执行。
DLL代码,里边实现了挂钩功能:
// dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" #include <iostream> HHOOK g_hHook = NULL; HINSTANCE hInst; BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { hInst = (HINSTANCE)hModule; // switch (ul_reason_for_call) // { // case DLL_PROCESS_ATTACH: // case DLL_THREAD_ATTACH: // case DLL_THREAD_DETACH: // case DLL_PROCESS_DETACH: // break; // } return TRUE; } LRESULT myKeyBrdFuncAd(int code, WPARAM wParam, LPARAM lParam) //作为SetWindowsHook的回调函数 { ::MessageBoxA(NULL, "Hello Injection", "Injection", MB_OK); /*std::cout << "CallBack" << std::endl;*/ return CallNextHookEx(g_hHook, code, wParam, lParam); } #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface #endif __declspec(dllexport) bool SetHook(DWORD dwThreadId) { g_hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)myKeyBrdFuncAd, hInst, dwThreadId); if (g_hHook == NULL) { return false; } return true; } #ifdef __cplusplus } #endif
再写一个cpp,可以将钩子安装到某个线程:
#include <windows.h> #include <iostream> int main() { typedef BOOL(*_pSetHook)(DWORD dwThreadId); HMODULE hDll = LoadLibrary("HookDll.dll"); if (hDll == NULL) { std::cout << "LoadLibrary failed" << std::endl; } _pSetHook pSetHook = (_pSetHook)GetProcAddress(hDll, "SetHook"); BOOL bRtn = (*pSetHook)((DWORD)8560);//GetCurrentThreadId() if (!bRtn) { std::cout << "Hook Failed" << std::endl; } FreeLibrary(hDll); system("pause"); return 0; }
下面将这个钩子安装到Evernote:
先利用pstask查看evernot的线程ID:
得到8560之后才能在上面的cpp中设定那个线程ID参数。
挂钩线程8560之后,再向Evernote传入键盘消息,先会弹出MessageBox:
然后CallNextHook才会把按键信息传入给Evernote:
再次输入字符,先弹窗:
而后Evernote才能接收到“2”: