Microsoft Detours - DetourUpdateThread? - PullRequest
       5

Microsoft Detours - DetourUpdateThread?

6 голосов
/ 14 апреля 2010

У меня есть несколько вопросов о библиотеке 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;
}

1 Ответ

5 голосов
/ 14 апреля 2010

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

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

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

  1. Получить снимок всех потоков

  2. Выполните цикл по снимку и приостановите потоки, которые мы еще не приостановили.

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

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

Редактировать: Re: CreateRemoteThread.

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

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

Спасибо

Пол

...