当前位置: 首页 > news >正文

滴水逆向三期笔记与作业——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;
}

在这里插入图片描述

相关文章:

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

滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编 一、Switch语句1、switch语句 是if语句的简写2、break加与不加有什么特点?default语句可以省略吗&#xff1f;3、游戏中的switch语句&#xff08;示例&#xff09;4、添加case后面的值&#xff0c;一个一个增加&…...

燃烧的指针(三)

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;c语言从基础到进阶 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于c语言的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到小田代码世界~ &#x…...

微服务架构实施攻略:如何选择合适的微服务通信机制?

随着业务的快速发展和系统的日益复杂&#xff0c;传统的单体应用逐渐显露出瓶颈&#xff0c;已无法满足现代软件研发的需求。微服务架构作为一种灵活、可扩展的解决方案&#xff0c;通过将复杂系统拆分为一系列小型服务来提高系统的可伸缩性、灵活性和可维护性。在实施微服务架…...

【jetson笔记】解决vscode远程调试qt.qpa.xcb: could not connect to display报错

配置x11转发 jetson远程安装x11转发 安装Xming Xming下载 安装完成后打开安装目录C:\Program Files (x86)\Xming 用记事本打开X0.hosts文件&#xff0c;添加jetson IP地址 后续IP改变需要重新修改配置文件 localhost 192.168.107.57打开Xlaunch Win菜单搜索Xlaundch打开 一…...

网络安全产品之认识安全隔离网闸

文章目录 一、什么是安全隔离网闸二、安全隔离网闸的主要功能三、安全隔离网闸的工作原理四、安全隔离网闸的分类五、安全隔离网闸与防火墙的区别四、安全隔离网闸的应用场景 随着互联网的发展&#xff0c;网络攻击和病毒传播的方式越来越复杂&#xff0c;对网络安全的要求也越…...

Java通过模板替换实现excel的传参填写

以模板为例子 将上面$转义的内容替换即可 package com.gxuwz.zjh.util;import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*; import java.util.HashMap; import java.util.Map; import java.io.IOException; impor…...

眼底增强型疾病感知蒸馏模型 FDDM:无需配对,fundus 指导 OCT 分类

眼底增强型疾病感知蒸馏模型 FDDM&#xff1a;fundus 指导 OCT 分类 核心思想设计思路训练和推理 效果总结子问题: 疾病特定特征的提取与蒸馏子问题: 类间关系的理解与建模 核心思想 论文&#xff1a;https://arxiv.org/pdf/2308.00291.pdf 代码&#xff1a;https://github.c…...

代码随想录算法刷题训练营day17

代码随想录算法刷题训练营day17&#xff1a;LeetCode(110)平衡二叉树 LeetCode(110)平衡二叉树 题目 代码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(…...

Java集合如何选择

为什么使用集合 当需要存储一组类型相同的数据时&#xff0c;数组是最常用且最基本的容器之一。但是&#xff0c;使用数组存储对象存在一些不足之处&#xff0c;因为在实际开发中&#xff0c;存储的数据类型多种多样且数量不确定。这时&#xff0c;Java 集合就派上用场了。与数…...

简单介绍----微服务和Spring Cloud

微服务和SpringCloud 1.什么是微服务&#xff1f; 微服务是将一个大型的、单一的应用程序拆分成多个小型服务&#xff0c;每个服务负责实现特定的业务功能&#xff0c;并且可以通过网络通信与其他服务通信。微服务的优点是开发更灵活&#xff08;不同的微服务可以使用不同的开…...

Jenkins邮件推送配置

目录 涉及Jenkins插件&#xff1a; 邮箱配置 什么是授权码 在第三方客户端/服务怎么设置 IMAP/SMTP 设置方法 POP3/SMTP 设置方法 获取授权码&#xff1a; Jenkins配置 从Jenkins主面板System configuration>System进入邮箱配置 在Email Extension Plugin 邮箱插件…...

硬件知识(1) 手机的长焦镜头

#灵感# 手机总是配备好几个镜头&#xff0c;研究一下 目录 手机常配备的摄像头&#xff0c;及效果举例 长焦的焦距 焦距的定义和示图&#xff1a; IPC的焦距和适用场景&#xff1a; 手机常配备的摄像头&#xff0c;及效果举例 以下是小米某个手机的摄像头介绍&#xff1a…...

华为机考入门python3--(3)牛客3-明明的随机数

分类&#xff1a;集合、排序 知识点&#xff1a; 集合添加元素 set.add(element) 集合转列表 list(set) 列表排序 list.sort() 题目来自【牛客】 N int(input().strip()) nums set()for i in range(N):nums.add(int(input().strip()))# 集合转列表 nums_list l…...

vue父子组件传值问题

在Vue中&#xff0c;父子组件之间的数据传递可以通过props和事件来实现。 使用props传递数据&#xff1a;父组件可以通过props将数据传递给子组件&#xff0c;子组件可以在模板中直接使用这些数据。父组件可以通过v-bind指令将数据绑定到子组件的props上。例如&#xff1a; v…...

Rider 打开Unity项目 Project 全部显示 load failed

电脑自动更新&#xff0c;导致系统重启&#xff0c;第二天Rider打开Unity 工程&#xff0c;没有任何代码提示&#xff0c;字符串查找也失效。 现象&#xff1a; 1.所有的Project均显示laod failed。点击load failed。右侧信息显示Can not start process 2.选中解决方案进行Bui…...

Maven(下):依赖管理、依赖传递、依赖冲突、工程继承及工程聚合

1. 基于IDEA 进行Maven依赖管理 1.1 依赖管理概念 Maven 依赖管理是 Maven 软件中最重要的功能之一。Maven 的依赖管理能够帮助开发人员自动解决软件包依赖问题&#xff0c;使得开发人员能够轻松地将其他开发人员开发的模块或第三方框架集成到自己的应用程序或模块中&#xf…...

网络基础---初识网络

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、局域网…...

【Java】Java类动态替换Class

Java类动态替换Class 通过Java的Class对象&#xff0c;可以实现动态替换Class。 预习几个知识点 getClassLoader Java提供的ClassLoader可用于动态加载的Java类&#xff0c;可以通过多种形式获取ClassLoader。比如通过Class类获取 // 通过Class获取 ClassLoader classLoade…...

【驱动系列】C#获取电脑硬件显卡核心代号信息

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《驱动系列》文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点…...

AutoGen实战应用(二):多代理协作(Multi-Agent Collaboration)

AutoGen是微软推出的一个全新工具&#xff0c;它用来帮助开发者创建基于大语言模型(LLM)的复杂应用程序. AutoGen能让LLM在复杂工作流程启用多个角色代理来共同协作完成人类提出的任务。在我之前的一篇博客: AutoGen实战应用(一)&#xff1a;代码生成、执行和调试 中我们通过一…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...