如何通过改写进程地址空间的数据来达到插入汇编的功能

今天在找如何在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函数的目标。

从上述程序的汇编代码运行上可以更清晰地看到结果,如下所示

以上就是本博客的全文,本人限于能力,上文中难免有错误的地方,若读者发现上文的错误,请于评论区中指出,本人看到之后会立即修改的,谢谢。

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