对于《C++反汇编与逆向分析技术揭秘》第一章~第四章学习过程中的一些汇编代码及对应的c++代码的积累。
一、第一章
浮点数相关
(1)
(2)浮点数作为返回值
(3)类型转换函数_ftol(将float型转换为int型)的实现
二、第二章
指针
(1)各类型指针访问同一地址
(2)各类型指针的寻址方式
常量
四、第四章
算术运算与赋值
1.各种算术运算的工作形式
####### 代码片段1
####### 代码片段2
其优化过程如下——
####### 减法运算示例——Debug版
####### 各类型乘法转换——Debug版
####### 乘数不等于2\4\8的组合运算
####### 各类型乘法转换——Releas版
在这里补充一个知识点,关于汇编指令lea
。
- 如果
lea
指令的第二个操作数是寄存器必须要加[],不然会报错,此时lea
就是取[寄存器]的值。如:mov eax,2; lea ebx,[eax];
执行后ebx=2。 - 如果
lea
指令的第二个操作数是变量,加不加[]都是一样的效果,都是取变量的地址,相当于指针。如:num dword 2; lea ebx,num; lea eax,[num];
eax为num的地址,如eax=4206598,随程序不同不同,这时ebx==eax。
有的作者(以及编译器)会利用lea指令支持的寻址模式(即第二个操作数是寄存器的情况)来计算一些例如一个数乘2/4/8并且加另一个数一类的运算,所以如果你感觉计算的东西不太像个真正的内存地址,它有可能真的不是。例如——
lea edx, ds:5[esi*4] //此句代码等同于lea edx, [esi*4+5],都是混合运算;
//此时esi中存的是一个具体的变量值;
//执行之后edx=(esi中的值*4+5);
补充参考资料——
####### 各类型除法转换——Debug版
(1)该代码中只对除数为2的幂的情况进行了优化处理,其理论推导如下图——
代码中0040B80C的cdq是符号扩展到高位edx,如果eax的最高位(符号位)为1,那么edx的值为0xFFFFFFFF,也就是-1,否则为0。0040B80D地址处的sub eax,edx指令执行的操作是将eax减去高位edx,实际上就是被除数为负数的情况下由于除数为正数(+2的幂),故除法的商为负数。移位运算等价于向下取整,C语言的除法是向零取整,因此需要对商为负的情况做加1调整(见上图推导结论),减去-1等同于加1。eax不为负则减0,等于没处理。最后sar右移完成除法。这样的设计可以避免分支结构的产生。
代码中0040B854的cdq是符号扩展到高位edx,如果eax的最高位(符号位)为1,就是说被除数eax里面保留了负数值,那么edx的值为0xFFFFFFFE,也就是-1,否则为0。在以上代码中,0040B855处对edx做位与运算,当被除数为负数时,edx的值为7,否则为0。在0040B858处的 add eax,edx就是被除数为负数时加上8-1,不为负则加0,等于没处理。最后sar右移完成除法。
####### 各类型除法转换——Release版
(2)该代码中对除数不为2的幂的情况做了优化,其理论推导1如下图——
在解释其含义前,我们先来看看两个相关的小练习——
- 练习1
在地址text:00401004处,我们看到了 mov eax,38E38E3h,此后做了乘法和移位操作,最后直接使用edx显示。在乘法指令中,由于edx存放乘积数据的高4字节,因此直接使用edx就等价于乘积右移了32位,再算上text:0040100B sar edx,1,那就一共移动了33位。
在地址text:0040100D处,eax得到了edx的值,然后对eax右移了1Fh位,对应10进制也就是右移了31位,然后有个很奇怪的加法。其实这里移位的目的是得到有符号数的符号位,如果结果是正数, add edx,eax就是加0,等于什么都没干;如果结果是负数,由于其后面的代码直接使用edx作为计算结果,需要对除法的商调整加1。
该汇编代码反推出优化前的高级代码为——
printf("%d", argc/9);
由此引申出的通用模式1总结如下——
- 练习2
详细的推导参见教程,这里只给出由此引申出的通用模式2总结如下——
回到两个练习之前的代码部分(对红框中加法指令的详细解释见教材)——
由此引申出的通用模式3总结如下——
(3)除数为负的2的幂——理解同上除数为正的2的幂。
(4)除数为负的非2的幂——注意如何区分除数为负和除数为正的情况。
- 情况1
由此引申出的通用模式4总结如下——
- 情况2
由此引申出的通用模式5总结如下——
####### 取模运算
####### 取绝对值
2.自增和自减
关系运算与逻辑运算
1.表达式短路
(1)使用逻辑与完成表达式短路实现跳过递归调用
(2)使用逻辑或完成表达式短路实现跳过递归调用
2.条件表达式
(1)
(2)
由此引申出的通用模式6总结如下——
(3)
由此引申出的通用模式7总结如下——
(4)