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