通过CreateRemoteThread注入DLL
注入流程
- 获取要注入的目标进程的句柄(OpenProcess)
- 在目标进程中开辟内存空间,用于写入DLL的路径(VirtualAllocEx)
- 在开辟的空间中写入DLL的路径(WriteProcessMemory)
- 获取kernel32.dll的句柄(GetModuleHandle)
- 获取kernel32.dll中LoadLibrary的地址(GetProcAddress)
- 在目标进程中创建远程线程(CreateRemoteThread)
需要注意的地方
- 在Win11中因为自己的DLL命名为了MyHack.dll导致Windows Defender拦截了一切对该dll的访问(踩坑!!)
- 因为注入的应用不一定有输出的地方,所以需要使用
OutputDebugStringA("hack.dll has Injection!!!");
这种形式来输出,通过DebugView来查看
- 执行注入的exe和注入的dll一定要相同的位数
- 32位的执行exe和注入dll无法注入进64位的目标进程,CreateRemoteThread会报错5
注入代码
#include <Windows.h>
#include <tchar.h>
BOOL InjectDLL(DWORD dwPID, LPCTSTR szDllPath) {
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) {
_tprintf(L"OpenProcess(%d) failed [%d]\n", dwPID, GetLastError());
return FALSE;
}
LPVOID pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
if (!(WriteProcessMemory(hProcess, pRemoteBuf, szDllPath, dwBufSize, NULL))) {
_tprintf(L"WriteProcessMemory fail [%d]\n", GetLastError());
return FALSE;
}
HMODULE hMod = GetModuleHandle(L"kernel32.dll");
if (hMod == NULL) {
_tprintf(L"get kernel32.dll fail [%d]", GetLastError());
return FALSE;
}
LPTHREAD_START_ROUTINE pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
if (pThreadProc == NULL) {
_tprintf(L"GetProcAddress fail [%d]", GetLastError());
return FALSE;
}
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
if (hThread == NULL) {
_tprintf(L"CreateRemoteThread fail [%d]", GetLastError());
return FALSE;
}
DWORD retCode = WaitForSingleObject(hThread, INFINITE);
if (retCode == WAIT_FAILED) {
_tprintf(L"Wait Thread fail [%d]", GetLastError());
return FALSE;
}
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
int _tmain(int argc, TCHAR* argv[]) {
if (argc != 3) {
_tprintf(L"Usage : %s pid dllpath\n", argv[0]);
return 1;
}
if (InjectDLL((DWORD)_tstol(argv[1]), argv[2])) {
_tprintf(L"success");
}
else {
_tprintf(L"fail");
}
return 0;
}