2010-04-14 53 views
5

我對Microsoft Detours圖書館有幾個簡單的問題。我已經使用過它(成功),但我只是想過這個功能:Microsoft Detours - DetourUpdateThread?

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

回答

4

如何embaressing:我 忘記來源是可用的!

DetourUpdateThread靜靜地忽略了當前線程的入侵。否則,給定線程暫停。我想知道爲什麼所有的代碼示例無論如何都爭取當前線程!這回答了前兩個問題。

至於第三個問題: 我發現,試圖通過執行以下操作暫停所有線程的另一個繞行庫:通過快照中的所有線程

  1. 獲取快照

  2. 循環,並暫停我們尚未暫停的線程。

  3. 如果線程被掛起,然後回到1(我們仍然跟蹤我們已掛起的線程)。如果沒有線程被掛起,那麼我們就完成了。

我認爲,假設是,如果我們可以通過所有線程循環,他們都已經懸浮(即從之前我們採取了快照),則可以尚未創建多個線程。雖然不是很確定CreateRemoteThread!

編輯:回覆:CreateRemoteThread。

「進程中一次只能有一個線程處於DLL初始化或分離例程中。」 CreateRemoteThread「導致調用進程中每個DLL的入口點」。如果你是在一個DllMain函數 http://msdn.microsoft.com/en-us/library/ms682437%28VS.85%29.aspx

一個新的線程不能開始執行(只要新的線程尚未引起調用每個DLL的過程入口點)。 因此,如果您在DllMain函數中應用您的彎路,您可能只是從正在創建的新遠程線程的競態條件中安全並且其指令指針位於重寫的目標/蹦牀函數中。

感謝,

保羅

+0

感謝分享! – Danra 2012-08-01 11:30:23