把函数复制到堆上并运行的方法
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
实现如下:
[table=95%]
{
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]
这里能正确运行,但这种方法并不保险。
实际情况可能是:1、编译器产生的代码是多变的。2、刚刚好其它指令里没有 0xe8 这个机器码,要经过很多重判断(否则是话就大错特错了,:mrgreen: )
二、还有就是用直接调用的方法,或类似方法
[table=95%]
{
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
相关文章推荐
- 使用运行时函数实现方法交换
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。问题的解决方法!
- C/c++中计算函数运行时间的两种方法
- 保存下在线运行代码调试的方法,方便以后复制
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。问题的解决方法!
- 不使用字符串库函数实现字符串复制的几种方法
- python_获取当前代码行号_获取当前运行的类名和函数名的方法
- 对CUDA内核函数运行时间测量的方法
- Office 2010 您正试图运行的函数包含有宏或需要宏语言支持的内容-解决方法
- 正试图在os加载程序锁内执行托管代码。不要尝试在DllMain或映像初始化函数内运行托管代码 问题解决方法
- 运行时中函数调用黑魔法swizzle,交换两个方法或者改变一个方法的实现
- OFFICE 2010 您正试图运行的函数包含有宏或需要宏语言[解决方法]
- Golang记录、计算函数执行耗时、运行时间的一个简单方法
- myeclipse中直接复制的项目或项目改名后不能正常运行的解决方法
- javascript两种禁止一个函数没有运行结束时就再次调用的方法
- 对CUDA内核函数运行时间测量的方法
- jquery delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数
- php不使用copy()函数复制文件的方法
- Matlab函数运行时间的三种计算方法
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。问题的解决方法!