- 论坛徽章:
- 0
|
有需求见此贴,所谓的动态执行 http://bbs.chinaunix.net/thread-1235365-1-1.html
实现如下:
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;
}
|
上面的代码能实现,将函数复制到 malloc 出来的内存里正确执行,原理就是修改里面的 call 指令偏移值。
这里能正确运行,但这种方法并不保险。
实际情况可能是:1、编译器产生的代码是多变的。2、刚刚好其它指令里没有 0xe8 这个机器码,要经过很多重判断(否则是话就大错特错了, )
二、还有就是用直接调用的方法,或类似方法
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;
}
|
虽然,正确调用得到了保证,但要传递参数的话,要多动点脑子 |
评分
-
查看全部评分
|