首页
社区
课程
招聘
[原创] Arm静态分析引擎原理一 - 反汇编引擎码表设计
发表于: 2026-7-29 15:02 490

[原创] Arm静态分析引擎原理一 - 反汇编引擎码表设计

2026-7-29 15:02
490

我原来写了个手搓反汇编引擎的帖子,有人说垃圾,我觉得确实写的潦潦草草,这里重新仔细的写一遍


反汇编其实很简单,没有特殊处理过的elf/pe/mach-o,找到对应的代码部分,顺着往下写就行,查表-解码-输出汇编,比如基于llvm的capstone、ghidra、zydis这些,都是查表做的。这个表是什么,就是cpu指令集的手册。


我实现了一个arm的反汇编引擎,名字叫rosemary,原理和capstone,zydis这些差不多,属于重复的轮子。

引擎基于:DDI0487L_b_a-profile_architecture_reference_manual.pdf这个手册实现的,是不是最新的我也好久没有看过了。


现在进入正题


arm汇编的码表设计类似b-tree索引,以arm64为例,4字节,32个bit的一个数字

从0-31,每一个bit或者bit组合形成一个章节,比如0xx0000xxxxxxxxxxxxxxxxxxxxxxxx,这个就是arm的保留码,任何符合这个规则的编码,都可以认为是nop。


arm的码表一级目录分为Reserved/SME/SVE/Data Processing IMM/Branch/Data processing register/SIME/Load and Store,如下图:

二级码表又可以分为data processing 1 source, Pc-rel, Add/SUB/Logic等等,那么根据手册,就可以非常轻松的理解,给定一条arm指令,如果它的二进制是:

那么它就是属于Data processing Immediate, 如果它的二进制是:

那么它就是Data-processing(1 source immediate)里面的,依次类推,直到匹配到一条确定性的指令。



当匹配到一条指令时候,就需要确定这条指令的操作数是什么了,比如mov x0, 1,那么指令是mov,操作数有两个一个是x0,另外一个是常数1。

我们拿arm64的add(Immediate)来举例:


这一条add指令有三个操作数:add Xd, Xn, #imm,其中:

寄存器Xd是0-4

寄存器Xn是5-9

立即数是10-21

立即数有shift,如果sh(第22位) == 1的情况下,那么立即数要左移12位,如果是0的情况下,就不显示

sf表示的是寄存器是32位还是64位,如果是32位,那么Xn就是Wn,他们的Wn和Xn的物理位置是一样的,只不过长短不一样



有了上面基础理解,就可以设计解码器和解码数据了,按照最简单也是最蠢的办法就是

但是cpu的指令集有成千上万条的具体指令,不能做成一个巨大的switch,那样几乎是无法维护的,所以大家都是自己定义数据格式来生成解码表。

接下来是设计描述汇编arm/x86/mips的数据结构,这里就可以根据自己的喜好,比如有人喜欢lua,有人喜欢python,根据自己的情况选一门脚本语言,来描述汇编语言。

我比较喜欢写ruby,我选ruby,以Data Processing – Immediate里的add为例:

定义


一条add指令的描述数据就是这个样子的:

patterns: 描述指令的每个bit位,有0/1/x,0/1表示必须位0或者必须位1,x表示不关心。

desc:在章节部分的字符串,调试方便。

list:标识这是一个章节,如果一个item没有list,那么表示它是一条确定的指令。

param:格式是31:0,30:0,29:0,这里表示指令的第31位,第30位,第29位必须同时为0。

name:指令的助记符。

grammar:指令的语法,调试方便。

ops_desc: 描述指令的每一个oprands,以上面为例,add Wd, Wn, #imm,

t: :r_w表示操作数是寄存器类型,w表示32位寄存器,x表示64位寄存器,还有SIMD的向量寄存器。


冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

最后于 5天前 被neocanable编辑 ,原因: 编辑一下,后面还有后续
收藏
免费 28
打赏
分享
最新回复 (12)
雪    币: 11112
活跃值: (10619)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
2
2026-7-29 15:08
0
雪    币: 1449
活跃值: (9032)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
3
你说的没错,但是那些牛X工具的实现,没有你说的 这么简单
2026-7-29 15:21
0
雪    币: 530
活跃值: (3451)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
gamehack 你说的没错,但是那些牛X工具的实现,没有你说的 这么简单
反汇编引擎的实现原理其实就是很简单,复杂的地方是指令集的庞大和设计测试用例
2026-7-29 15:26
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
666
2026-7-29 16:08
0
雪    币: 89
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
反编译才是最难的
2026-7-29 16:32
0
雪    币: 530
活跃值: (3451)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
温泉划水鱼 反编译才是最难的
反编译的难主要在于类型恢复和内存上,其实pre-c的结构恢复不难,毕竟可以goto
2026-7-29 16:50
0
雪    币: 1560
活跃值: (5508)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
8
123123
2026-7-29 16:52
0
雪    币: 0
活跃值: (2096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
555
2026-7-29 16:56
0
雪    币: 10700
活跃值: (8877)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
666
2026-7-29 17:19
0
雪    币: 23
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
1
2026-7-29 18:54
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
666
2026-7-29 19:31
0
雪    币: 568
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
学习学习
2026-7-30 00:06
0
游客
登录 | 注册 方可回帖
返回