共计 2533 个字符,预计需要花费 7 分钟才能阅读完成。
前言
通过多个 Api 配合使用 CreateRemoteThread 使用实现让目标进程加载指定 DLL 或二进制代码并执行
注入步骤
- 获取进程 Pid
- 获取窗口句柄,可以通过 FindWindow 获取窗口句柄拿进程 ID GetWindowThreadProcessId
- 也可以直接遍历进程获取 Pid
- 通过 OpenProcess 打开进程
- 通过 VirtualAllocEx 在目标进程上申请一块内存空间
- 通过 WriteProcessMemory 往申请的内存空间里面写入 DLL 路径或二进制代码
- 获取 LoadLibraryA 函数地址
- 先通过 GetModuleHandle 拿到模块句柄 在通过 GetProcAddress 获取函数地址
- 或则 先通过(LoadLibraryA – GetModuleHandle)RVA 函数在模块中的偏移,在通过遍历等方式拿到目标进程的 kernel32 的模块句柄,模块句柄 + RVA 函数偏移 = LoadLibraryA 在目标进程的位置
- 通过 WriteProcessMemory 创建远程线程执行注入的 DLL 或二进制代码
完整代码
#include <cstdio>
#include <Windows.h>
int main()
{
// 获取窗口句柄
HWND hWnd = FindWindow(TEXT("wcTKKN"), NULL);
if (hWnd == NULL)
{printf("FindWindow error \n");
return 0;
}
printf("FindWindow %p \n" , hWnd);
// 通过窗口句柄获取进程 ID
DWORD dwPid = 0;
GetWindowThreadProcessId(hWnd, &dwPid);
if (dwPid == 0)
{printf("GetWindowThreadProcessId error \n");
return 0;
}
printf("GetWindowThreadProcessId %d \n", dwPid);
// 通过进程 ID 打开进程拿到进程句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess == NULL)
{printf("OpenProcess error \n");
return 0;
}
printf("OpenProcess %p \n", hProcess);
// 通过进程句柄 申请内存空间
LPVOID lpBuffer = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpBuffer == NULL)
{printf("VirtualAllocEx error \n");
CloseHandle(hProcess);
return 0;
}
// 在内存空间内写入 dll 路径或二进制代码
char szPath[MAX_PATH] = "D:\\InjectDll.dll";
DWORD dwBytes = 0;
BOOL bRet = WriteProcessMemory(hProcess, lpBuffer, szPath, MAX_PATH, &dwBytes);
if (bRet == FALSE || dwBytes != MAX_PATH)
{printf("WriteProcessMemory error \n");
VirtualFree(lpBuffer, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
printf("WriteProcessMemory %d \n", dwBytes);
// 获取 kernel32 模块地址
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
if (hKernel32 == NULL)
{printf("GetModuleHandle error \n");
VirtualFree(lpBuffer, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
printf("GetModuleHandle %p \n", hKernel32);
// 通过模块地址 拿到 LoadLibraryA 函数地址
FARPROC pLoadLibrary = GetProcAddress(hKernel32, "LoadLibraryA");
if (pLoadLibrary == NULL)
{printf("GetProcAddress error \n");
VirtualFree(lpBuffer, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
printf("GetProcAddress %p \n", pLoadLibrary);
// 创建远程线程
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibrary, lpBuffer, 0, NULL);
if (hThread == NULL)
{printf("CreateRemoteThread error \n");
VirtualFree(lpBuffer, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
printf("CreateRemoteThread %p \n", hThread);
// 等待线程结束
WaitForSingleObject(hThread, -1);
DWORD dwExitCode = 0;
GetExitCodeThread(hThread, &dwExitCode);
printf("GetExitCodeThread %d \n", dwExitCode);
if (dwExitCode == NULL)
{printf("Inject error \n");
}
else
{printf("Inject ok \n");
}
// 释放资源
CloseHandle(hThread);
VirtualFree(lpBuffer, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
正文完