[英]How to check whether new threads created inside third party DLL in visual c++ application
我目前正在努力驗證是否可以從可視c ++應用程序中的代碼調用的dll文件中創建新線程。 最好是我想查看資源消耗並在dll內部創建任何線程的情況下調用堆棧。 我需要在非調試模式下運行應用程序時發生這種情況。 你們中有人知道我們如何解決這個問題嗎?
讓應用程序在其啟動代碼中掛接CreateThread API,最好在DLL初始化之前。 雖然這是深奧的魔力。 您必須確切地知道自己在做什么。
編輯:如果您要問,您可能不適合該任務。 繼續需要您自擔風險。
大概的想法是:使用反匯編程序在正在運行的進程中查看CreateThread()
的前幾個命令。 在主要的exe代碼中,修補CreateThread的內存,以將JMP命令插入到自己的蹦床功能中。 在匯編中編寫一個蹦床,它將調用您自己的鈎子函數,也許從修補部分重復一些命令,然后跳回到CreateThread()的未修補部分。
這不是用於生產-僅用於在自己的計算機上運行具有已知版本的CreateThread的可執行文件,因為這將取決於CreateThread的內容。 在某種程度上,應用程序成為其自己的調試器,但這不是DLL可以輕易注意到的調試器。
要修補進程內存的可執行部分,您可能必須調整內存保護標志,默認情況下它將不可寫。
自然,您必須介意這些問題。
另外,您可以修補CreateThread的開頭以引發異常(例如INT 3),並使用向量異常處理程序來捕獲該異常。 Win32 API函數的開頭有一個2字節的NOP,剛好可以打補丁。
編輯:嘗試了VEH方法,似乎更干凈。 現在,在我的機器上,CreateThread的第一個命令是MOV EDI, EDI
實際上是2字節的無操作,非常適合修補。 因此,異常處理程序變為:
LONG NTAPI OnExc(_EXCEPTION_POINTERS* Exc)
{
if (Exc->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
{ //Feel free to add an extra check for exception address
//Just in case there are rogue INT 3's elsewhere
wprintf(L"Yay, thread created\n");
//Not a good idea to do I/O from the exception handler :)
//Continue from the next command after INT 3
Exc->ContextRecord->Eip++;
return EXCEPTION_CONTINUE_EXECUTION;
}
else
return EXCEPTION_CONTINUE_SEARCH;
}
掛鈎代碼如下:
AddVectoredExceptionHandler(1, OnExc);
HMODULE hKernel32 = GetModuleHandle(L"kernel32.dll");
unsigned char* pCreateThread = (unsigned char*)GetProcAddress(hKernel32, "CreateThread");
//Allow writing to the memory block where CreateThread is
MEMORY_BASIC_INFORMATION mi;
VirtualQuery(pCreateThread, &mi, sizeof mi);
DWORD dw;
VirtualProtect(mi.BaseAddress, mi.RegionSize, PAGE_EXECUTE_READWRITE, &dw);
//Check if the first two bytes are indeed MOV EDI, EDI
if (pCreateThread[0] == 0x8b && pCreateThread[1] == 0xff)
{
//And patch!
pCreateThread[0] = 0xcc; //Replace with INT 3
pCreateThread[1] = 0x90; //Replace with NOP
}
就這樣,着迷了。 可以通過調用_beginthread
或_beginthreadex
隨意進行測試-但不能在調試器下進行。 調試器將在異常處理程序執行之前捕獲並處理INT 3。
這都是32位代碼。 甚至都沒有看過Win64的外觀。
我沒有涉及其他方面的工作。 具體來說,如果所討論的DLL是靜態加載的, 並且在其啟動代碼中創建了線程, 並且如果該鈎子安裝在[Win] main()中,則該鈎子將無法捕獲那些線程。 由於這是您的項目,因此我無法對其進行檢查。
增強的另一種途徑-如果您想捕獲線程創建的結果(例如,線程ID),僅此技術是行不通的。 您不僅需要鈎住CreateThread的入口點,還需要鈎住出口。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.