使用自己写的代码, 在指定的进程里面启动一个远程线程, 从而把相关的代码注入到这个指定进程里面去, 实施操作. 通常这样做是为了拦截一些系统的 API, 或者是操控(挟持)这个进程.
2. 具体实现
拿到进程的句柄, 然后用 LoadLibrary 系统函数开启一个远程的线程. 从而把我们的DLL导入到这个指定的进程.(读者可以使用自己的办法, 不过套路应该都差不多)
3. 样例代码
- #include "windows.h"
- int main()
- {
- char * lpExeFile = "D:\\src-project\\testProcess.exe";
- char * lpDllFile = "D:\\src-project\\memTrace.dll";
- // Step 1. 开启想要跟踪的进程,并挂起.
- STARTUPINFOA startupInfo = { sizeof(startupInfo) };
- PROCESS_INFORMATION processInfo;
- if ( ! CreateProcessA(
- NULL,lpExeFile,NULL,NULL,FALSE,CREATE_SUSPENDED,
- NULL,NULL,&startupInfo,&processInfo ) )
- {
- return -1;
- }
- // Step 2. 开启远程线程的相关参数初始化.
- LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL; // 表示使用默认值.
- SIZE_T sizeStack = 0; // 表示使用默认值.
- LPTHREAD_START_ROUTINE lpStartAddress // 新线程执行入口地址.
- = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32"),"LoadLibraryA");
- LPVOID lpParameter = NULL; // 传给新线程的参数.
- DWORD flagCreation = 0; // 表示立即执行, CREATE_SUSPENDED 表示挂起.
- DWORD threadID = 0; // 用来记录新创建的线程的ID.
- // Step 3. 准备远程线程需要的参数.
- SIZE_T sizeLength = strlen(lpDllFile) + 1;
- lpParameter = VirtualAllocEx(processInfo.hProcess,NULL,sizeLength,MEM_COMMIT,PAGE_READWRITE);
- if ( ! lpParameter ) return -1;
- if ( ! WriteProcessMemory(processInfo.hProcess,lpParameter,lpDllFile,sizeLength,NULL) )
- return -1;
- // Step 4. 通过远程线程导入我们的动态库.
- HANDLE hRemoteThread = CreateRemoteThread(
- processInfo.hProcess,lpThreadAttributes,sizeStack,
- lpStartAddress,lpParameter,flagCreation,&threadID);
- WaitForSingleObject(hRemoteThread,INFINITE);
- // Step 5. 恢复子进程的主线程, 相关系统资源的销毁.
- ResumeThread(processInfo.hThread);
- VirtualFreeEx(processInfo.hProcess,lpParameter,0,MEM_RELEASE);
- if ( hRemoteThread ) CloseHandle(hRemoteThread);
- if ( processInfo.hThread ) CloseHandle(processInfo.hThread);
- if ( processInfo.hProcess ) CloseHandle(processInfo.hProcess);
- return 0;
- }