逆向基础之C语言:C语言switch case以及它的反汇编

一.if else if 转换成switch case的形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int fun()
{
    int a;
    int b;
    a=1;
    b=2;
    if(a+b==0)
    {
        a++;
    }
    else if(a+b==1)
    {
        b++;
    }
    else if(a+b==2)
    {
        b++;
    }
    else if(a+b==3)
    {
        b++;
    }
    else if(a+b==4)
    {
        b++;
    }
    else
    {
        a=a+b;
    }
    return 0;
}

  上面的这个函数是用if else if写的,转换成switch case写就如下面代码所示.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int fun()
{
    int a;
    int b;
    a=1;
    b=2;
  
    switch(a+b)
    {
    case 0:
        {
            a++;
            break;
        }
    case 1:
        {
            b++;
            break;
        }
    case 2:
        {
            b++;
            break;
        }
    case 3:
        {
            b++;
            break;
        }
    case 4:
        {
            b++;
        }
    default:
        {
            a=a+b;
        }
    }
    return 0;
}

  

由此例可以看出,If else if转换成switch case的形式必须满足下面三个条件:

1.必须是==表达式

2.等号左边必须是相同的表达式

3.等号的右边必须是常量或数字,而且数字要互不相同.

二.switch case多减去4字节空间

switch case多减去4字节空间,用来存放表达式的结果

如图所示,只有两个变量却减了C,ebp-c的位置用来存放表达式a+b的结果

三.switch case怎么判断比较的位置

如果case从0开始,则比较最大case数

上面写的代码case从0开始,最大是4, 则比较的就是最大case数.

如果case不从0开始,则先减去最小的case数,变为从0开始
然后比较时用最大的case数减去最小的case数,就是比较的值

如下面代码case不从0开始,最小的case数为1,最大的case数为8

 

复制代码
switch(a+b)
    {
    case 2:
        {
            a++;
            break;
        }
    case 1:
        {
            b++;
            break;
        }
    case 8:
        {
            b++;
            break;
        }
    case 3:
        {
            b++;
            break;
        }
    case 4:
        {
            b++;
        }
    default:
        {
            a=a+b;
        }
    }
复制代码

 

那么它的反汇编就是先减去最小的case数1,比较时就是最大的case数8减去最小的case数1,比较的值为7,如下图所示

四.switch case的几种情况

1.case数连续的,会建一张表,case地址表,表里放case数的地址

如上图所示是case0,case1,case2,case3,case4这样的反汇编,建了一张表,表里存放了每一个case数的地址.

2.相对连续的情况,它会建两张表,第一张表是编号表,里面放case的编号,从0开始,如果没有的case,里面存放的是case的个数,对应default的位置.第二张表记录case的地址,用case的编号加上case的地址找到case的位置.

复制代码
switch(a+b)
    {
    case 0:
        {
            a++;
            break;
        }
    case 1:
        {
            b++;
            break;
        }
    case 2:
        {
            b++;
            break;
        }
    case 11:
        {
            b++;
            break;
        }
    case 12:
        {
            b++;
        }
    case 13:
        {
            b++;
        }
    default:
        {
            a=a+b;
        }
    }
复制代码

代码如上所示,case0,1,2连续,后面11,12,13连续

如上图红框所示,右边的红框为编号表,没有case的就用总个数6代替,有case的就从0依次编号

上图红框表示第二张表,case地址表,里面的内容对应每个case的地址

3.毫无规律的情况,直接判断比较,一般比较方式:用二分法

复制代码
switch(a+b)
    {
    case 0x100:
        {
            a++;
            break;
        }
    case 0x300:
        {
            b++;
            break;
        }
    case 0x500:
        {
            b++;
            break;
        }
    case 0x1000:
        {
            b++;
            break;
        }
    case 0x6000:
        {
            b++;
            break;
        }
    case 0x8000:
        {
            b++;
        }
    case 0x9000:
        {
            b++;
        }
    default:
        {
            a=a+b;
        }
    }
复制代码

case数如上面的代码所示

反汇编直接从中间的1000开始比 ,二分法比较.

4.综合前面三种

如图所示,除了建表也有直接比较的


今天的文章就到这里了,如果有任何不明白的地方欢迎与我交流,我必定知无不言。这篇文章也花了一定的心血,喜欢的小伙伴可以点赞关注哦。感激不尽!

posted @ 2022-06-21 12:10  逆向小星同学  阅读(297)  评论(0编辑  收藏  举报