ARM64汇编01 - 环境搭建

arm官方手册

由于市面上几乎没有arm相关书籍,所以推荐看官方文档。虽然是英文的,看不下去也要硬看,毕竟搞这方面的还是得有啃英文文档/书籍的能力。

另外,再推荐一个翻译网站:https://www.deepl.com/zh/translator

arm 手册下载地址:

https://developer.arm.com/documentation/ddi0487/latest

https://developer.arm.com/documentation/ddi0602/2023-12/?lang=en

开发环境

使用 kali + vscode + ndk-build。

ndk-build 可以使用 android studio 下载。

开发目录结构:

ARM64 |-- Android.mk|-- Application.mk|-- arm64.c|-- build.sh|-- push.sh|-- connect.sh

关于 Android.mk 与 Application.mk 的知识,可以参照官方文档:

https://developer.android.com/ndk/guides/build?hl=zh-cn

这里只简单介绍必要的。

Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)#LOCAL_ARM_MODE := armLOCAL_MODULE := arm64LOCAL_SRC_FILES := arm64.cinclude $(BUILD_EXECUTABLE)#include #(BUILD_SHARED_LIBRARY)
  • LOCAL_PATH:此变量用于指定当前文件的路径。必须在 Android.mk 文件开头定义此变量。

  • CLEAR_VARS:此变量用于清除LOCAL_PATH变量外的许多LOCAL_***变量(例如:LOCAL_MODULE、LOCAL_SRC_FILES等)。这是非常有必要的,因为所有的编译文件都在同一个GUN MKAE执行环境中,所有的变量都是全局变量,不清除容易引起解析错误。

  • LOCAL_MODULE:此变量用于存储模块名称。指定的名称在所有模块名称中必须唯一,并且不得包含任何空格。

  • LOCAL_ARM_MODE:默认情况下,构建系统会以 thumb 模式生成 ARM 目标二进制文件,其中每条指令都是 16 位宽,并与 thumb/ 目录中的 STL 库链接。将此变量定义为 arm 会强制构建系统以 32 位 arm 模式生成模块的对象文件。

  • LOCAL_SRC_FILES:此变量包含构建系统生成模块时所用的源文件列表。

  • BUILD_EXECUTABLE:根据您列出的源文件构建目标可执行文件。

  • BUILD_SHARED_LIBRARY:根据您列出的源文件构建目标共享库。

Application.mk

APP_ABI := arm64-v8a
APP_BUILD_SCRIPT := Android.mk
APP_PLATFORM := android-26
  • APP_ABI:默认情况下,NDK 构建系统会为所有非弃用 ABI 生成代码。您可以使用 APP_ABI 设置为特定 ABI 生成代码。

    指令集
    32 位 ARMv7APP_ABI := armeabi-v7a
    64 位 ARMv8 (AArch64)APP_ABI := arm64-v8a
    x86APP_ABI := x86
    x86-64APP_ABI := x86_64
    所有支持的 ABI(默认)APP_ABI := all
  • APP_BUILD_SCRIPT:默认情况下,ndk-build 假定 Android.mk 文件位于项目根目录的相对路径 jni/Android.mk 中。如需从其他位置加载 Android.mk 文件,请将 APP_BUILD_SCRIPT 设置为 Android.mk 文件的绝对路径。

  • APP_PLATFORM:APP_PLATFORM 会声明构建此应用所面向的 Android API 级别,并对应于应用的 minSdkVersion。例如, android-16 说明无法运行在低于Android 4.1(API 级别 16)的设备上。

arm64.c

#include <stdio.h>int main()
{while (1){getchar();printf("hello\n");}return 0;
}

这里就是我们的测试代码,会将它编译成可执行文件,然后push到设备上去运行。我们可以使用 IDA 来观察汇编代码。

build.sh

export ANDROID_NDK=/root/Android/Sdk/ndk/21.4.7075529$ANDROID_NDK/ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk

ndk-build 脚本位于 NDK 安装目录顶层。所以我们定义一个变量表示其目录,然后直接使用即可。

  • NDK_APPLICATION_MK=<file> :使用 NDK_APPLICATION_MK 变量指向的特定 Application.mk 文件进行构建。

  • 如果Android.mkApplication.mk所在目录的名字不是jni,需要通过变量指定 :NDK_PROJECT_PATH=.

push.sh

adb connect 192.168.3.12:5555
adb push obj/local/arm64-v8a/arm64 /data/local/tmp/arm64
adb shell "chmod 777 /data/local/tmp/arm64"

将生成的可执行文件 push 到 设备的指定位置。

注意生成的可执行文件有两个:

├── libs
│   └── arm64-v8a
│       └── arm64
├── obj
│   └── local
│       └── arm64-v8a
│           ├── arm64
│           └── objs
│               └── arm64
│                   ├── arm64.o
│                   └── arm64.o.d

obj/local/arm64-v8a/arm64 这个可执行文件是带调试信息的。

libs/arm64-v8a/arm64 这个可执行文件是经过 strip 了的,不带符号与调试信息。

我们学习时使用带调试信息的即可。

connect.sh

adb connect 192.168.3.12:5555
#adb shell "/data/local/tmp/android_server64"

连接设备,打开 IDA 的 server。

然后我们在有 IDA 的主机上连接设备,转发端口,就可以进行调试了。

LOCAL_ARM_MODE

前面我们说了,这个选项是用来表明生成的目标文件里面,它的汇编代码是使用 arm 还是 thumb 指令。

我们测试一下 arm 的效果:

LOCAL_ARM_MODE := arm

其main函数汇编如下:

.text:0000000000000714                               ; =============== S U B R O U T I N E =======================================
.text:0000000000000714
.text:0000000000000714                               ; Attributes: noreturn bp-based frame
.text:0000000000000714
.text:0000000000000714                               ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:0000000000000714                               EXPORT main
.text:0000000000000714                               main                                    ; DATA XREF: LOAD:0000000000000438↑o
.text:0000000000000714                                                                       ; .got:main_ptr↓o
.text:0000000000000714
.text:0000000000000714                               var_10= -0x10
.text:0000000000000714                               var_s0=  0
.text:0000000000000714
.text:0000000000000714                               ; __unwind {
.text:0000000000000714 F3 0F 1E F8                   STR             X19, [SP,#-0x10+var_10]!
.text:0000000000000718 FD 7B 01 A9                   STP             X29, X30, [SP,#0x10+var_s0]
.text:000000000000071C FD 43 00 91                   ADD             X29, SP, #0x10
.text:0000000000000720 13 00 00 90 73 E2 1C 91       ADRL            X19, aHello             ; "hello"
.text:0000000000000720
.text:0000000000000728
.text:0000000000000728                               loc_728                                 ; CODE XREF: main+20↓j
.text:0000000000000728 C6 FF FF 97                   BL              .getchar
.text:0000000000000728
.text:000000000000072C E0 03 13 AA                   MOV             X0, X19                 ; s
.text:0000000000000730 CC FF FF 97                   BL              .puts
.text:0000000000000730
.text:0000000000000734 FD FF FF 17                   B               loc_728
.text:0000000000000734                               ; } // starts at 714
.text:0000000000000734
.text:0000000000000734                               ; End of function main
.text:0000000000000734
.text:0000000000000734                               ; .text ends
.text:0000000000000734

可以看到都是 4 个字节的指令,除了 ADRL ,查看文档发现并没有这个指令。网上搜索了一下,发现这是一个伪指令,最终会将其转换为两条加载指令。所以,算下来,main 函数体的指令其实都是4个指令的。

再测试一下 thumb 指令的效果:

LOCAL_ARM_MODE := thumb

发现,指令并没有变化,这是为啥呢?我们看下面这个表:

可以看到,thumb 指令只存在于 armeabi-v7a 里面。

现在的应用在googleplay与国内商店的推动下,都已采用了 arm64-v8a,所以我们可以不用太关心 thumb 指令了。

想要看一下 thumb 指令,我们在 Application.mk 里面设置一下:

APP_ABI := arm64-v8a armeabi-v7a

这样就可以生成两个可执行文件,使用 ida 打开 armeabi-v7a 下的文件,查看其 main 函数:

.text:000005FC                               ; =============== S U B R O U T I N E =======================================
.text:000005FC
.text:000005FC                               ; Attributes: noreturn bp-based frame
.text:000005FC
.text:000005FC                               ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:000005FC                               EXPORT main
.text:000005FC                               main                                    ; DATA XREF: .text:000005A8↑o
.text:000005FC                                                                       ; .got:main_ptr↓o
.text:000005FC                               ; __unwind {
.text:000005FC D0 B5                         PUSH            {R4,R6,R7,LR}
.text:000005FE 02 AF                         ADD             R7, SP, #8
.text:00000600 03 4C                         LDR             R4, =(aHello - 0x606)   ; "hello"
.text:00000602 7C 44                         ADD             R4, PC                  ; "hello"
.text:00000602
.text:00000604
.text:00000604                               loc_604                                 ; CODE XREF: main+12↓j
.text:00000604 FF F7 9C EF                   BLX             getchar
.text:00000604
.text:00000608 20 46                         MOV             R0, R4                  ; s
.text:0000060A FF F7 A0 EF                   BLX             puts
.text:0000060A
.text:0000060E F9 E7                         B               loc_604
.text:0000060E
.text:0000060E                               ; End of function main
.text:0000060E
.text:0000060E                               ; ---------------------------------------------------------------------------

非常明显的变长指令,毕竟 thumb 指令的出现就是为了减少指令的长度。

调试一下这个程序,可以从寄存器窗口观察到 T flag 的值是1:

有些情况下,如果程序加了壳,或者说搞了自解密,可能会导致 IDA 错误识别指令。本来是 thumb 却识别成了 arm,或者反过来将 arm 识别成了 thumb。这个时候就需要我们手动将指令模式改过来。

在对应汇编位置,我们按 ALT + G 快捷键即可更改指令编码格式:

将 T 的值改成 1 就是 thumb 格式,改成 0 就是 arm 格式。

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

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

相关文章

架设一台NFS服务器,并按照以下要求配置

1、开放/nfs/shared目录&#xff0c;供所有用户查询资料 2、开放/nfs/upload目录&#xff0c;为192.168.xxx.0/24网段主机可以上传目录&#xff0c; 并将所有用户及所属的组映射为nfs-upload,其UID和GID均为210 3、将/home/tom目录仅共享给192.168.xxx.xxx这台主机&#xff0c;…

LightDB - oracle_fdw 过滤条件下推增强【24.1】

LightDB - oracle_fdw 过滤条件下推增强【24.1】 1. 字符串比较下推1.1 示例 2. 隐式转换下推2.1 示例 3. nvl 和trim 下推3.1 示例 LightDB 在24.1版本对oracle_fdw 的where下推进行了增强&#xff0c;新增对如下两种情况进行下推&#xff1a; 字符串比较下推&#xff0c;如 …

1-RuoYi-Vue环境部署

1.准备工作 JDK > 1.8 (推荐1.8版本) Mysql > 5.7.0 (推荐5.7版本) Redis > 3.0 Maven > 3.0 Node > 12提示 前端安装完node后&#xff0c;最好设置下淘宝的镜像源&#xff0c;不建议使用cnpm&#xff08;可能会出现奇怪的问题&#xff09; 2.运行系统 前往…

Spring集成MyBatis与MyBatis-Plus添加分页插件

项目场景&#xff1a; MyBatis使用分页插件PageHelperMyBatis-Plus3.4.0版本之前添加分页插件&#xff0c;使用配置PaginationInterceptor&#xff1b;MyBatis-Plus3.4.0版本添加分页插件&#xff0c;使用配置MybatisPlusInterceptor&#xff1b; 配置示例&#xff1a; 1、My…

大模型微调学习记录-基于GLM-130B

0. 前序背景 论文&#xff1a;GLM-130B: AN OPEN BILINGUAL PRE-TRAINED MODEL GLM2的微调教程 目前GLM2-130B优于或相当GPT-3-175B的性能。 选择130B&#xff08;1300亿参数&#xff09;是从硬件性能考虑&#xff0c;可以在单张A100&#xff08;40Gx8&#xff09;上进行推理…

openssl3.2 - 官方demo学习 - mac - poly1305.c

文章目录 openssl3.2 - 官方demo学习 - mac - poly1305.c概述笔记END openssl3.2 - 官方demo学习 - mac - poly1305.c 概述 MAC算法为Poly1305, 加密算法为AES-128-ECB, 用key初始化加密算法 加密算法进行padding填充 对加密算法的key加密, 放入MAC_key后16字节, 将MAC_key的…

jvm -Djava.library.path 无法打开共享对象文件:

项目代码修改 java -jar -Xms1024m -Xmx1024m -Dloader.path/data/encrypt/lib -Djava.library.path/data/encrypt/libVtExtAPI.so server-1.0.0-SNAPSHOT.jar 重新启动

C#设计模式教程(1):简单工厂模式

在C#中,工厂模式可以分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。 简单工厂模式(Simple Factory Pattern): 简单工厂模式并不属于23种经典设计模式之一,但它是工厂模式的一种简单形式。在简单工厂模式中,有一个工厂类负责根据传入的参数决定创建哪种产…

bevy the book 20140118翻译(全)

源自&#xff1a;Bevy Book: Introduction 主要用 有道 翻译。 Introduction 介绍 Getting Started 开始 Setup 设置 Apps 应用程序 ECS Plugins 插件 Resources 资源 Next Steps 下一个步骤 Contributing 贡献 Code 代码 Docs 文档 Building Bevys Ecosystem 构建 b…

VScode远程开发

VScode远程开发 在SSH远程连接一文中&#xff0c;我么介绍了如何使用ssh远程连接Jetson nano端&#xff0c;但是也存在诸多不便&#xff0c;比如:编辑文件内容时&#xff0c;需要使用vi编辑器&#xff0c;且在一个终端内&#xff0c;无法同时编辑多个文件。本节将介绍一较为实用…

基于ORB算法的图像匹配

基础理论 2006年Rosten和Drummond提出一种使用决策树学习方法加速的角点检测算法&#xff0c;即FAST算法&#xff0c;该算法认为若某点像素值与其周围某邻域内一定数量的点的像素值相差较大&#xff0c;则该像素可能是角点。 其计算步骤如下&#xff1a; 1&#xff09;基于F…

VMware Workstation Pro虚拟机搭建

下载链接&#xff1a;Download VMware Workstation Pro 点击上方下载&#xff0c;安装过程很简单&#xff0c;我再图片里面说明 等待安装中。。。。。是不是再考虑怎样激活&#xff0c;我都给你想好了&#xff0c;在下面这个链接&#xff0c;点赞收藏拿走不谢。 https://downl…

Jupyter-Notebook无法创建ipynb文件

文章目录 概述排查问题恢复方法参考资料 概述 用户反馈在 Notebook 上无法创建 ipynb 文件&#xff0c;并且会返回以下的错误。 报错的信息是: Unexpected error while saving file: Untitled5.ipynb attempt to write a readonly database 排查问题 这个是一个比较新的问…

lodash 的 _.groupBy 函数是怎么实现的?

说在前面 &#x1f388;lodash的_.groupBy函数可以将一个数组按照给定的函数分组&#xff0c;返回一个新对象。该函数接收两个参数&#xff1a;第一个参数是要进行分组的数组&#xff0c;第二个参数是用于分组的函数。该函数会对数组中的每个元素进行处理&#xff0c;返回一个值…

物联网孢子捕捉分析仪在农田起到什么作用

TH-BZ03随着科技的飞速发展&#xff0c;物联网技术在农业领域的应用越来越广泛。其中&#xff0c;物联网孢子捕捉分析仪作为一种先进的设备&#xff0c;在农田中发挥着不可或缺的作用。本文将详细介绍物联网孢子捕捉分析仪在农田中的作用。 一、实时监测与预警 物联网孢子捕捉分…

【webrtc】GCC 7: call模块创建的ReceiveSideCongestionController

webrtc 代码学习&#xff08;三十二&#xff09; video RTT 作用笔记 从call模块说起 call模块创建的时候&#xff0c;会创建 src\call\call.h 线程&#xff1a; 统计 const std::unique_ptr<CallStats> call_stats_;SendDelayStats &#xff1a; 发送延迟统计 const…

WebGL中开发VR(虚拟现实)应用

WebGL&#xff08;Web Graphics Library&#xff09;是一种用于在浏览器中渲染交互式3D和2D图形的JavaScript API。要在WebGL中开发VR&#xff08;虚拟现实&#xff09;应用程序&#xff0c;您可以遵循以下一般步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&a…

手把手带你死磕ORBSLAM3源代码(五十一) FrameDrawer.cc DrawTextInfo

目录 一.前言 二.代码 2.1完整代码 2.2 cv::Mat::zeros介绍 2.3 cv::putText介绍 2.4 cv::Point介绍

word vba自动化排版-设置标题模板样式、标题、正文、图表、页面、上下标等设置、删除空白行、删除分页符分节符、删除空格等

word vba自动化排版-设置标题模板样式、标题、正文、图表、页面、上下标等设置、删除空白行、删除分页符分节符、删除空格等 目录 1.前提 2.思路 3.word中设置 4.效果图 5.经验教训 6.直接上代码 1.前提 需求&#xff1a;工作中涉及自动识别大量的文字报告&#xff08;o…

实验笔记之——基于TUM-RGBD数据集的SplaTAM测试

之前博客对SplaTAM进行了配置&#xff0c;并对其源码进行解读。 学习笔记之——3D Gaussian SLAM&#xff0c;SplaTAM配置&#xff08;Linux&#xff09;与源码解读-CSDN博客SplaTAM全称是《SplaTAM: Splat, Track & Map 3D Gaussians for Dense RGB-D SLAM》&#xff0c;…