C语言逆向分析——IF条件语句的反汇编,要熟悉各种if的姿势以及与或非表达式组合
第四课 IF语句的反汇编判断
int plus(int Y,int X)
{
int N = t;
if(X<Y)
t=t+Y;//t=N+yC
}
void main()
{
plus(5,4);
}
IF…ELSE…语句的反汇编判断:
记住知识点:
1、当每个条件跳转指令要跳转的地址前面都有jmp 指令
2、这些jmp指令跳转的地址都是一样的
3、如果某个分支没有条件判断,则为else部分
IF…ELSE IF…ELSE IF..多分支语句的反汇编判断:
关系运算符:
“==”、“!=”、“>=”、“<=”、“>”、“<”
关系运算符的结果只有2个
,0
或者1
.
上面截图有错:
vc6实践操作看到的:
1、逻辑与(&&)
在反汇编中的形式:
逐条判断,符合条件不跳,继续判断下一条
2、逻辑或(||)
在反汇编中的形式:
逐条判断,符合条件就跳,不判断下一条
NOT非的反汇编分析:
我们再补充下运算符和表达式
运算符与表达式
什么是运算符?什么是表达式?运算符:加减乘除、大于小于等于、赋值,表达式则是由运算符和变量组成,如下代码示例,从x+y开始都是表达式:
int
x,y;
x =
12
;y =
23
;
x+y;x-y;x<y;x=y;x==y;
如果x和y类型不同,最终结果按照这个顺序进行结果类型转换:char => short => int => float => double;我们可以举例说明:
void
main()
{
char
x =
1
;
short
y =
2
;
int
z = x + y;
return
;
}
对应反编码代码为:
00410938
mov
byte
ptr [ebp-
4
],
1
0041093C mov word ptr [ebp-
8
],offset main+20h (
00410940
)
00410942
movsx eax,
byte
ptr [ebp-
4
]
00410946
movsx ecx,word ptr [ebp-
8
]
0041094A add eax,ecx
0041094C mov dword ptr [ebp-0Ch],eax
通过汇编代码我们明显可以看出其结果类型的转换。另外需要注意的是:表达式不论怎么复杂,最终只有一个结果。
注意:
MOVSX指令,有符号扩展
当我们执行,mov eax,bl的时候,会提示错误,bl是8位,eax是32位,所以需要扩展,这时需要movsx
MOVZX指令,无符号扩展
首先我们来了解一下一些常用的运算符。
算数运算符
加 |
减 |
乘 |
除 |
取余 |
自加 |
自减 |
+ |
- |
* |
/ |
% |
++ |
-- |
加减乘除、取余都很简单,我们要了解一下自加、自减的用法:
int
i =
1
;
++i;
i++;
--i;
i--;
如上就是自加、自减的用法,注意自加、自减的都是1,但其符号为什么可以在变量前或变量后?既然可以这样,其二者区别是什么?我们可以来看一下反汇编代码:
通过反汇编代码我们看不出来其存在什么差别,我们可以借助printf函数来查看区别:
int
i =
1
;
printf(
"%d \n"
, i++);
printf(
"%d \n"
, ++i);
运行一下来看看效果:
可以看见第一个输出了1,第二个输出了3,那么我们可以暂时认为:自加、自减符号在前则自加、自减完返回,符号在前则先返回当前值,然后再自加、自减;具体的,我们来看一下反汇编代码便可得知:
如上图反汇编代码便可说明我们的猜测是正确的。
关系运算符
小于 |
小于等于 |
大于 |
大于等于 |
等于 |
不等于 |
< |
<= |
> |
>= |
== |
!= |
示例代码:
int
i;
i =
1
;
int
a;
a =
2
;
i<a;
a>i;
i<=a;
a>=i;
...
注意:
关系运算符的值只能是0或1
关系运算符的值为真时,结果值都为1
关系运算符的值为假时,结果值都为0
逻辑运算符
非 |
逻辑与 |
逻辑或 |
! |
&& |
|| |
示例代码:
int
a =
0
;
int
b =
1
;
int
c = !a;
a && b;
a<b && b>a;
注意:
&& 和 ||,使用时左右两边的结果相与、相或,结果最终只有一个。
位运算符
左移 |
右移 |
非 |
或 |
异或 |
与 |
<< |
>> |
~ |
| |
^ |
& |
位运算在汇编的学习中有提到,这里不过多赘述。
赋值运算符
赋值 |
= |
条件运算符
条件运算符又称为三元运算符,由问号、分号组成,示例代码如下:
int
a;
a =
1
>
2
?
1
:
0
;
我们看下反汇编,变量a最终的值是什么:
最终值为0,那么可以得出这样一个结论:1>2为表达式,表达式成立则执行问号后面的内容,不成立则执行冒号后面的内容。