- 首先打开指定进程获得进程句柄
- :VirtualAllocEx在远程进程中非配内存空间
- 用WriteProcessMemory把DLL路径写入1步骤中的空间中
- GetProcAddress获取本进程中DLL的虚拟地址(其他进程一样)
- 将2步骤中的地址传入CreateRemoteThread创建远程线程
- 等待WaitForSingleObject 返回函数TRUE
bool CGameMemoryDlg::InjectDllW(DWORD dwProcessId, PCWSTR pszDllFile)
{
BOOL bOk=FALSE;
HANDLE m_hInsert=NULL,hThread=NULL;
LPVOID pszDllFileRemote=NULL;
__try{
HANDLE m_hInsert = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE,dwProcessId);
if (m_hInsert==NULL) __leave;
// 定义要传入的字符数
int cch=1+lstrlenW(pszDllFile);
int cb=cch*sizeof(wchar_t);
// 给远程进程分配用来存字符串的地址空间
pszDllFileRemote=::VirtualAllocEx(m_hInsert,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
if (pszDllFileRemote==NULL) __leave;
// 把本进程字符串写入到远程进程中
if(!::WriteProcessMemory(m_hInsert,pszDllFileRemote,pszDllFile,cb,NULL)) __leave;
// 获取当前进程LoadLibraryW地址
PTHREAD_START_ROUTINE ptnThreadRtn = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")),"LoadLibraryW");
if (ptnThreadRtn==NULL) __leave;
// 在远程进程中创建线程,因为线程函数和loadlibrary很像
hThread= ::CreateRemoteThread(m_hInsert,NULL,0,ptnThreadRtn,pszDllFileRemote,0,NULL);
if(hThread==NULL) __leave;
// 用来检测Handle事件的信号状态
// 参数dwMilliseconds为INFINITE时函数将直到相应时间事件变成有信号状态才返回,
// 否则就一直等待下去,直到WaitForSingleObject有返回值才执行后面的代码
WaitForSingleObject(hThread,INFINITE);
bOk=true;
}
__finally{
if (pszDllFileRemote!=NULL)
VirtualFreeEx(m_hInsert,pszDllFileRemote,0,MEM_RELEASE);
if (hThread!=NULL)
::CloseHandle(hThread);
if (m_hInsert!=NULL)
::CloseHandle(m_hInsert);
}
return bOk;
}