首页
社区
课程
招聘
[求助]请大家看一个程序
发表于: 2007-1-6 14:26 4021

[求助]请大家看一个程序

2007-1-6 14:26
4021
程序不是很长,在VC6.0下编译通过,但运行发生异常。
这是一篇英文文章里面的代码 ,名字叫Self Modifying Code 谁有兴趣和我一起学习,可以发给他;
#include<stdio.h>
void Demo(int (*_printf) (const char *,...))
{
_printf("Hello, OSIX!n");
return;
}
int main(int argc, char* argv[])
{
char buff[1000];      
int (*_printf) (const char *,...);  //声明一个函数指针
int (*_main) (int, char **);        //函数指针
void (*_Demo) (int (*) (const char *,...)); //函数指针
_printf=printf;          //_printf指向printf
int func_len = (unsigned int)_main-(unsigned int)_Demo;//取得函数指针长度,很明显应该等于4
for (int a=0; a<func_len; a++)
buff[a] = ((char *)Demo)[a]; //拷贝指针到数组buff[1000]
_Demo = (void (*) (int (*) (const char *,...))) &buff[0];
_Demo(_printf);
return 0;
}
这个程序原意是先将函数Demo()的地址拷贝到buff,然后把buff的地址赋值给_Demo 然后调用_Demo(_printf)
调试时不知道什么原因,Demo的地址并没有传给_Demo.不知道问题出在哪儿。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 342
活跃值: (318)
能力值: ( LV12,RANK:740 )
在线值:
发帖
回帖
粉丝
2
我的理解:
#include <stdio.h>
...
_printf("Hello, OSIX!n");//这里应该是\n吧?!呵呵这个是鸡蛋里挑骨头,玩笑。
...

//int func_len = (unsigned int)&_main-(unsigned int)&_Demo;//取得函数指针长度,很明显应该等于4<= 好像不对吧,应该改为下面这样.

_main=main;//加两句赋值语句
_Demo=Demo;
int func_len = (unsigned int)_main-(unsigned int)_Demo;//这里应该是取得Demo函数函数体的长度,以备后面拷贝的时候用.这个值好像只有在编译成release版本的时候才正确.
...
_Demo(_printf);//这里运行的实际是buff的内容,我们将Demo函数的函数体拷贝到了buff中,所以buff实现了和Demo一样的功能.当然我们可以在buff中拷入任何的可执行代码.
printf("%d",buff[0]);//这里加一句:若没有这句话,release版会把for语句给"优化"掉,可能是编译器认为没有引用吧.
return 0;
}
编译成release版,运行成功.
2007-1-6 17:26
0
雪    币: 191
活跃值: (55)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
非常谢谢aalloverred的帮助。
先承认一下错误,一开始我就对buff数组的作用理解错误 而且对_main和_Demol两个变量的作用也没弄明白。谢谢aalloverred指出
但是我还有一个疑问 为什么输出Debug还会发生异常呢?
2007-1-6 23:09
0
雪    币: 191
活跃值: (55)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
在原文中找到答案啦。文章是这样说的“One note about VC++:
if you are in debug mode, the compiler will insert an
"adapter" and allocate the functions somewhere else.
Damn Microsoft”
翻译过来就是:
VC++ 在debug模式下,编译器会插入一个“适配器”,而且会把会把函数放在其他地方,鄙视微软

晕 微软真可恶  
又在下面找到答案了:
在debug模式下 在工程 ->设置->连接->再选中 允许配置文件
这样在 debug 模式下就不会发生异常了
2007-1-6 23:51
0
雪    币: 1790
活跃值: (3899)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
记得以前就看到过能把自身二进制代码打印出来的程序,现在算是了解其方法了

谢谢楼主
2007-1-8 20:39
0
游客
登录 | 注册 方可回帖
返回
//