轉載請聲明出處: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”: