一道BT的面试题

      昨天在网上看到一个BT的面试题,代码如下:问题是运行这个程序屏幕上为什么会出现一个  :)  ,就是一个冒号加一个右括号。

      注:环境VC6 SP6 + vista sp2

      我囧,当然是先跑起来看一下,debug下确实在屏幕上打印出来一个 :) ,再看看程序,它把c2的地址强制转换为了一个函数指针,它想干嘛?!然后下面还调用了这个函数,居然没crash,看来是c2里面的数值有点特殊,可能是构造的指令码,懒得分析了,直接把debug下编出来的文件放OD里面看一下,跑到函数调用的地方,如图:

      三个红框的部分是两次调用pf和一次调用printf的位置,前面给c1和c2分配了空间,调用pf实际上直接就是运行EBP-C处的代码也就是指令执行到栈上去了,牛×,第一个call跟进去,如下图:

      那个指令00B8 00004000 C3实际上就是c1和c2的值,可以转换成十六进制看一下,RETN返回之后,EAX中的值是00400000,很神奇的一个数字啊,为什么神奇,因为EXE文件加载到内存中的时候基址就是Ox00400000,所以实际上,这个时候EAX指向的是pe文件的第一个字节。

      PE文件的第一个字节是啥?打开来看下:4D,传说中的MZ。再看第一个图片的代码,函数返回后把EAX加1,然后取指向的值,返回0x5A,接着这个值减去0x31,再存入ECX,计算出来是十进制41,查下ascii表http://apps.hi.baidu.com/share/detail/703688,果然是对应的右括号,第二个冒号也可以同样分析出来,汗。机器码前,了无秘密。

      还有一个问题是,如果我编成release来跑的,直接crash,还是OD看一下是啥问题:

      我囧,怎么这两个变量c1和c2没了……直接去执行堆栈指针指向地址的堆栈上的东东,不crash才怪了。那就给编译器使个障眼法,让它不优化掉这两个变量吧。杯具的代码。

 

【END】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值