本文首次发表于 上手 9 套工具,玩转二进制文件
如果能把每一个 bit 都看透,那么还有什么 bug 解决不了的呢?!
~~文末有码农进阶必修课程~~
前言
文件的终极存储方式是一堆二进制(01)串,在这个基础上,如果内容都能按照 8 位的 ASCII 文本表达,那就是纯文本文件,用各种文本编辑工具处理即可,如果内容是结构化的程序数据,比如可执行文件,那么得从二进制层面去操作。
对于特定的结构化数据,一般都有配套的操作 API,比如说 ELF,有专属的 binutils, elfutils 等,本文主要介绍通用的二进制操作工具,并以 ELF 为例,比照介绍相应的专属工具,这些工具在 Ubuntu 中都可以直接安装。
准备工作
先准备一个具体的小汇编程序,这个作为本文二进制操作演示的材料。
# hello.s
#
# as --32 -o hello.o hello.s
# ld -melf_i386 -o hello hello.o
# objcopy -O binary hello hello.bin
#
.text
.global _start
_start:
xorl %eax, %eax
movb $4, %al # eax = 4, sys_write(fd, addr, len)
xorl %ebx, %ebx
incl %ebx # ebx = 1, standard output
movl $.LC0, %ecx # ecx = $.LC0, the addr of string
xorl %edx, %edx
movb $13, %dl # edx = 13, the length of .string
int $0x80
xorl %eax, %eax
movl %eax, %ebx # ebx = 0
incl %eax # eax = 1, sys_exit
int $0x80
.section .rodata
.LC0:
.string "Hello Worldxax0"
把上面这份代码汇编、链接,并执行:
$ as --32 -o hello.o hello.s
$ ld -melf_i386 -o hello hello.o
$ ./hello
Hello World
仅保留代码和数据:
$ objcopy -O binary hello hello.bin
经过上面两步,得到了两个二进制文件,一个是 ELF 可执行文件 hello,另外一个是只包含了代码和数据的二进制文件 hello.bin。
二进制查看
比较常用的二进制读取工具有:
- hexdump
- xxd
- od
查看 hello.bin
以读取 hello.bin
为例,三者可以输出类似的数据样式:
$ hexdump -C hello.bin
00000000 31 c0 b0 04 31 db 43 b9 6d 80 04 08 31 d2 b2 0d |1...1.C.m...1...|
00000010 cd 80 31 c0 89 c3 40 cd 80 48 65 6c 6c 6f 20 57 |..1...@..Hello W|
00000020 6f 72 6c 64 0a 00 00 |orld...|
00000027
$ xxd -g 1 hello.bin
00000000: 31 c0 b0 04 31 db 43 b9 6d 80 04 08 31 d2 b2 0d 1...1.C.m...1...
00000010: cd 80 31 c0 89 c3 40 cd 80 48 65 6c 6c 6f 20 57 ..1...@..Hello