我创建一个进程使用 CreateProcess()CREATE_SUSPENDED 然后继续在远程进程中创建一小段代码来加载一个DLL并调用一个函数(由该DLL导出),使用 VirtualAllocEx() (与 ..., MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE), WriteProcessMemory(), ,然后打电话 FlushInstructionCache() 在那块带有代码的内存上。

之后我打电话 CreateRemoteThread() 要调用该代码,请为我创建一个 hRemoteThread.我已经验证了远程代码按预期工作。 注: 此代码只是返回,它不调用任何Api以外 LoadLibrary()GetProcAddress(), ,然后调用导出的存根函数,该函数当前只是返回一个值,然后将作为线程的退出状态传递。

现在是特殊的观察:请记住, 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 返回。

这发生在Windows XP SP3,32位。

编辑: 我刚刚尝试过Sysinternals Process Monitor来查看发生了什么,我可以验证我以前的观察结果。注入的代码不会崩溃或任何事情,相反,我会看到,如果不等待线程,它不会在关闭代码注入的程序之前退出。我在想电话是不是 CloseHandle(hRemoteThread) 应该推迟什么的。..

编辑+1: 不是的 CloseHandle().如果我只是为了测试而忽略它,那么在等待线程完成时,行为不会改变。

有帮助吗?

解决方案

运行的第一个线程并不特别。

例如,创建一个控制台应用程序,它创建一个挂起的线程并终止原始线程(通过调用ExitThread)。此过程永远不会终止(无论如何在Windows7上)。

或者让新线程等待五秒钟然后退出。正如预期的那样,进程将存活五秒钟,并在辅助线程终止时退出。

不知道你的例子发生了什么。避免竞争的最简单方法是使新线程恢复原始线程。

现在推测,我想知道你所做的事情是否不太可能引起问题。例如,所有的 DllMain 调用隐式加载的Dll?它们是否意外地发生在错误的线程上,它们是否被跳过,或者它们是否被推迟到您的代码运行并且主线程启动之后?

其他提示

赔率是好的,线程与 main (或等效)函数调用 ExitProcess (显式或在其运行时库中)。 ExitProcess, ,那么,退出整个进程,包括杀死所有线程。由于主线程不知道您注入的代码,因此它不会等待它完成。

不知道有一个很好的方法可以让主线程等待你的完成。..

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top