【发布时间】:2012-03-14 03:09:06
【问题描述】:
我使用CreateProcess() 和CREATE_SUSPENDED 创建了一个进程,然后继续在远程进程中创建一小段代码以加载一个DLL 并调用一个函数(由该DLL 导出),使用VirtualAllocEx() (使用..., MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)、WriteProcessMemory(),然后使用代码在该内存块上调用FlushInstructionCache()。
之后我调用CreateRemoteThread() 来调用该代码,为我创建了一个hRemoteThread。我已验证远程代码按预期工作。 注意:此代码仅返回,它不调用除LoadLibrary() 和GetProcAddress() 之外的任何API,然后调用导出的存根函数,该函数当前仅返回一个值,然后将作为线程的退出状态。
现在出现了一个特殊的观察结果:请记住 PROCESS_INFORMATION::hThread 仍然处于暂停状态。当我简单地忽略hRemoteThread 的退出代码并且也不等待它退出时,一切都会“正常”。调用CreateRemoteThread() 的例程返回,PROCESS_INFORMATION::hThread 被恢复,(远程)程序实际开始运行。
但是,如果我致电WaitForSingleObject(hRemoteThread, INFINITE) 或执行以下操作(效果相同):
DWORD exitCode = STILL_ACTIVE;
while(STILL_ACTIVE == exitCode)
{
Sleep(500);
if(!GetExitCodeThread(hRemoteThread, &exitCode))
break;
}
随后是CloseHandle(),这导致hRemoteThread 在PROCESS_INFORMATION::hThread 恢复之前完成,并且该过程只是“消失”。让hRemoteThread 在没有PROCESS_INFORMATION::hThread 的情况下以某种方式完成就足以导致进程终止。
这看起来有点像竞态条件,因为在某些情况下hRemoteThread 可能仍然更快,并且即使我保留代码原样,该过程也可能仍然“消失”。
这是否意味着在进程中运行的第一个线程自动成为主线程,并且该主线程有特殊规则?
我一直认为进程在其最后一个线程死亡时结束,而不是在特定线程死亡时结束。
另请注意:这里没有以任何方式调用ExitProcess(),因为hRemoteThread 只是返回,而PROCESS_INFORMATION::hThread 在我等待hRemoteThread 返回时仍处于暂停状态。
这发生在 32 位 Windows XP SP3 上。
编辑:我刚刚尝试了 Sysinternals Process Monitor 来查看发生了什么,我可以验证我之前的观察结果。注入的代码不会崩溃或任何事情,相反,我会看到,如果我不等待线程它不会在我关闭注入代码的程序之前退出。我正在考虑是否应该推迟对CloseHandle(hRemoteThread) 的调用或其他什么...
编辑+1:不是CloseHandle()。如果我只是为了测试而忽略它,那么在等待线程完成时行为不会改变。
【问题讨论】:
标签: multithreading winapi code-injection win32-process createremotethread