《逆向工程核心原理》——DLL注入与卸载
利用CreateRemoteThread
#include <iostream> #include <tchar.h> #include <Windows.h> #include <tlhelp32.h> BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp; HANDLE hToken; LUID luid; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { _tprintf(L"OpenProcessToken error: %u\n", GetLastError()); return FALSE; } if (!LookupPrivilegeValue(NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid)) // receives LUID of privilege { _tprintf(L"LookupPrivilegeValue error: %u\n", GetLastError()); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { _tprintf(L"AdjustTokenPrivileges error: %u\n", GetLastError()); return FALSE; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { _tprintf(L"The token does not have the specified privilege. \n"); return FALSE; } return TRUE; } BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath) { HANDLE hProcess = NULL, hThread = NULL; HMODULE hMod = NULL; LPVOID pRemoteBuf = NULL; DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR); LPTHREAD_START_ROUTINE pThreadProc; // #1. 通过dwPID获取进程句柄 if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) { _tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError()); return FALSE; } // #2. 在注入的目标进程中开辟内存,存储Dll的路径 pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); // #3. 写入DLL路径数据 WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL); // #4. 获取LoadLibraryA() API hMod = GetModuleHandle(L"kernel32.dll"); pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW"); // #5. 调用CreateRemoteThread hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE; } BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName) { BOOL bMore = FALSE, bFound = FALSE; HANDLE hSnapshot, hProcess, hThread; HMODULE hModule = NULL; MODULEENTRY32 me = { sizeof(me) }; LPTHREAD_START_ROUTINE pThreadProc; // dwPID = notepad 进程id // 使用TH32CS_SNAPMODULE 参数,获取加载到notepad 进程dll的名称 hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);//句柄 bMore = Module32First(hSnapshot, &me); for (; bMore; bMore = Module32Next(hSnapshot, &me))//循环比较地址 { if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) || !_tcsicmp((LPCTSTR)me.szExePath, szDllName)) { bFound = TRUE; break; } } if (!bFound) { CloseHandle(hSnapshot); return FALSE; } if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))//获取目标进程的句柄 { _tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError()); return FALSE; } hModule = GetModuleHandle(L"kernel32.dll"); pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");//获取FreeLibrary的api地址 hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL); //卸载dll WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hProcess); CloseHandle(hSnapshot); return TRUE; } int main() { std::cout << "Hello World!\n"; DWORD pID; std::cout << "input pid:\n"; _tscanf(_T("%d"), &pID); TCHAR dllPath[256] = { 0 }; std::cout << "input dll path:\n"; _tscanf(_T("%s"), dllPath); if (!SetPrivilege(SE_DEBUG_NAME, TRUE)) { printf("error \n"); getchar(); return 1; } // inject dll if (InjectDll(pID, dllPath)) { _tprintf(L"InjectDll(\"%s\") success!!!\n", dllPath); getchar(); } else { _tprintf(L"InjectDll(\"%s\") failed!!!\n", dllPath); getchar(); } printf("input 'q' to ejection\n"); if (getchar() == 'q') { if (EjectDll(pID, dllPath)) { printf("ejection success!\n"); } else { printf("ejection error!\n"); } } return 0; }