今天研究了下 RAM 代码

动态修改代码实践
本文介绍了一种通过在运行时动态修改机器指令实现的快速加法函数。利用IA-32指令集,通过直接操作指令流的方式,实现了对指定变量的即时增量更新。此方法展示了动态代码生成与修改的技术细节。

初步研究了下一种有趣的技术: 能动态修改的代码。 把机器指令写到数组中,并且动态修改他。据称在某些场合能极大提高速度(譬如,无需传递参数,可以动态修改流程)。 偶今天用VC尝试了一下简单的ram函数,颇为有趣,虽然这个例子并未看到高效在哪里...

比如下面的程序定义了一个ram函数 addInt , 他将一个数加上另一个数(使用 IA-32指令集,即目前32位奔腾和AMD兼容机的指令集):

int main(){
    static unsigned char addInt_fd[] = {
        0x81, 0x05,                //0000 add [<address>], <num>
        0x00, 0x00, 0x00, 0x00,    //0002   -<address>
        0x00, 0x00, 0x00, 0x00,    //0006   -<num> addInt_by
        0xc3,                      //000a ret
    };

    void* &addInt_address = *(void**)( addInt_fd + 0x02);      // address of the num to add
    long  &addInt_num     = *(long* )( addInt_fd + 0x06);      // the constant to add to num
    void (*addInt)()      = (void (*)())((void*) addInt_fd );  // the func


    int a = 874;
    addInt_address = &a;
    addInt_num = 5910000;

    addInt();

    printf( "%d/n", a );
}

 

输出:

5910874

 

怎么做的呢? 首先讲一下用到的指令。 若有变量long a ,他的地址是 0x 004010ff。 我们要把它的内容增加 0xaabbccdd,最快速的指令是: 

<格式>  add dword ptr [ lhs ], rhs                                     ; lhs 和 rhs 都是dword立即数
<指令>  add dword ptr [ 0x004010ff ],   0xaabbccdd
<编码>  81 05     ff 10 40 00     dd cc bb aa

 

所以现在我定义一段内存 addInt_fd, 他的内容是半成品的 add 指令:

81 05    00 00 00 00    00 00 00 00 

两个全0 的dword 是占位符。 现在我们可以在运行时把a 的地址写到 lhs 上,把需要增加的量写到 rhs 上,然后强行call 这个 addInt_fd 的地址。 最后加一个 ret 指令就可以返回,其编码是:

c3 

为了方便调用和输入指令,我用两个引用指向需填参数的地址,并且用一个函数指针指向这段内存的首地址。这样就完成了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值