逆向基础之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.综合前面三种
如图所示,除了建表也有直接比较的
今天的文章就到这里了,如果有任何不明白的地方欢迎与我交流,我必定知无不言。这篇文章也花了一定的心血,喜欢的小伙伴可以点赞关注哦。感激不尽!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通