您的位置:首页 > 其它

把函数复制到堆上并运行的方法

2012-08-21 11:11 92 查看
有需求见此贴,所谓的动态执行 http://bbs.chinaunix.net/thread-1235365-1-1.html
实现如下:

[table=95%][font=FixedSys]void add(int a, int b)

{

printf("a+b=%d\n", a+b);

}

char *get_call_addr(char *p, int len)

{

while(len-- && (*p != (char)0xe8 ))

p++;

if (len)

return p;

else

return 0;

}

void set_call(int call_addr, int fun_addr)

{

int ip = call_addr + 5;

int set_call_addr = call_addr + 1;

(*(int *)set_call_addr) = fun_addr - ip;

}

int main()

{

char *p = (char *)malloc(100);

memcpy(p, add, 100);

void (*pf)(int, int) = (void(*)(int, int))p;

char *call_addr = get_call_addr(p, 100);

if (call_addr) {

set_call((int)call_addr, (int)printf);

pf(10, 20);

}

return 0;

}

[/font]上面的代码能实现,将函数复制到 malloc 出来的内存里正确执行,原理就是修改里面的 call 指令偏移值。

这里能正确运行,但这种方法并不保险。

实际情况可能是:1、编译器产生的代码是多变的。2、刚刚好其它指令里没有 0xe8 这个机器码,要经过很多重判断(否则是话就大错特错了,:mrgreen: )

二、还有就是用直接调用的方法,或类似方法

[table=95%][font=FixedSys]void foo()

{

printf("I'm foo()...\n");

}

int main()

{

char *p = (char *)malloc(20);

int pf = (int)foo;

p[0] = 0xff;

p[1] = 0x15;

*((int *)&p[2]) = (int)&pf;

p[6] = 0xc3;

(void (*)())p();

return 0;

}

[/font]虽然,正确调用得到了保证,但要传递参数的话,要多动点脑子:)

http://www.chinaunix.net/old_jh/23/1237275.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐