ARM64汇编09 - 分支指令与模式切换

本文主要讨论两部分内容:

  • 分支指令,B、BL 等

  • v7中的模式切换,arm切thumb,thumb切arm。理解了模式切换就会明白为什么在做 inline hook 时,有些地址需要加上1,加上 1 的作用是什么。

B

B指令是无条件跳转指令。看描述是一个相对于PC地址的跳转,范围是使用 imm26 来描述。26 位表示的范围是 +/-128M。为啥会是 128M 呢?是因为最后的值还需要乘以4。

举个例子:

在 000000000001EDA4 处有一条 B 指令,执行完该指令之后就会直接跳转到 000000000001EDAC 处,IDA使用一条带箭头的线给出了提示。

之前在学习 so 的时候,写过一个死循环指令:

00 00 00 14

我们可以分析一下其具体的每一位:

00010100 00000000 00000000 00000000 ->
0 00101 00000000000000000000000000

因为是跳转到自己位置,所以 imm26 是 0,很好理解。

对比了一下 v7 与 v8 中的死循环指令,发现一个未曾注意到的区别:

v8: 00 00 00 14
v7: fe ff ff ea

在 v7 中,feffff 表示的是 -2,由于 pc = pc + 8,所以算下来,offset = 8 + (-2)* 4 = 0。

但是在 v8 中,offset 就直接是 imm26 的值,这是否说明在 v8 中,pc就是自身的值?暂时未找到具体文档,先留个疑问。

在 V7 中,存在 arm 与 thumb 指令,那么 B 指令跳转会发生模式切换吗?是不会的,编译器可以保证,除非你修改了指令代码,如果在 B 指令中发生了模式切换,肯定是会出问题的,因为 T 位没有发生变化,执行 B 指令的跳转后,CPU 仍会将跳转后的模式当成跳转前的模式来处理。所以,如果你修改了指令代码,切记保证跳转前后的模式一致。

BL

BL指令与B指令几乎一样,唯一的区别就是它跳转的时候会将下一条指令(PC+4,这里也说明了PC的值就是所见即所得)的地址写入到LR寄存器。这条指令表示调用了一个函数。

看V8中的一个例子:

按下 F7:

可以看到发生了两件事:

  • 指令跳转到了目标地址去执行

  • X30 寄存器的值被修改成了BL指令的下一条指令地址,但是这个说法并不准确,因为在 v7 中表现稍微有点不一样。在 arm 模式中,储存的是BL指令的下一条指令地址,在 thumb 模式中,储存的的是下一条指令的地址+1,这个1 是 t 标志位的值。

按下 F7:

看到,LR 寄存器的值变成了 0xB708160F ,这是一个奇数,指令的地址不可能是一个奇数。它的值是 B708160E 的值加上1,这个1表示当从函数跳转回来继续执行的时候,需要以 thumb 模式来执行。

BX

在 v8  中,没有BX指令了,猜测因为BX指令相比B和BL指令的不同之处在于它可以描述模式切换,但是v8中没有模式切换了,所以BX指令就没必要了。

BX后面只能跟寄存器。

.text:000005C8 10 FF 2F E1                   BX              R0

这里有一个BX指令,它跳转到 R0 指向的地址,一般情况下,R0是直接储存的目标地址,这个时候,表示模式不会切换。当它储存的地址是目标地址+1的时候,就会发生模式切换。

BLX

这个也是带模式切换的,v8中也没了。

BLX后可以跟寄存器或者立即数。当 BLX 后面跟的是立即数是,一定会发生模式切换。

比如:

BLX sub_B^EBA934

如果当前是arm模式,执行后变成 thumb 模式,如果当前是 thumb 模式,执行后变成 arm 模式。

BLX 与 BL 一样,也会写 LR 寄存器的值,写入的值规则也是一样,下一条指令地址 + t 标志位的值。

BLX 后面跟寄存器的时候,不一定会发生模式切换。如果想带模式切换,需要将寄存器的值+1,这个时候就会进行从 arm 到 thumb 模式的切换。如果本身就处于 thumb 模式,那么寄存器的值就不需要+1,因为寄存器最后一位的值会直接写入到t标志位。当处于 thumb 模式时,寄存器最后一位是0,就会进行从 thumb 到 arm 模式的切换。

总结一下:BX 与 BLX 指令会有模式切换,当指令跟着寄存器的时候,寄存器的最后一位的值会影响模式的切换,最后一位是 0 ,表示需要切换到 arm 模式,最后一位是 1,表示需要切换到 thumb 模式。当前模式与需要切换的模式不一致时,就会发生模式切换。

V7导出函数的arm与thumb模式

有一个问题:就是libc.so中有许多的导出函数,有些函数可能是以arm模式运行,有些函数可能是要以thumb模式运行,那么当我们使用这些函数的时候,程序是如何知道该函数要以何种模式运行的呢?

我们先看看 IDA 中的导出表的 printf 这个函数:

printf	000528A4

可以看到它的地址是一个偶数。

我们再使用 readelf 程序看看这个符号的信息:

6115: 000528a5    84 FUNC    GLOBAL DEFAULT   13 printf

发现,这个地址是一个奇数,这说明了,跳转到 printf 函数需要切换成 thumb 模式来执行。

IDA中展示的是函数的真实地址,但是没有带模式,readelf 显示的信息中带上了模式信息。

MOV PC, reg

我们上面讨论 BX 指令的时候,BX会直接跳转到目标地址,相当于是改写了 pc 寄存器的值,所以有些人就觉得mov pc, reg 与 BX 指令就是相等的。但是显然不是,因为 mov 不具有切换模式功能。就算想使用 mov 模拟 BX 来进行模式切换,比如 mov pc, target_addr + 1,这个指令只会出异常,而不会切换模式。因为奇数地址是非法的。BX指令实际上是将最后一位给了 t 标志位,而不是真的跳转到一个奇数地址。总之,不要使用 mov 指令来修改 PC 寄存器。

LDR PC, [reg]

这个指令就不同与MOV指令了,它是支持模式切换的,与 BX 指令一样,实际上我们看一下IDA的反汇编代码,会发现plt的调用就是使用的 LDR 指令:

.plt:00000540                               ; int getchar(void)
.plt:00000540                               getchar                                 ; CODE XREF: main:loc_604↓p
.plt:00000540 00 C6 8F E2                   ADR             R12, 0x548
.plt:00000544 01 CA 8C E2                   ADD             R12, R12, #0x1000
.plt:00000548 AC FA BC E5                   LDR             PC, [R12,#(getchar_ptr - 0x1548)]! ; __imp_getchar

这里调用 getchar 函数的时候,就是使用了 LDR 指令,赋值个 PC 的地址有可能是奇数,也有可能是偶数,为奇数表示需要切成 thumb 模式来执行。

再看一个例子:

.text:0000068E D0 B5                         PUSH            {R4,R6,R7,LR}
.text:00000690 02 AF                         ADD             R7, SP, #8
.text:00000692 0C 46                         MOV             R4, info
.text:00000694                               info = R4                               ; unw_proc_info_t_0 *
.text:00000694                               co = R0                                 ; libunwind::AbstractUnwindCursor *
.text:00000694 01 68                         LDR             R1, [co]
.text:00000696 4A 6A                         LDR             R2, [R1,#0x24]
.text:00000698 21 46                         MOV             R1, info
.text:0000069A 90 47                         BLX             R2
.text:0000069A
.text:0000069C 61 68                         LDR             R1, [info,#4]
.text:0000069E 00 20                         MOVS            R0, #0
.text:000006A0 00 29                         CMP             R1, #0
.text:000006A2 04 BF                         ITT EQ
.text:000006A4 4E F2 6B 60                   MOVWEQ          R0, #0xE66B
.text:000006A8 CF F6 FF 70                   MOVTEQ          R0, #0xFFFF
.text:000006AC D0 BD                         POP             {info,R6,R7,PC}

这是一段程序,可以看到,首先将 LR 等寄存器储存起来,我们知道,LR 会由 BX 修改,它的值可能是奇数也可能是偶数。再看最后一条指令,将储存起来的 LR 的值,赋值给了 PC,这就相当于是使用了 LDR 指令了。这个时候,PC 的值就可能是奇数,会发生模式切换。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux phpstudy 重启命令

[rootLinuxWeb phpstudy]# ./system/phpstudyctl restart 查看命令 1) phpstudy -start 启动小皮面板 2) phpstudy -stop 停止小皮面板 3) phpstudy -restart 重启小皮面板 4) phpstudy -status 查询面板状态 5) phpstudy -in…

中北大学软件学院javaweb实验三JSP+JDBC综合实训(一)__数据库记录的增加、查询

目录 1.实验名称2.实验目的3.实验内容4.实验原理或流程图5.实验过程或源代码(一)编程实现用户的登录与注册功能【步骤1】建立数据库db_news2024和用户表(笔者使用的数据库软件是navicat)【步骤2】实现用户注册登录功能(与上一实验报告不同的是&#xff0…

windows下redis配置为服务自启动

1. 准备安装包 2. 解压该zip到文件夹 3. 配置环境变量 4. 配置自启动 4.1 检查redis.windows.conf和 redis.windows-service.conf 文件,将bind注释掉 4.2 [cmd]窗口运行redis 输入 redis-server.exe 或者 redis-server.exe redis.windows.conf 4.3 验证redis是否…

外卖订餐总后台系统原型

页面数量:共 210 页 源文件格式:rp格式,兼容 Axure RP 9/10 应用领域:O2O领域、网上订餐、外卖行业 文章展示不够全面,如有兴趣请联系作者 该原型作品为外卖订餐总后台管理系统,定位偏向美团外卖与饿了么一…

力扣HOT100 - 45. 跳跃游戏 II

解题思路&#xff1a; 贪心 class Solution {public int jump(int[] nums) {int end 0;int maxPosition 0;int steps 0;for (int i 0; i < nums.length - 1; i) {maxPosition Math.max(maxPosition, i nums[i]);if (i end) {end maxPosition;steps;}}return steps;…

[FlareOn1]Bob Doge

[FlareOn1]Bob Doge Hint:本题解出相应字符串后请用flag{}包裹&#xff0c;形如&#xff1a;flag{123456flare-on.com} 得到的 flag 请包上 flag{} 提交。 密码&#xff1a;malware 没什么思路&#xff0c;原exe文件运行又install了一个challenge1.exe文件 c#写的&#xff…

MySQL————创建存储过程函数 有参数传递

存储过程使用大纲 有参数传递 delimiter $$ 声明一个名称为get_student_introduce CREATE PROCEDURE gei_student_introduce(in p_name VARCHAR(20)) 开始操作 BEGIN 撰写真正在操作DMLDQL都行 select introduce 简介 from student WHERE userNamep_name; end $$ delimite…

地下车库导航地图怎么做?停车场地图绘制软件哪个好?

上海懒图科技以先进技术和丰富的行业服务经验为用户提供停车场景下的全流程服务平台&#xff0c;用户基于平台可自主快速绘制酷炫的停车场地图&#xff0c;通过提供完善的停车场应用功能集和扩展API服务包&#xff0c;可以方便地实现电子地图服务于您的各类停车场应用中&#x…

CRMEB开源打通版/标准版v4电商商城系统小程序发布之后无法生成海报问题

小程序产品分销二维码生成不了 开发者工具可以生成海报&#xff0c;但是发布之后无法生成 1.在开发者工具中&#xff0c;将不校验合法域名关闭 2.点击生成海报&#xff0c;查看console3.将域名填写到微信公众平台小程序的download合法域名中 网址微信公众平台

用vue实现json模版编辑器

用vue实现json模版编辑器 控件区表单区配置项区 &#xff08;还没写&#xff09;业务逻辑 设想业务逻辑是拖拽控件生成表单 动手做了一个简单的demo 业务的原型图设想如下所示 其中使用的技术主要是vuedragger 控件区 做控件区的时候首先我们要有确定的配置项 其实也很简单 …

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第21课-购买烟花插件

【WEB前端2024】开源智体世界&#xff1a;乔布斯3D纪念馆-第21课-购买烟花插件 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎…

【antd + vue】Failed to resolve component: a-select-option

一、问题说明 1、出现情况&#xff1a; <a-select>嵌套<a-select-option>&#xff0c;其中<a-select-option>循环&#xff0c;能正常使用&#xff0c;但是控制台警告。 2、控制台警告&#xff1a; [Vue warn]: Failed to resolve component: a-select-op…

HTML满屏漂浮爱心

目录 写在前面 满屏爱心 代码分析 系列推荐 写在最后 写在前面 小编给大家准备了满屏漂浮爱心代码&#xff0c;一起来看看吧~ 满屏爱心 文件heart.svg <svg xmlns"http://www.w3.org/2000/svg" width"473.8px" height"408.6px" view…

AI与边缘设备,光子芯片,AI规划能力,自然语言驱动的AI游戏

1 Archetype AI 发布了一个创新的人工智能平台 —— Newton 这是一个专门为理解物理世界设计的基础模型。 Newton 设计用于连接实时物理数据&#xff0c;其数据源是全球数十亿传感器的输入&#xff0c;实现了对物理现实的直接解读。 利用从各种传感器&#xff08;如加速度计…

【声呐仿真】学习记录3-待续

【声呐仿真】学习记录3-后续 第五阶段-获取数据1.运行赫尔库勒斯沉船的世界&#xff1a;2.键盘操纵rov至合适的位置&#xff0c;调整Image topic&#xff0c;查看输出图像3.RVIZ SONAR 图像查看器插件&#xff08;没有对应的topic&#xff09;4.点云5.录制rosbag 第六阶段-查看…

VUE如何实现批量下载多个文件并导出zip格式

效果图 1、安装jszip和file-saver插件 npm install jszip npm install file-saver2、在所需页面引入 import JSZip from "jszip"; import FileSaver from "file-saver";3、模拟fileList数组 //fileList模拟文件数组export default {name: "notic…

揭秘四川古力未来科技抖音小店:创新优势引领电商新风潮

在当下这个数字化、网络化的时代&#xff0c;电商行业正以前所未有的速度迅猛发展&#xff0c;而抖音小店作为其中的佼佼者&#xff0c;凭借其独特的平台优势和创新的经营模式&#xff0c;吸引了越来越多的消费者和商家。其中&#xff0c;四川古力未来科技抖音小店凭借其显著的…

【无标题】ubuntu环境手把手配置mmdetection

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 ubuntu环境手把手配置mmdetection 前言一、环境安装配置1.安装conda环境2.安装pytorch3.安装 MMEngine 和 MMCV4.安装mmdet 二、测试环境1.我们需要下载配置文件和模型权重文…

vue2中npm i报错gyp info it worked if it ends with ok

当我拿到一个老的vue2项目&#xff0c;怎么也起不起来&#xff0c;后来找到报错原因&#xff0c;如上图所示&#xff0c;可以看到报错的path是node-sass&#xff0c;那么就猜想应该是sass版本和node版本不匹配。 于是我查看了我的node版本是16 而sass版本是下图所示&#xff0c…

centos7.8 迁移为 TencentOS Server 2.4(TK4) 报错解决

文章目录 一 问题二 解决三 注意 一 问题 CentOS 官方计划停止维护 CentOS Linux 项目&#xff0c;公司某台腾讯云的centos7.8服务器计划迁移为 TencentOS Server 2.4(TK4) 。在下载rpm包执行迁移命令后报错&#xff0c;场景还原如下。 首先 安装 Python 3 yum install -y p…