从反汇编的角度看C++语法(hani199012@gmail.com.cn/QQ :1121797386)
写在前面的话
写这些读书笔记,主要是对自己在学习C++过程中遇到的一些问题进行总结,同时,利用反汇编工具来看C++语法在实际内存中的体现,因为,C++是一门高级语言,其实是写给人看的,但是机器只认识0 1 ,如果弄懂汇编语言,查看一些练习的程序的反汇编代码,这样,在学习高级语言的时候,看到底层中内存的布局,和实际的函数之间的调用关系,如此看得更加实际,不在那么抽象。
主要的参考书籍是《C++反汇编与逆向分析》(钱林松 赵海旭),《老码识途--从机器码到框架的系统观逆向修炼之路》
这几本书确实写的很好。
其实,我也是个学习者,通过写一点总结性的文章,放到网上,希望,能够得到大家的批评与建议,进一步能够相互学习。
用到的工具: VC++6.0或者 VS2008 等
摘自 《老码识途》
下面是我测试的情况(基本上和书中说的一样)
1、VC6.0 debug版
[ebp-4] 中存放的是变量i 的值, [ebp+ecx*4-2ch] 是 a[i] ecx*4 对应i 2ch 是 44(十进制) 当i=10 的时候 [ebp+ecx*4-2ch]就变为 [ebp-4] 被赋值为0 ,则陷入死循环
2、VC6.0 release版
下面是我用OD反汇编的结果
00401000 把寄存器esi中的值压入栈中,保存
00401001 把寄存器edi中的值压入栈中,保存
00401002 把这个地址(由基地址加偏移地址组成)对应的数 据传入edi
00401008 esi esi 进行异或操作,也就是 esi清零
0040100A 把ds:[ebx]地址 传给 ebx(取地址操作)
00401010 把esi 压栈保存
00401011 把loop.004020F4压栈保存
00401016 call edi 就是调用函数 edi 就是刚才保存的打印函数,调用printf函数
00401018 esi 里面的数据减1
00401019 esp(栈指针寄存器) 里面的数据+8 ,平衡call
0040101c 比较esi 中的数据 与10(十进制)
0040101F 不相等就跳到循环开始
综上 ,esi 保存了一个变量 ,假设为a (初值0),做++ 运算,当这个变量a 大于10 就跳出循环,并把esi中的值传给printf作为参数,输出
函数传参,通过把参数值保存到栈中,然后call 函数,在函数里面通过ebp加偏移地址做相应的操作,如果,有返回值,把返回值保存到栈中,这样,函数参数传入后,通过保存在栈中的返回值得到结果了。
3、Vs 2008 debug 版
38h 比 2ch 要大,不会出现vc6.0 debug版的情况。Vs2008之后的版本中,有很多这样这样的情况,把一些默认的值都增大了,起到了优化的作用。