通过实例对远程线程注入进行详细的讲解:
远程线程注入的核心函数是
CreateRemoteThread(
_In_ HANDLE hProcess,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);
被注入的目标进程程序:
int _tmain(int argc, _TCHAR* argv[])
{
printf("hello world!");
system("pause");
getchar();
return 0;
}
注入程序:
BOOL InjectionDll( DWORD processID ,WCHAR szDllPath[]) //第一个参数:被注入进程ID 第二个参数:dll路径
{
if( NULL == szDllPath)
return FALSE;
//1.打开进程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID);
//2.在远程进程中申请空间
LPVOID pszDllName = VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT,PAGE_READONLY);
if(NULL == pszDllName )
return FALSE;
//更改空间的读写内容
DWORD dwOld = 0;
VirtualProtectEx(hProcess,pszDllName,4096,PAGE_READWRITE,&dwOld);
//3.向远程进程进程中写入数据
if(!WriteProcessMemory(hProcess,pszDllName,szDllPath,MAX_PATH,NULL))
return false;
//恢复空间的读写权限
VirtualProtectEx(hProcess,pszDllName,4096,dwOld,NULL);
//4.在远程进程中创建远程线程
HANDLE hInjecthread = CreateRemoteThread(hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)LoadLibrary,
pszDllName,
NULL,
NULL
);
//5.等待线程结束返回
DWORD dw = WaitForSingleObject(hInjecthread,-1);
//6.获取线程退出码,即LoadLibrary的返回值,即dll的首地址
DWORD dwExitCode;
GetExitCodeThread(hInjecthread,&dwExitCode);
HMODULE hMod = (HMODULE)dwExitCode;
//7.释放空间
if(!VirtualFreeEx(hProcess,pszDllName,4096,MEM_COMMIT))
return FALSE;
CloseHandle(hProcess);
return TRUE;
}
向目标程序中注入的dll程序(使用vs创建win32控制台类型的dll):
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL,NULL,NULL,NULL); //注入到目标进程中后,弹出提示框
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
实验结果:
当dll注入成功,目标进程会弹出提示框