我尝试为 ARM 构建一个小型反汇编程序,我想知道如何objdump
设法从拇指模式指令(16 位指令宽)中整理出正常模式指令(32 位指令宽),而无需查看t
CPSR 中的标志。
但首先,让我们构建一个小示例并对其进行一些实验。
我写了一小段 ARM 程序集(gas
语法)作为基础示例:
.arm
mov fp, #0
moveq r1, r0
.thumb
mov r0, #0
mov fp, r0
然后,我像这样交叉编译它:
$> arm-none-eabi-gcc -Wall -Wextra -mlittle-endian -c -o arm_sample arm_sample.s
而且,这里是objdump
ARM 目标文件的输出:
$> objdump -d ./arm32_mov
./arm32_mov: file format elf32-littlearm
Disassembly of section .text:
00000000 <.text>:
0: e3a0b000 mov fp, #0
4: 01a01000 moveq r1, r0
8: 2000 movs r0, #0
a: 4683 mov fp, r0
但是,当我运行我的工具时,我得到:
warning: decoder says at (0x8,0):'strmi r2, [r3], r0' : Unknown mnemonic
0: 00 b0 a0 e3 mov fp, #0
4: 00 10 a0 01 moveq r1, r0
8: ...
我的工具基于libopcodes
(完全像objdump
),所以第三条指令只是被解释为仍然处于 32 位模式,而两条拇指模式指令只是被解释为一条 32 位指令,它给出strmi r2, [r3], r0
.
我的问题是我不明白如何objdump
知道在正常模式和拇指模式之间有一个切换。在发现这一点之前,我认为此信息仅在执行时通过t
CPSR 状态寄存器中的标志值才可用。
我试图查看代码,objdump
但是,我没有看到任何依赖于架构的案例来处理 ARM 拇指模式的案例。所以,这对我来说仍然是个谜......
欢迎任何建议!
编辑
事实上,我处理了一个目标文件(用-c
选项编译),所以没有那么多符号。但是,这是通过objdump
以下方式获得的更详细的输出:
$> objdump -x ./arm32_mov
./arm32_mov: file format elf32-littlearm
./arm32_mov
architecture: armv4t, flags 0x00000010:
HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000c 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000040 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000040 2**0
ALLOC
3 .ARM.attributes 00000016 00000000 00000000 00000040 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .ARM.attributes 00000000 .ARM.attributes
而且,这是输出readelf
:
$> readelf -a ./arm32_mov
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 148 (bytes into file)
Flags: 0x5000000, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 8
Section header string table index: 5
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 00000c 00 AX 0 0 4
[ 2] .data PROGBITS 00000000 000040 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000040 000000 00 WA 0 0 1
[ 4] .ARM.attributes ARM_ATTRIBUTES 00000000 000040 000016 00 0 0 1
[ 5] .shstrtab STRTAB 00000000 000056 00003c 00 0 0 1
[ 6] .symtab SYMTAB 00000000 0001d4 000070 10 7 7 4
[ 7] .strtab STRTAB 00000000 000244 000007 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
There are no relocations in this file.
There are no unwind sections in this file.
Symbol table '.symtab' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 1
2: 00000000 0 SECTION LOCAL DEFAULT 2
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 NOTYPE LOCAL DEFAULT 1 $a
5: 00000008 0 NOTYPE LOCAL DEFAULT 1 $t
6: 00000000 0 SECTION LOCAL DEFAULT 4
No version information found in this file.
Attribute Section: aeabi
File Attributes
Tag_CPU_arch: v4T
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-1
解决方案(伊恩库克)
$ objdump --syms --special-syms ./arm32_mov
./arm32_mov: file format elf32-littlearm
SYMBOL TABLE:
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l .text 00000000 $a <-- ARM code
00000008 l .text 00000000 $t <-- Thumb code
00000000 l d .ARM.attributes 00000000 .ARM.attributes
可以肯定的是,我再次交错了手臂代码、拇指代码和手臂代码。这是转储:
$> objdump --syms --special-syms ./arm32_mov
./arm32_mov: file format elf32-littlearm
SYMBOL TABLE:
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l .text 00000000 $a
00000008 l .text 00000000 $t
0000000c l .text 00000000 $a
00000000 l d .ARM.attributes 00000000 .ARM.attributes
您可以看到 ARM 符号在0x0
和处出现了两次,并且0xc
围绕着拇指符号。