关于Microsoft Detours Library,我有几个简单的问题。 我已经使用它(成功),但我只是想了一下这个function:
LONG DetourUpdateThread(HANDLE hThread);
我在其他地方读到,这个函数实际上会挂起线程,直到事务完成。 这似乎很奇怪,因为大多数示例代码调用
DetourUpdateThread(GetCurrentThread());
无论如何,显然这个函数“登记”了线程,所以当事务提交(和绕行)时,如果它们位于“在目标函数或蹦床函数中被重写的代码内”,它们的指令指针就被修改。
我的问题是:
当事务提交时,当前线程的指令指针是否在DetourTransactionCommit函数中? 如果是这样,我们为什么要打扰它更新?
另外,如果挂起的线程被挂起,当前线程如何继续执行(假设大多数示例代码调用DetourUpdateThread(GetCurrentThread());)?
最后,是否可以暂停当前进程的所有线程,避免竞争条件(考虑到线程可能随时被创build和销毁)? 也许这是在交易开始的时候完成的? 这将允许我们更安全地枚举线程(因为似乎不太可能创build新的线程),但CreateRemoteThread()如何?
谢谢,
保罗
作为参考,这里是一个简单的例子摘录:
// DllMain function attaches and detaches the TimedSleep detour to the // Sleep target function. The Sleep target function is referred to // through the TrueSleep target pointer. BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) { if (dwReason == DLL_PROCESS_ATTACH) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)TrueSleep, TimedSleep); DetourTransactionCommit(); } else if (dwReason == DLL_PROCESS_DETACH) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)TrueSleep, TimedSleep); DetourTransactionCommit(); } return TRUE; }
如何embaressing:我忘记了来源是可用的!
DetourUpdateThread静静地忽略了当前线程的入侵。 否则,给定的线程被挂起。 我想知道为什么所有的代码示例无论如何都争取当前的线程! 这回答了前两个问题。
至于第三个问题:我发现另一个绕行的库,试图暂停所有线程通过执行以下操作:
获取所有线程的快照
循环快照并挂起我们尚未挂起的线程。
如果线程被挂起,那么回到1(我们仍然跟踪我们已经挂起的线程)。 如果没有线程被暂停,那么我们就完成了。
我认为假设是,如果我们可以遍历所有的线程,并且它们都已经被挂起了(也就是从我们拍摄快照之前),那么不能创建更多的线程。 虽然不是很确定CreateRemoteThread!
编辑:Re:CreateRemoteThread。
“进程中只有一个线程可以在一次DLL初始化或分离例程中”。 CreateRemoteThread“导致调用进程中每个DLL的入口点”。 http://msdn.microsoft.com/en-us/library/ms682437%28VS.85%29.aspx
如果您在一个DllMain函数(只要新的线程尚未导致调用进程中的每个DLL的入口点)一个新的线程不能开始执行。 因此,如果您在DllMain函数中应用您的绕行,则您可能只是在创建新的远程线程的竞态条件下保持安全,并且其指令指针位于重写的目标/蹦床函数中。
谢谢,
保罗