Microsoft Detours - DetourUpdateThread?

У меня есть несколько быстрых вопросов о библиотеке Microsoft Detours. Я использовал его раньше (успешно), но я просто подумал об этой функции:

LONG DetourUpdateThread(HANDLE hThread);

Я читал в другом месте, что эта функция фактически приостановит поток до завершения транзакции. Это кажется странным, так как большинство примеров кода вызывает:

DetourUpdateThread(GetCurrentThread());

в любом случае, по-видимому, эта функция "вербует" потоки таким образом, что при фиксации транзакции (и обходе) их указатели инструкций изменяются, если они лежат "в переписанном коде либо в целевой функции, либо в функции trampoline."

мои вопросы:

когда транзакция фиксируется, указатель инструкции текущего потока будет находиться в функции DetourTransactionCommit? Если да, то почему мы должны беспокоиться о его обновлении?

кроме того, если зачисленные потоки приостановлены, как текущий поток может продолжать выполнение (учитывая, что большинство примеров кода вызывает DetourUpdateThread(GetCurrentThread());)?

наконец, не могли бы вы приостановить все потоки для текущего процесса, избегая условий гонки (учитывая, что потоки могут быть созданы и уничтожены в любое время)? Возможно, это делается, когда начинается сделка? Это позволит нам более безопасно перечислять потоки (поскольку кажется менее вероятным, что новые потоки могут быть created), хотя как насчет 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;
}

1 ответов


Как embaressing: Я забыл, что источник был доступен!

DetourUpdateThread молча игнорирует включение текущего потока. В противном случае, данный поток is приостановлено. Интересно, почему все примеры кода все равно включают текущий поток! Это ответ на первые 2 вопроса.

Что касается 3-го вопроса: Я нашел другую библиотеку обхода, которая пытается приостановить все потоки, выполнив следующее:

  1. вам снимок всех потоков

  2. цикл через снимок и приостановить потоки, которые мы еще не приостановили.

  3. Если потоки были приостановлены, то вернитесь к 1 (мы все еще отслеживаем потоки, которые мы приостановили). Если нити не были подвешены, то мы закончили.

Я думаю, дело в том, что если мы можем перебрать все нити, и все они уже приостановлено (т. е. до того, как мы взяли моментальный снимок), то больше потоков не может быть создано. Не так уверен в CreateRemoteThread, хотя!

Edit: Re: CreateRemoteThread.

" только один поток в процессе может быть в процедуре инициализации DLL или отсоединения одновременно." CreateRemoteThread "приводит к вызову точки входа каждой DLL в процессе". http://msdn.microsoft.com/en-us/library/ms682437%28VS.85%29.aspx

новый поток не может начать выполняться, если вы находитесь в Функция DllMain (пока новый поток еще не вызвал вызов точки входа каждой DLL в процессе). Поэтому, если вы применяете свои объезды в функции DllMain, вы можете просто быть в безопасности от состояния гонки нового удаленного потока, создаваемого и имеющего указатель инструкции в вашей переписанной функции target/trampoline.

спасибо,

Павел