关于Microsoft Detours库,我有几个快速问题。我曾经(成功地)使用过它,但是我对此功能只有一个想法:

长DetourUpdateThread(HANDLE hThread);

我在其他地方读到,该函数实际上将挂起线程,直到事务完成。由于大多数示例代码调用,这似乎很奇怪:

DetourUpdateThread(GetCurrentThread());

无论如何,显然,此函数“征募”线程,以便在事务提交(进行绕行)时,如果它们的指令指针位于“目标函数或蹦床函数中的重写代码内”,则它们的指令指针将被修改。

我的问题是:

当事务提交时,当前线程的指令指针是否将在DetourTransactionCommit函数内?如果是这样,为什么我们要麻烦它进行更新?

另外,如果登记的线程被挂起,当前线程如何继续执行(假设大多数示例代码都调用DetourUpdateThread(GetCurrentThread());)?

最后,您是否可以挂起当前进程的所有线程,从而避免争用情况(考虑可以随时创建和销毁线程)?也许这是在交易开始时完成的?这将使我们能够更安全地枚举线程(因为似乎不太可能创建新线程),尽管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;
}

最佳答案

如何表现:
我忘了源可用!

DetourUpdateThread默默地忽略了当前线程的登记。否则,给定线程将被挂起。我不知道为什么所有代码​​示例仍然会加入当前线程!这回答了前两个问题。

至于第三个问题:
我发现了另一个绕行库,它试图通过执行以下操作来挂起所有线程:

  • 获取所有线程的快照
  • 遍历快照并挂起我们尚未挂起的线程。
  • 如果线程被挂起,则返回1(我们仍然跟踪已挂起的线程)。如果没有线程被挂起,那么我们就完成了。

  • 我认为这样的假设是,如果我们可以遍历所有线程并且它们都已经被挂起(即从拍摄快照之前开始),那么就无法再创建更多线程了。虽然不太确定CreateRemoteThread!

    编辑:回复:CreateRemoteThread。

    “一个进程中只有一个线程可以同时处于DLL初始化或分离例程中。”
    CreateRemoteThread“导致对进程中每个DLL的入口点的调用”。
    http://msdn.microsoft.com/en-us/library/ms682437%28VS.85%29.aspx

    如果您在DllMain函数中,则新线程无法开始执行(只要新线程尚未引起调用进程中每个DLL的入口点)。
    因此,如果您在DllMain函数中应用弯路,则可能会避开正在创建的新远程线程的竞争状态,并将其指令指针包含在重写的目标/蹦床函数中。

    谢谢,

    保罗

    10-07 19:52
    查看更多