【问题标题】:Microsoft Detours - DetourUpdateThread?Microsoft Detours - DetourUpdateThread?
【发布时间】:2011-02-07 20:37:17
【问题描述】:

我有几个关于 Microsoft Detours 库的快速问题。我以前用过(成功),但我只是想到了这个功能:

LONG 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;
}

【问题讨论】:

    标签: c++ windows multithreading detours


    【解决方案1】:

    多么令人尴尬: 忘记有源了!

    DetourUpdateThread 默默地忽略当前线程的登记。否则,给定线程 挂起。我想知道为什么所有代码​​示例都需要当前线程!这回答了前 2 个问题。

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

    1. 获取所有线程的快照

    2. 遍历快照并挂起我们尚未挂起的线程。

    3. 如果线程被挂起,则返回 1(我们仍会跟踪已挂起的线程)。如果没有线程被挂起,那么我们就完成了。

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

    编辑:回复:CreateRemoteThread。

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

    如果您在 DllMain 函数中,则新线程无法开始执行(只要新线程尚未导致调用进程中每个 DLL 的入口点)。 因此,如果您在 DllMain 函数中应用您的弯路,您可能只是避免了正在创建的新远程线程的竞争条件,并且在您重写的目标/蹦床函数中拥有其指令指针。

    谢谢,

    保罗

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多