逆向知识第八讲,if语句在汇编中表达的方式
2017-11-14 02:16
281 查看
逆向知识第八讲,if语句在汇编中表达的方式
一丶if else的最简单情况还原(无分支情况)
高级代码:#include "stdafx.h" int main(int argc, char* argv[]) { unsigned int nNumber = 0; scanf("%ud",&nNumber); if(argc == 0) { nNumber = 0; //第一种情况下无分支 } else { nNumber = -1; } return nNumber; }
总共两种情况,我们看下Release中怎么优化的把(注意,优化方式选择O2,速度优先)
汇编代码:
可以看到我们熟悉的代码了.也就是昨天的三目运算.
总共三行汇编代码.
还原套路一样,还是 代入大于0 小于0 还有==0,看看最终结果是什么.
鉴于昨天还原过代码了,这里这届代入,还原出高级代码.
argc > 0的情况下 if(argc > 0) eax = -1
argc < 0的情况下 if(argc < 0) eax =-1
argc == 0的情况下 if(argc == 0) eax = 0
综合三种情况,可以得出具体的条件了. 其中 ><这样写是在高级语言中不能这样写的,
所以得出的还原代码为
if(argc == 0) eax =0 else eax == -1
二丶if else 的第二种情况(减少分支)
高级代码:// MyCode.cpp : Defines the entry point for the console application. // #include "stdafx.h" int main(int argc, char* argv[]) { unsigned int nNumber = 0; scanf("%ud",&nNumber); if(argc == nNumber) { printf("%d",nNumber / 8); } else { printf("%d",nNumber / 5); } return nNumber; }
对应汇编代码:
这个主要涉及找上下界问题
1.地址: 1018 101C 分别保存了局部变量的值
2.地址: 1023 比较了argc和局部变量Var4的值
3.地址: 1025 jnz跳转,因为1023地址的比较会影响标志位 由此判定, argc和var4比较,jnz(不相等)但因为汇编中是反条件,所以是相等的情况下
4.因为jnz是一个地址,所以这个地址是一个下界,那么jnz上面的比较代码则是上界,在其内部,我们还原为if语句块(先不用管里面具体干啥)
还原if语句块
if(argc == var4) printf("%d",var4 / 8);
还原else语句块
else printf("%d",var4 / 5);
在下方我们发现了相同的汇编代码,也就是把retn放到上面去了,这个主要是为了减少分支.
三丶if else 第第三种形式,代码外提的情况
代码外提的情况下,主要在优化方式的选择上,我们知道 o2(优化方式是速度优先) 现在我们改成o1(也就是体积优先了)这个时候就会出现代码外提.
高级代码:
// MyCode.cpp : Defines the entry point for the console application. // #include "stdafx.h" int main(int argc, char* argv[]) { unsigned int nNumber = 0; scanf("%ud",&nNumber); if(argc == nNumber) { printf("Hello"); } else { printf("World"); } return nNumber; }
切换为o1
protect -> setting即可.
对应汇编代码:
首先,找if else的时候,先确定上下界
地址: 101A位置 寻得了 if的上界
地址: 101E位置 寻得了 if的下界
注意: 中间划掉了两个指令,这两个指令是流水线优化,平栈的指令.所以没有帮助,划掉
地址: 1025位置,其指令跳转的地址是一个增量,那么则确定是else的下界
地址: 1027位置 寻得了else的上界
其实简单来说,第一个跳转位置,跳转到哪里的一块区域,是一个if的语句块而跳转的位置则是else语句块的上界,其上面固定一个jmp(注意其地址跳转是一个增量)那么跳转的地址是else的下界
重点代码外提:
我们可以看到 我们的if语句块中 push了一个 hello,我们的else语句块中,push了一个 word
那么除了if else 直接调用的printf,这样也是可以的.因为参数是一样的.平栈都是相等的.所以可以提到外面来打印输出.
四丶多分支if elseif .... else的还原
这个其实很简单了.如果是多分支,则寻找上界下界即可.因为编译器做的东西很多了.
高级代码:
// Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" int main(int argc, char* argv[]) { unsigned int nVar_4 = 5; scanf("%d", &nVar_4); // argc == 0 ? 0 : -1 if (argc == 0) { printf("argc == 0\r\n"); } else if(argc == 1) { printf("argc == 1\r\n"); } else if(argc == 2) { printf("argc == 2\r\n"); } else if(argc == 3) { printf("argc == 3\r\n"); } else { printf("else\r\n"); } printf("haha\r\n"); printf("haha\r\n"); printf("haha\r\n"); printf("haha\r\n"); printf("haha\r\n"); return nVar_4; }
对应汇编代码:
看到这种,直接判断为 if else if else if else这种语句,然后寻找上下界即可.
相关文章推荐
- 逆向知识-汇编寻址方式汇总
- 逆向知识第七讲,三目运算符在汇编中的表现形式,以及编译器优化方式
- 反汇编逆向实例_ifelse语句反汇编
- 【逆向知识】逆向知识笔记-寄存器、栈的存储方式、反汇编指令、跳转
- 第七章 if条件语句的知识和实践(邮件报警)
- Android逆向中常用的ARM汇编指令基础知识
- 快速识别汇编中等价的C语言语句(if, while, for, switch)
- 用正确的方式写if语句――与零值作比较
- if语句的汇编表示
- 逆向初学【一】:汇编入门-基础知识
- if 语句在汇编的作用
- 逻辑运算符,if、swtch语句(java基础知识三)
- 用正确的方式写if语句——与零值作比较
- 一天一条shell知识------shell的结构之判断语句if-then
- X86 寻址方式、AT&T 汇编语言相关知识、AT&T 与 Intel 汇编语言的比较、gcc 嵌入式汇编
- 逆向知识十三讲,汇编中数组的表现形式,以及还原数组
- 反汇编逆向实例_while语句反汇编
- Android逆向中常用的ARM汇编指令基础知识
- 九、运用栈的知识对后缀表达式的运算方式进行表达
- 快速识别汇编中等价的C语言语句(if, while, for, switch)