3

我正在尝试修补函数cat()以返回 true,但由于某种原因,当我什至不调用该函数时程序崩溃。问题是我的修补方法吗?我想我写的是正确的地址(函数的地址是 004012e4)。我在 Windows XP 32 位系统上使用代码块 (gcc)。

#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

int cat()
{
    cout<<"false"<<endl;
    return false;
}

int main()
{
    DWORD beef;
    int (*css)();
    css=cat;
    cout<<css<<endl;
    system("PAUSE");
    VirtualProtect(&css,49,PAGE_EXECUTE_READWRITE,&beef);
    asm("mov $0x40130f,%eax");//move address of the mov $0x0,eax instruction to eax
    asm("movl $0x1,(%eax)");//write at address changing B800 to B801 or return true

    return 0;
}
4

2 回答 2

2

为什么要硬编码函数地址?你有它的代码,你正在打印出来。如果您打印它然后更改代码以包含您打印的内容,则您可能会移动该功能。为什么不只是动态生成汇编语句?

于 2012-12-06T15:22:46.807 回答
0

我对此不是 100%,但我很确定代码段没有映射到数据选择器。x86 CPU 中的默认数据选择器段被调用ds,但代码位于选择器寄存器上cs。出于安全原因(也可能是虚拟内存空间原因),我相信代码通常不会映射到同一空间。

不熟悉 GCC asm,但这样的事情可能会奏效:

asm("mov $0x40130f,%eax");
asm("push %%fs");
asm("mov %%cs,%%fs");   // Not sure you can address memory using cs:eax directly...
asm("movl $0x1,%%fs:(%eax)");
asm("pop %%fs");

自从我编写汇编程序以来已经有很长时间了,但是您可能会看到我在说什么。

于 2012-12-06T16:37:39.747 回答