簡體   English   中英

如何檢查是否在Visual C ++應用程序的第三方DLL中創建了新線程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM