C语言逆向分析——IF条件语句的反汇编,要熟悉各种if的姿势以及与或非表达式组合

第四课 IF语句的反汇编判断

 

 

第四课 练习1
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...语句的反汇编判断

IF…ELSE…语句的反汇编判断:

 

 

 

第五课 IF...ELSE IF...ELSE IF..多分支语句的反汇编判断

记住知识点:

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,但其符号为什么可以在变量前或变量后?既然可以这样,其二者区别是什么?我们可以来看一下反汇编代码:

images/download/attachments/12714021/image2021-2-21_23-29-48.png

通过反汇编代码我们看不出来其存在什么差别,我们可以借助printf函数来查看区别:

int i = 1;
 
printf("%d \n", i++);
printf("%d \n", ++i);

运行一下来看看效果:

images/download/attachments/12714021/image2021-2-21_23-35-37.png

可以看见第一个输出了1,第二个输出了3,那么我们可以暂时认为:自加、自减符号在前则自加、自减完返回,符号在前则先返回当前值,然后再自加、自减;具体的,我们来看一下反汇编代码便可得知:

images/download/attachments/12714021/image2021-2-21_23-38-19.png

如上图反汇编代码便可说明我们的猜测是正确的。

关系运算符

小于

小于等于

大于

大于等于

等于

不等于

<

<=

>

>=

==

!=

示例代码:

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最终的值是什么:

images/download/attachments/12714021/image2021-2-22_0-4-33.png

最终值为0,那么可以得出这样一个结论:1>2为表达式,表达式成立则执行问号后面的内容,不成立则执行冒号后面的内容

 

posted @ 2023-04-02 19:26  bonelee  阅读(380)  评论(0编辑  收藏  举报