170522 逆向-控制语句的汇编和优化

本文探讨了汇编语言中的控制流程实现,包括IF-THEN-ELSE和SWITCH-CASE语句的汇编代码形式及优化技巧。通过具体示例说明了如何利用cmp、test等指令进行条件判断,并介绍了编译器如何优化条件分支以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1625-5 王子昂 总结《2017年5月22日》 【连续第233天总结】

A. 加密与解密 控制语句

B. 高级语言中用IF-THEN-ELSE、SEITCH-CASE等语句来构成程序的判断流程,不仅条理清楚,并且维护性好

然而在汇编代码中则复杂得多,由cmp等指令后面跟着各类跳转指令jz,jnz等构成

识别关键跳转是软件解谜的一个重要技能

IF-THEN-ELSE

将其编译成汇编代码以后,整数用cmp指令比较,浮点数则用fcom,fcomp等比较

IF-THEN-ELSE的汇编代码形式一般为:

cmp a,b

jz/jnz xxxx

cmp指令不修改操作数,根据两个操作数的相减结果,影响处理的几个标志

实际上,许多情况下编译器都用test或or之类较短的逻辑指令来替换cmp指令

一般形式为test eax,eax

如eax为0,则其逻辑与运算结果为0,就设置ZF位为1,否则为0

eg:

#include <stdio.h>

int main(void)

{

int a,b=5;

scanf("%d", &a);


if(a==0)

a=8;

return a+b;

}

汇编代码为:

lea eax, dword ptr [esp] ;eax指向局部变量空间

push eax

push 00407030 ;指向字符串%d

call 00401030 ;C语言的scanf函数

mov eax, dword ptr [esp+8] ;将输入的字符传出

add esp,8 ;由于是__cdecl调用,函数外平衡堆栈

test eax,eax ;若eax为0则ZF置1,否则置0

jne 00401020 ;若ZF=1不跳转,否则跳转

mov eax,8

00401020 add eax,5

pop ecx ;释放局部变量用到的内存,相当于add esp,4

ret


SWITCH-CASE

该语句编译后实质上就是多个IF-THEN语句的嵌套组合,编译器会将SWITCH变异成一组不同关系运算组成的语句

编译器在编译代码的时候,可能同一段高级语言,由于优化选项不同,产生的汇编代码也会截然不同

例如可以用dec eax指令代替cmp指令,这样更短,执行更快

另外,一些编译器优化时,在不改变原逻辑的前提下,使用数学技巧把源代码中一些逻辑分支语句转换成算术操作,消除或减少程序中出现的条件转移指令,提高CPU的性能

eg:

int main(void)

{

if(FindWindow(NULL,'计算器'))

return 1;

else

return 5;

}

用VC++编译后,汇编代码为:

push 406030 ;Title="计算器"

push 0 ;Class=0

call dword ptr [405090] ;FindwWindowA

neg eax

sbb eax,eax

and al,0FC

add eax,5

retn

首先用neg指令检验eax是否为0,结果存放在CF标志位中。sbb指令将目的操作数减去原操作数,再减去借位CF,结果送到目的操作数。sbb eax,eax这局的结果由CF决定,当CF为1时,eax为-1,否则为0。

接下来根据eax的值FFFFFFFFh和0来决定最终结果。当eax是FFFFFFFFh时,计算结果是1;当eax是0时,计算结果为5

and al,0FC

add eax,5

这类代码比较常见,要知道是条件转移指令优化生成的,才有思路去还原

C. 明日计划

加密与解密 循环语句

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值