如何通過改寫進程地址空間的數據來達到插入彙編的功能

今天在找如何在Windows上編譯breakpad的答案時,看到了這個博客:https://www.cnblogs.com/cswuyg/p/3207576.html。在這個博客的代碼中學到了點東西,現在就來記錄一下。

 talk is cheap show me the code.先上代碼好了,下面的代碼是我從上面的博客上精簡下來的測試代碼,如下

#include <Windows.h>
#include <iostream>

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI TempSetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
    std::cout << "TempSetUnhandledExceptionFilter\n";
    return NULL;
}

BOOL PreventSetUnhandledExceptionFilter()
{
    HMODULE hKernel32 = LoadLibrary(L"kernel32.dll");
    if (hKernel32 == NULL)
    {
        return FALSE;
    }
    void *pOrgEntry = ::GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
    if (pOrgEntry == NULL)
    {
        return FALSE;
    }

    unsigned char newJump[5];
    DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
    dwOrgEntryAddr += 5; //跳轉指令使用5字節的空間

    void *pNewFunc = &TempSetUnhandledExceptionFilter;
    DWORD dwNewEntryAddr = (DWORD)pNewFunc;
    DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;

    newJump[0] = 0xE9;  //jump
    memcpy(&newJump[1], &dwRelativeAddr, sizeof(DWORD));
    SIZE_T bytesWritten;
    DWORD dwOldFlag, dwTempFlag;
    ::VirtualProtect(pOrgEntry, 5, PAGE_READWRITE, &dwOldFlag);
    BOOL bRet = ::WriteProcessMemory(::GetCurrentProcess(), pOrgEntry, newJump, 5, &bytesWritten);
    ::VirtualProtect(pOrgEntry, 5, dwOldFlag, &dwTempFlag);
    return bRet;
}

int main()
{
    PreventSetUnhandledExceptionFilter();
    SetUnhandledExceptionFilter(NULL);

    return 0;
}

上述代碼的功能很簡單,在PreventSetUnhandledExceptionFilter函數中,先找到SetUnhandledExceptionFilter函數在進程中的地址+5的值,爲什麼要+5呢,因爲這五個字節要存放彙編的跳轉指令E9 地址;然後獲取TempSetUnhandledExceptionFilter函數的在進程中的地址值,接着計算上面兩個值的差,最後把彙編的跳轉指令寫入到SetUnhandledExceptionFilter函數的地址。造成的結果就是,當在main函數中執行SetUnhandledExceptionFilter時,程序會跳轉到SetUnhandledExceptionFilter地址的位置開始執行,然後執行E9 地址彙編指令再跳轉到TempSetUnhandledExceptionFilter函數的位置執行,這樣就達到了屏蔽SetUnhandledExceptionFilter函數的目標。

從上述程序的彙編代碼運行上可以更清晰地看到結果,如下所示

以上就是本博客的全文,本人限於能力,上文中難免有錯誤的地方,若讀者發現上文的錯誤,請於評論區中指出,本人看到之後會立即修改的,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章