滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编

滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编

  • 一、Switch语句
    • 1、switch语句 是if语句的简写
    • 2、break加与不加有什么特点?default语句可以省略吗?
    • 3、游戏中的switch语句(示例)
    • 4、添加case后面的值,一个一个增加,观察反汇编代码的变化(何时生成大表).
    • 5、将3中的常量值的顺序打乱,观察反汇编代码(观察顺序是否会影响生成大表).
    • 6、将case后面的值改成从100开始到109(连续),观察汇编变化(观察值较大时是否生成大表).
    • 7、将连续的10项中抹去1项或者2项,观察反汇编有无变化(观察大表空缺位置的处理).
    • 8、在10项中连续抹去,不要抹去最大值和最小值(观察何时生成小表).
    • 9、将case后面常量表达式改成毫不连续的值,观察反汇编变化.
    • 10、部分连续,部分差值非常大
  • 二、do/while反汇编
    • 1、do/while的语法
    • 2、do/while的反汇编
    • 3、example
    • 4、总结
  • 三、while反汇编
    • 1、while语句的语法
    • 2、while语句反汇编
    • 3、example
    • 4、总结
  • 四、for循环反汇编
    • 1、for语句的语法
    • 2、for循环的执行次序
    • 3、example
    • 4、总结
  • 五、作业
    • 1、写一个Switch语句,不生产大表也不生产小表,贴出对应反汇编
    • 2、写一个Switch语句,只生成大表,贴出对应反汇编
    • 3、写一个Switch语句,生成大表和小表,贴出对应反汇编
    • 4、为do/while语句生成的反汇编填写注释
    • 5、为while语句生成的反汇编填写注释
    • 6、为for语句生成的反汇编填写注释

一、Switch语句

1、switch语句 是if语句的简写

  • if语句
if(表达式 == 常量1)
{//...代码
}
else if(表达式 == 常量2)
{//...代码
}
else if(表达式 == 常量3)
{//...代码
}
else
{//...代码
}
  • switch语句
switch(表达式)                
{                case 常量表达式1:语句;break;case 常量表达式2:语句;break;case 常量表达式3:语句;break;case 常量表达式3:语句;break;default:        语句;break;
}

switch要求:

1、case后面必须是常量表达式

2、case后常量表达式的值不能一样

3、switch后面表达式必须为整数

2、break加与不加有什么特点?default语句可以省略吗?

不写break时,编译可以通过,但会将不写break的case全部执行一遍。
default语句可以省略,当所有条件都不满足的时候,会默认执行default中的代码,如果不存在default,但所有条件不满足,则不执行代码。

3、游戏中的switch语句(示例)

F1  F2  F3  F4  F5  F6  F7  F8
0   1   2   3   4   5   6   7
switch(表达式)
{case 1:打坐....break;case 2:加红....        break;case 3:加蓝....        break;case 4:释放技能....break;default:语句;break;
}

4、添加case后面的值,一个一个增加,观察反汇编代码的变化(何时生成大表).

我的环境是64位的vscode,与海哥教程中存在较大差异。

  • 少分支Switch结构
void Function(int x){
switch (x){
case 1:
printf("1");
break;
case 2:
printf("2");
break;
case 3:
printf("3");
break;
default:
printf("4");
break;
}
}int main(int argc, char* argv[]){
Function(2);return 0;
}

在这里插入图片描述

由汇编可见,少分支的Switch与if相似,所以正向代码中,分支较少时建议不使用Switch

  • 多分支Switch结构
void Function(int x){
switch (x){
case 1:
printf("1");
break;
case 2:
printf("2");
break;
case 3:
printf("3");
break;
case 4:
printf("4");
break;
default:
printf("5");
break;
}
}int main(int argc, char* argv[]){
Function(2);return 0;
}

在这里插入图片描述
未发现大表寻址过程

  • 多分支Switch结构
void Function(int x){
switch (x){
case 1:
printf("1");
break;
case 2:
printf("2");
break;
case 3:
printf("3");
break;
case 4:
printf("4");
break;
case 5:
printf("5");
break;
case 6:
printf("6");
break;
default:
printf("7");
break;
}
}
int main(int argc, char* argv[]){
Function(3);
return 0;
}

在这里插入图片描述
存在大表寻址过程,已优化

  • 总结
    1、分支少于4的时候,使用Switch没有意义,因为编译器会生成类似if/else之类的反汇编;
    2、case后面的常量表达式可以是无序的,并不影响大表的生成

• 分支较少时,不生成大表,也不生成小表,会生成if…else语句
• 分支达到一定数量时,生成大表,且大表跟顺序无关
• 大表可以理解为一个存储了多个地址的连续表,通过Register*4可以来寻址。
• 分支达到一定数量,生成大表,但是中间缺少很多case时,还会生成一张小表。
• 小表的作用可以理解为把大表的空缺地址,移动到了小表,把空缺的case值所在的地方填为default的地址

5、将3中的常量值的顺序打乱,观察反汇编代码(观察顺序是否会影响生成大表).

并不影响大表生成

6、将case后面的值改成从100开始到109(连续),观察汇编变化(观察值较大时是否生成大表).

  • 代码
void Function(int x){
switch (x){
case 100:
printf("100");
break;
case 101:
printf("101");
break;
case 102:
printf("102");
break;
case 103:
printf("103");
break;
case 104:
printf("104");
break;
case 105:
printf("105");
break;
case 106:
printf("106");
break;
case 107:
printf("107");
break;
case 108:
printf("108");
break;
default:
printf("109");
break;
}
}
int main(int argc, char* argv[]){
Function(103);
return 0;
}
  • 反汇编
    在这里插入图片描述

如果[参数-100]大于[max-min],说明传入参数小于case最小值或者大于case最大值,此时直接执行default即可;
反之说明参数在min到max之间,而此时eax中存储的是[参数-100]的数值,而编译器已经维护了一张表,根据eax的位置,像一维数组查数一样根据公式,eax=基址+eax代表的内存的数据,跳转到eax的执行地址即可(jmp rax)。

7、将连续的10项中抹去1项或者2项,观察反汇编有无变化(观察大表空缺位置的处理).

在这里插入图片描述

被删除的部分并不会被填充0,大表会把抹去的分支项原先所对应的地址全部给填充为default默认地址.

8、在10项中连续抹去,不要抹去最大值和最小值(观察何时生成小表).

小表是将大表的地址移动到小表,空缺的地方填充为到default的偏移量。
海哥的教程中删除一定的case分支后,生成小表,但本地环境win64+VSCOde中,未生成小表,删除一定的分支后,直接转换成if/else形式(我也很疑惑……)。

9、将case后面常量表达式改成毫不连续的值,观察反汇编变化.

类似于if/else的结构

10、部分连续,部分差值非常大

  • 代码
void Function(int x){
switch (x){
case 300:
printf("300");
break;
case 301:
printf("301");
break;
case 302:
printf("302");
break;
case 303:
printf("303");
break;
case 304:
printf("304");
break;
case 305:
printf("305");
break;
case 306:
printf("306");
break;
case 307:
printf("307");
break;
case 3:
printf("3");
break;
default:
printf("309");
break;
}
}
int main(int argc, char* argv[]){
Function(303);
return 0;
}
  • 反汇编
    在这里插入图片描述
    与if/else相同,下图为海哥教程图
    在这里插入图片描述

二、do/while反汇编

1、do/while的语法

do
{//执行代码
}while(表达式)

2、do/while的反汇编

在这里插入图片描述

3、example

在这里插入图片描述

4、总结

  1. 根据条件跳转指令所跳转到的地址,可以得到循环语句块的起始地址。
  2. 根据条件跳转指令所在的地址,可以得到循环语句块的结束地址。
  3. 条件跳转的逻辑与源码相同。

三、while反汇编

1、while语句的语法

while(表达式)        
{//执行代码
}

2、while语句反汇编

在这里插入图片描述

3、example

在这里插入图片描述

4、总结

  1. 根据条件跳转指令所跳转到的地址,可以得到循环语句块的结束地址;
  2. 根据jmp 指令所跳转到的地址,可以得到循环语句块的起始地址;
  3. 在还原while 比较时,条件跳转的逻辑与源码相反。

四、for循环反汇编

1、for语句的语法

for(表达式1;表达式2;表达式3)
{
//执行的代码
}

2、for循环的执行次序

表达式1
表达式2
执行的代码(大括号里面的内容)
表达式3

表达式2 //如果表达式2成立
执行的代码(大括号里面的内容)
表达式3

表达式2 //如果表达式2成立
执行的代码(大括号里面的内容)
表达式3

表达式2 //如果不成立
跳出循环

3、example

在这里插入图片描述

4、总结

  1. 第一个jmp 指令之前为赋初值部分
  2. 第一个jmp 指令所跳转的地址为循环条件判定部分起始
  3. 判断条件后面的跳转指令条件成立时跳转的循环体外面
  4. 条件判断跳转指令所指向的地址上面有一个jmp jmp地址为表达式3的起始位置

五、作业

1、写一个Switch语句,不生产大表也不生产小表,贴出对应反汇编

void Function(int x)
{
switch(x)
{
case 1:printf("1");break;
case 2:printf("2");break;
case 3:printf("3");break;
default:printf("Error");break;
}
}int main(int argc, char* argv[]){Function(2);return 0;
}

在这里插入图片描述

2、写一个Switch语句,只生成大表,贴出对应反汇编

void Function(int x)
{
switch(x)
{
case 1:printf("1");break;
case 2:printf("2");break;
case 3:printf("3");break;
case 4:printf("4");break;
case 5:printf("5");break;
case 6:printf("6");break;
default:printf("Error");break;
}
}int main(int argc, char* argv[]){
Function(5);return 0;
}

在这里插入图片描述

3、写一个Switch语句,生成大表和小表,贴出对应反汇编

void Function(int x)
{
switch(x)
{
case 100:printf("100");break;
case 101:printf("101");break;
case 110:printf("110");break;
case 3:printf("3");break;
case 1:printf("1");break;
default:printf("Error");break;
}
}
int main(int argc, char* argv[]){Function(101);return 0;
}

我的是if/else结构,博客站中是大小表结构。

4、为do/while语句生成的反汇编填写注释

void Function(int i)
{do{printf("%d\n", i);i++;} while (i>3);}
int main(int argc, char* argv[]){Function(0);return 0;
}

在这里插入图片描述

5、为while语句生成的反汇编填写注释

void Function(int i)
{while (i<3){printf("%d\n", i);i++;}}
int main(int argc, char* argv[]){Function(0);return 0;
}

在这里插入图片描述

6、为for语句生成的反汇编填写注释

void Function(int x)
{for (int i = 0; i < x; i++){printf("%d\n", i);}
}
int main(int argc, char* argv[]){Function(5);return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/652498.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深兰科技入选亿欧《“制”敬不凡先锋榜·智能机器人Top10》榜单

日前&#xff0c;由亿欧协办的2023工博会工业智能化发展高峰论坛于上海成功举办&#xff0c;会上发布了《2023智能制造&#xff1a;“制”敬不凡先锋者》系列名单。深兰科技凭借在智能机器人开发中的技术创新和模式应用&#xff0c;入选《“制”敬不凡先锋榜——智能机器人Top1…

前端大厂面试题探索编辑部——第二期

目录 题目 单选题1 题解 关于TCP 关于UDP 单选题2 题解 A选项的HTTP是否是无状态协议 B选项的HTTP支持的方法 C选项的关于HTTP的状态码 D选项HTTP协议的传输格式 题目 单选题1 1.以下哪个描述是关于 TCP 和 UDP 的区别&#xff08;&#xff09; A. TCP 是无连接的…

行测-资料:3. 比重、平均数

1、比重 1.1 现期比重★★★ C A&#xff0c;16.63%≈1/6 B C&#xff0c;拆成 50% 和 6.6% ≈ 1/15。 C D 1.2 基期比重★ 数学推导&#xff0c;A&#xff0c;B&#xff0c;A/(1 a)&#xff0c;B / (1 b) A&#xff0c;4 / 9&#xff0c;12 / 27 x 1.14 / 1.18&#xff0c;看…

【大数据】Flink 架构(四):状态管理

Flink 架构&#xff08;四&#xff09;&#xff1a;状态管理 1.算子状态2.键值分区状态3.状态后端4.有状态算子的扩缩容4.1 带有键值分区状态的算子4.2 带有算子列表状态的算子4.3 带有算子联合列表状态的算子4.4 带有算子广播状态的算子 在前面的博客中我们指出&#xff0c;大…

WinRAR压缩包高级技巧:永久设置压缩包单个或批量单独压缩成包并且不内嵌文件夹,解压保留原始时间设置

目录点击跳转&#xff1a;WinRAR压缩包高级技巧&#xff1a;永久设置压缩包单个或批量单独压缩成包并且不内嵌文件夹&#xff0c;解压保留原始时间设置 解压永久设置1 解压保存原始时间 压缩永久设置1 默认压缩成zip手机电脑都通用的格式2 默认压缩文件不多额外嵌套一层文件夹&…

【新书推荐】3.1节 布尔运算

本节内容&#xff1a;布尔运算&#xff0c;又称为逻辑运算或位运算。 ■布尔代数&#xff1a;and与、or或、not非、xor异或&#xff0c;按位运算。 3.1.1 布尔代数 ■布尔代数与二进制的关系 乔治布尔是一位英国小学数学老师&#xff0c;19世纪最重要的数学家之一。出版了《…

《HTML 简易速速上手小册》第2章:HTML 的标签和元素(2024 最新版)

文章目录 2.1 文本格式化标签&#xff08;&#x1f3a9;✨&#x1f4dc; 网页的“时尚搭配师”&#xff09;2.1.1 基础示例&#xff1a;一篇博客的格式化2.1.2 案例扩展一&#xff1a;产品介绍页面2.1.3 案例扩展二&#xff1a;个人简历 2.2 链接和锚点&#xff08;&#x1f6a…

matplotlib实现动画效果

实现正弦波动画 import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation import numpy as np# 创建图像和轴 fig, ax plt.subplots()# 生成平均分布在0~2*pi之间的100个坐标点 x_data np.linspace(0, 2 * np.pi, 100) # 画出初始图 line, ax.plo…

【漏洞复现】中移铁通禹路由器信息泄露漏洞

Nx01 产品简介 中移禹路由器支持宽带拨号、动态IP和静态IP三种上网模式,一般中国移动宽带的光猫都是智能光猫也就是光猫带路由器功能,中移禹路由器作为二级路由使用。 Nx02 漏洞描述 中移禹路由器ExportSettings处存在信息泄露漏洞&#xff0c;攻击者可以获取后台权限。 Nx03…

sqli.labs靶场(8-17关)

8、第八关&#xff08;布尔盲注&#xff09; id1显示You are in...........&#xff0c;id1单引号不显示&#xff0c;id1 --显示正常 这个应该是单引号闭合&#xff0c;接下来就和第七关差不多上脚本 爆库名长度&#xff1a;id1%27%20and%20length(database()){i}%20-- 爆库…

算法分析(概论)

目录 第一章 概论 1.算法的概念 1.定义 2.算法设计要求 3.算法的特性 4.算法描述 5.数据结构与算法 6.算法设计的基本步骤 2.算法分析 1.计算机资源 2.算法分析 3.评判算法效率的方法 4.算法时间复杂度分析 5.渐进符号 1.大Ο符号 2.大Ω符号 3.大Θ符号 4.三…

bert预训练模型下载

查看 bert 模型所支持的预训练模型有哪些 from transformers import BERT_PRETRAINED_MODEL_ARCHIVE_LIST print(BERT_PRETRAINED_MODEL_ARCHIVE_LIST) 运行结果会吧所有支持的模型打印出来&#xff0c;比如 bert-base-chinese 一般下载模型我们搜索到的都是去 https://hugg…

详解顺序结构双指针处理算法

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

MySQL中使用percona-xtrabackup工具 三种备份及恢复 (超详细教程)

CSDN 成就一亿技术人&#xff01; 今天讲讲再MySQL中使用percona-xtrabackup这个开源工具来实现在线备份。 CSDN 成就一亿技术人&#xff01; 目录 介绍percona-xtrabackup 安装Percona 完整备份 备份流程 恢复流程 1.模拟文件损坏 2.滚回日志 3.恢复数据目录 4.授权…

可解释性人工智能(XAI)概述

文章目录 每日一句正能量前言可解释性人工智能&#xff08;XAI&#xff09;定义研究的作用应用领域XAI的目标后记 每日一句正能量 一个人若想拥有聪明才智&#xff0c;便需要不断地学习积累。 前言 人工智能&#xff08;AI&#xff09;的发展速度迅猛&#xff0c;并在许多领域…

【JavaScript】ECMA6Script es6

文章目录 一、 es6的介绍二、 es6的变量和模板字符串2.1 let 与 var2.2 const 与 var2.3 模板字符串 三、 es6的解构表达式四、 es6的箭头函数4.1 声明和特点4.2 实践和应用场景4.3 rest和spread 五、es6的对象创建和拷贝5.1 对象创建的语法糖5.2 对象的深拷贝和浅拷贝 六、es6…

Qt扩展-QXlsx读写Excel配置使用

QXlsx读写Excel配置使用 一、概述1. 功能概述2. 其他维护 二、安装1. 下载源码2. 配置项目3. 测试代码4. 运行结果 一、概述 项目介绍&#xff1a;https://qtexcel.github.io/QXlsx/Example.html GitHub&#xff1a;https://github.com/QtExcel/QXlsx/tree/master QXlsx 是一个…

2024年最适合开Palworld的游戏服务器

如果要开Palworld服务器&#xff0c;当然要选大内存的服务器 在雨云&#xff0c;你不仅可以 链接&#xff1a;雨云 - 新一代云服务提供商欢迎来到以用户体验为优先的雨云&#xff0c;我们提供稳定高速的国际虚拟主机&#xff0c;云服务器产品&#xff0c;强大的功能&#xff…

WindowsOS

C:. ├─PerfLogs&#xff0c;系统日志文件夹 ├─Program Files&#xff0c;程序文件 ├─Program Files&#xff08;x86&#xff09;&#xff0c;程序文件&#xff08;x86&#xff09; ├─ProgramData&#xff0c;程序数据 ├─Windows&#xff0c;Windows系统文件夹 └─Us…

数据结构排序小结

排序类型小结 &#x1f4a6; 插入排序直接插入排序希尔排序 &#x1f4a6; 选择排序直接选择排序堆排序 &#x1f4a6; 交换排序冒泡排序快速排序&#x1f43e;霍尔版本补坑位版本前后指针版本非递归版本 &#x1f4a6; 归并排序递归版本非递归版本 &#x1f4a6; 性能测试 &am…