C ++ /内联汇编中的运行时修补

时间:2012-12-06 15:02:17

标签: c++ inline-assembly

我正在尝试修补函数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;
}

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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");

自从我编写汇编程序以来已经有很长一段时间了,但你可能已经看到了我的目标。