学习ARM反汇编工具objdump和一个简单实例

学习ARM反汇编工具objdump和一个简单实例

                                                                         --参考朱有鹏ARM裸机编程


1、反汇编的原理&为什么需要反汇编
arm-linux-objdump -D led.elf > led_elf.dis
objdump是gcc工具链中的反汇编工具,作用是由编译链接好的elf
格式的可执行程序,来反过来得到汇编源代码。

-D表示反汇编。

>左边的是ELF的可执行程序(反汇编时候的原材料)
>右边的是反汇编生成的反汇编程序。其实就是一个汇编语言。


一般情况下我们写一个源代码

类似于我们WINDOW里面是EXE的格式,PE格式是官方的名字。


2、为什么我们需要进行反汇编,我们要的就是可执行程序。

反汇编的原因有以下:
1、逆向破解
你想盗版的原来的程序,最终得到程序的源代码。
2、调式程序的时候,反汇编代码可以帮助我们理解程序。

(我们学习时使用objdump主要目的是这个),
尤其是在理解链接脚本,链接地址等概念时候。
尤其是在理解链接的时候,用反汇编对你的理解非常大。


如果你是C语言写的源代码,反汇编之后得到的汇编语言的源代码,

可以有助于你理解C和汇编之间的关系,
非常有助于理解深入理解C语言。

3、反汇编文件的分析:

(1)第一个是标号比如000000这些是代表当前的地址

(2)第二个标号比如e59f0050:代表的是机器码的意思,其实我们写的所有的可执行程序都是机器码

只不过汇编语言就是相当于一句汇编语言对应一个机器码,这样我们编程就不用像以前那么辛苦了。

  0:	e59f0050 	ldr	r0, [pc, #80]	; 58 <delay_loop+0x10>
这句话是 ldr r0, =0x11111111 // 从后面的=可以看出用的是ldr伪指令,因为需要编译器来判断这个数

编译器翻译出来就是上面的一句话,0x11111111这个数是ARM伪指令提供的。

那么到底机器把这句话放置在哪里呢?

把这句话放置在58这个地址中,后面已经有注释了:

再往下看58地址中,可以看到显示11111111


led.elf:     file format elf32-littlearm


Disassembly of section .text:

00000000 <_start>:
   0:	e59f0050 	ldr	r0, [pc, #80]	; 58 <delay_loop+0x10>
   4:	e59f1050 	ldr	r1, [pc, #80]	; 5c <delay_loop+0x14>
   8:	e5810000 	str	r0, [r1]

0000000c <flash>:
   c:	e3e00008 	mvn	r0, #8
  10:	e59f1048 	ldr	r1, [pc, #72]	; 60 <delay_loop+0x18>
  14:	e5810000 	str	r0, [r1]
  18:	eb000008 	bl	40 <delay>
  1c:	e3e00010 	mvn	r0, #16
  20:	e59f1038 	ldr	r1, [pc, #56]	; 60 <delay_loop+0x18>
  24:	e5810000 	str	r0, [r1]
  28:	eb000004 	bl	40 <delay>
  2c:	e3e00020 	mvn	r0, #32
  30:	e59f1028 	ldr	r1, [pc, #40]	; 60 <delay_loop+0x18>
  34:	e5810000 	str	r0, [r1]
  38:	eb000000 	bl	40 <delay>
  3c:	eafffff2 	b	c <flash>

00000040 <delay>:
  40:	e59f201c 	ldr	r2, [pc, #28]	; 64 <delay_loop+0x1c>
  44:	e3a03000 	mov	r3, #0

00000048 <delay_loop>:
  48:	e2422001 	sub	r2, r2, #1
  4c:	e1520003 	cmp	r2, r3
  50:	1afffffc 	bne	48 <delay_loop>
  54:	e1a0f00e 	mov	pc, lr
  58:	11111111 	tstne	r1, r1, lsl r1
  5c:	e0200240 	eor	r0, r0, r0, asr #4
  60:	e0200244 	eor	r0, r0, r4, asr #4
  64:	00895440 	addeq	r5, r9, r0, asr #8

Disassembly of section .ARM.attributes:

00000000 <.ARM.attributes>:
   0:	00001a41 	andeq	r1, r0, r1, asr #20
   4:	61656100 	cmnvs	r5, r0, lsl #2
   8:	01006962 	tsteq	r0, r2, ror #18
   c:	00000010 	andeq	r0, r0, r0, lsl r0
  10:	45543505 	ldrbmi	r3, [r4, #-1285]	; 0x505
  14:	08040600 	stmdaeq	r4, {r9, sl}
  18:	Address 0x00000018 is out of bounds.


4、反汇编文件的格式和看法


标号地址、标号名字、指令地址、指令机器码
指令机器码反汇编到的指令

扩展:ARM汇编中用地址池的方式实现非法立即数。

指令和地址是一一对应的,
我们下载烧录的bin文件,内部其实就是
一条一条的指令机器码,这些指令每一条都有一个指令地址。
这个地址是连接的ld给根据我们写的链接脚本来指定的。


-Ttext  :指定我们的起始地址的。

所有的地址都从别的地址开始执行,根据你的地址来执行。



5、展望:反汇编工具帮助我们分析链接脚本


反汇编的时候得到的地址是链接器考虑了链接脚本之后得到的地址,而
我们写代码是通过指定链接脚本来让链接器给我们链接合适的地址。


但是有时候我们写的链接脚本有误,或者我们不知道
这个链接脚本会怎么样?


这时候可以通过看反汇编文件分析这个链接脚本的效果。
看是不是我们想要的,如果不是的话可以改了再看。






### 如何使用 `objdump` 进行反汇编 #### 基本概念 `objdump` 是 Linux 平台上用于处理 ELF 文件的强大工具之一,能够将二进制文件转换为人类可读的汇编代码。此工具不仅限于简单反汇编功能;它还提供了丰富的选项来展示各种类型的元数据和辅助信息。 #### 使用实例 为了执行基本的反汇编操作,可以采用以下命令: ```bash objdump -l -x -d gcc_objdump > gcc_objdump.dmp ``` 这条指令会把名为 `gcc_objdump` 的ELF文件的内容解码成汇编语言并保存至 `gcc_objdump.dmp` 文件中[^1]。 如果希望更深入地分析特定部分(例如 `.text` 段),则应考虑加入 `-j` 参数指定节区名称,并且可以通过管道符配合其他实用程序如 `more` 实现分页浏览效果: ```bash objdump -j .text -Sl objtest --prefix-addresses | more ``` 上述命令允许逐屏查看已编译C/C++程序(`objtest`)内`.text`段对应的机器码及其源级映射关系,同时每条指令前加上其内存地址作为前缀[^2]. 当涉及到混合模式下既想要看到原始汇编又不丢失高级语言结构时,则推荐利用带有 `-S` 开关的方式来进行联合显示: ```bash objdump -S test ``` 这使得开发者可以在同一视图里对比检查源代码同最终生成的目标代码间的关系,有助于定位潜在错误位置以及理解优化过程的影响程度[^4]. 除了以上提到的功能外, `objdump` 同样适用于探索静态库(.a)内部组成情况。通过组合运用诸如 `cp`, `ar`, 和 `nm` 等命令,用户可以获得有关链接器脚本、符号定义等方面的知识[^5]: ```bash cp /usr/lib/libpcap.a /home/user/src/ ar t libpcap.a nm -s libpcap.a | less ``` 这些例子展示了如何复制一个标准C函数库副本到个人工作空间,列出其中所含对象模块的名字列表,并借助 `less` 分页器滚动阅览各个成员内的全局/外部可见符号详情.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值