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;…

大模型微调学习记录-基于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;上进行推理…

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 重新启动

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 排查问题 这个是一个比较新的问…

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

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…

实验笔记之——基于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;…

在红墙下的冬日幻想:Pygame库实现下雪动画

在红墙下的冬日幻想&#xff1a;借助Pygame库实现下雪动画 寒风轻拂着故宫红墙&#xff0c;我静静地思念着你。这个冬天&#xff0c;借助 Python 的 Pygame 库&#xff0c;我为你呈现一场梦幻般的下雪动画&#xff0c;让雪花在故宫红墙的映衬下在屏幕上翩翩起舞。 准备 首先…

【C++】:STL序列式容器list源码剖析

一、list概述 总的来说&#xff1a;环形双向链表 特点&#xff1a; 底层是使用链表实现的&#xff0c;支持双向顺序访问 在list中任何位置进行插入和删除的速度都很快 不支持随机访问&#xff0c;为了访问一个元素&#xff0c;必须遍历整个容器 与其他容器相比&#xff0c;额外…

【AI预测】破晓未来教育市场:如何精准定位、精选师资并启动高潜力培训项目

在当前全球化和技术快速迭代的背景下&#xff0c;各行业正面临巨大的人才缺口和新的发展机遇。 全球化浪潮&#xff0c;各行业如同搭乘上了一列高速列车&#xff0c;不断深入探索并广泛应用AI技术以提升产业效率、创新服务模式。在智能制造领域&#xff0c;工业4.0时代犹如给…

【leetcode】消失的数字

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家刷题&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1.暴力求解法2.采用异或的方法&#xff08;同单身狗问题&#xff09;3.先求和再减去数组元素 点击查看…

Linux grep命令(grep指令)grep --help各选项介绍(待更)

文章目录 grep --help英文中文 使用示例-E, --extended-regexp&#xff1a;此选项表示模式为扩展正则表达式。-F, --fixed-strings&#xff1a;此选项表示模式被视为固定字符串而不是正则表达式。-G, --basic-regexp&#xff1a;此选项表示模式为基础正则表达式。这是默认的模式…

Rust之旅 - Rust概念、Windows安装、环境配置

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列专栏目录 [Java项目…

【C++初阶】第二站:类与对象(上) -- 上部分

前言: C学习的第二站&#xff1a;类和对象(上)文章的上半部分,知识点:面向过程和面向对象初步认识、类的引入、类的定义、类的访问限定符及封装、类的作用域、类的实例化. 目录 面向过程和面向对象初步认识 类的引入 类的定义 类的访问限定符及封装 访问限定符 封装 类的…

深入理解Linux文件系统

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;晴る—ヨルシカ 0:20━━━━━━️&#x1f49f;──────── 4:30 &#x1f504; ◀️ ⏸ ▶️ ☰ &…

防火墙技术

防火墙&#xff08;英语&#xff1a;Firewall&#xff09;技术是通过有机结合各类用于安全管理与筛选的软件和硬件设备&#xff0c;帮助计算机网络于其内、外网之间构建一道相对隔绝的保护屏障&#xff0c;以保护用户资料与信息安全性的一种技术。 防火墙技术的功能主要在于及…