反编译基本方法

8010717f: 5b pop %ebx
80107180: 5e pop %esi
80107181: 5f pop %edi
80107182: 5d pop %ebp

为了配合GDB进行调试,有时我们需要将源码进行反编译,从而得到汇编代码,查看对应的地址上的语句。

一些常用命令

objdump:二进制文件分析

常用参数

  • -f 显示文件头信息
  • -D 反汇编所有section (-d反汇编特定section)
  • -h 显示目标文件各个section的头部摘要信息
  • -x 显示所有可用的头信息,包括符号表、重定位入口。-x 等价于 -a -f -h -r -t 同时指定。
  • -i 显示对于 -b 或者 -m 选项可用的架构和目标格式列表。
  • -r 显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。
  • -R 显示文件的动态重定位入口,仅仅对于动态目标文件有意义,比如某些共享库。
  • -S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。
  • -t 显示文件的符号表入口。类似于nm -s提供的信息
  • -G 显示一个ELF文件中.stab/.stab.index/.stab.excl段(symbol-table)的内容

实例

1 查看本机是大端存储还是小端存储

1
2
3
4
5
duan@husky:~/Code/linux/6.828/lab/obj/kern (lab1 *%) $ objdump -i
BFD 头文件版本 (GNU Binutils) 2.35.1
elf64-x86-64
(header 小端序, data 小端序)
i386

2 反汇编程序

1
2
3
4
objdump -d kernel | grep %cr4  # 将kernel进行反编译,然后查看cr4寄存器所在的所有命令

8010000c: 0f 20 e0 mov %cr4,%eax
80100012: 0f 22 e0 mov %eax,%cr4

3 显示目标文件各个section的头部摘要信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
objdump -h kernel 

kernel: 文件格式 elf32-i386

节:
Idx Name Size VMA LMA File off Algn
0 .text 00001a1d f0100000 00100000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rodata 000006bc f0101a20 00101a20 00002a20 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
...

9 .bss 00000661 f0112060 00112060 00013060 2**5
CONTENTS, ALLOC, LOAD, DATA
10 .comment 00000012 00000000 00000000 000136c1 2**0
CONTENTS, READONLY

4 显示程序头信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ objdump -x kernel
kernel: 文件格式 elf32-i386
kernel
体系结构:i386,标志 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
起始地址 0x0010000c

程序头:
LOAD off 0x00001000 vaddr 0xf0100000 paddr 0x00100000 align 2**12
filesz 0x00006d62 memsz 0x00006d62 flags r-x
LOAD off 0x00008000 vaddr 0xf0107000 paddr 0x00107000 align 2**12
filesz 0x0000b6c1 memsz 0x0000b6c1 flags rw-
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
filesz 0x00000000 memsz 0x00000000 flags rwx

5 显示文件头信息

1
2
3
4
5
6
$ objdump -f obj/kern/kernel

obj/kern/kernel: 文件格式 elf32-i386
体系结构:i386,标志 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
起始地址 0x0010000c

比较重要的是起始地址,这里显示为0x0010000c

nm:显示文件中的符号

nm命令用于显示文件中的符号,对于一般的文件,我们能够直接读,而对于二进制可执行文件以及一些动态链接库,我们有必要通过nm命令查看其中的一些符号。相当于是将二进制转换为汇编,然后读取其中的符号内容。

1
2
3
4
nm kernel | grep _start
8010a48c D _binary_entryother_start
8010a460 D _binary_initcode_start
0010000c T _start

上面的命令查看了一个kernel可执行文件,然后抓取_start关键字,得到三行结果。

参考文献

0%