elf文件反编译C语言,ELF文件解析和反汇编
首先來(lái)看一段Unix/Linux下的匯編代碼:
#PURPOSE: This program finds the maximum number of a
# set of data items.
##VARIABLES: The registers have the following uses:
## %edi - Holds the index of the data item being examined
# %ebx - Largest data item found
# %eax - Current data item
## The following memory locations are used:
## data_items - contains the item data. A 0 is used
# to terminate the data
#
.section .data
data_items:
.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
.section .text
.globl _start
_start:
movl $0, %edi
movl data_items(,%edi,4), %eax
movl %eax, %ebx
start_loop:
cmpl $0, %eax
je loop_exit
incl %edi
movl data_items(,%edi,4), %eax
cmpl %ebx, %eax
jle start_loop
movl %eax, %ebx
jmp start_loop
loop_exit:
movl $1, %eax
int $0x80
被紅色注釋的部分就是匯編代碼,先大概的解釋一下這段代碼的意思。.section .data表示的是數(shù)據(jù)段。
data_items:
.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
表示的是定義的一個(gè)long型的數(shù)組。
.section .text 表示的是代碼區(qū)段。下面的部分就是真正的代碼部分。
.globl _start 表示的定義了一個(gè)全局的標(biāo)識(shí)符_start,相當(dāng)C語(yǔ)言中的標(biāo)簽作用,_start要被鏈接器使用,相當(dāng)C語(yǔ)言中的main函數(shù)一樣,是整個(gè)程序的入口。
用%edi寄存器中的值表示數(shù)組下標(biāo)
movl data_items(,%edi,4), %eax
movl %eax, %ebx
表示把取數(shù)組data_items中的第%edi的值,存放至寄存器%eax,同時(shí)%ebx表示的是數(shù)組中的最大值,初始化為數(shù)組的第一個(gè)元素。
start_loop,loop_exit都屬于標(biāo)簽性質(zhì)。
cmpl $0, %eax
je loop_exit
因?yàn)槲覀兌x數(shù)組的時(shí)候,最后一個(gè)元素為0,即0為哨兵,比較%eax和0,如果相等的話(huà),表示程序已經(jīng)完成,跳轉(zhuǎn)至loop_exit處執(zhí)行。
incl %edi
movl data_items(,%edi,4), %eax
cmpl %ebx, %eax
否則移動(dòng)數(shù)組下標(biāo),取數(shù)組的下一個(gè)元素值,與%ebx進(jìn)行比較,若%eax中的值比%ebx值大,則將%eax值給%ebx,保持%ebx維持是數(shù)組的最大值。
movl $1, %eax
int $0x80
表示exit退出,并且退出碼為1.
上面所講的就是該段匯編代碼的涵義。.
把上述的匯編代碼編輯在test.s文檔中,然后執(zhí)行下面的命令:
as test.s -o test.o
ld test.o -o test
Unix/Linux中的可執(zhí)行文件都是采用的ELF文件格式標(biāo)準(zhǔn),但是有3中不同的類(lèi)型:
<1>.可重定位的目標(biāo)文件(Relocatable Object file)
<2>.可執(zhí)行文件(Executable file)
<3>.共享庫(kù)(Shared library)
我們通過(guò)分析ELF文件的組成,來(lái)了解編譯和鏈接的過(guò)程。
我們用Linux下帶的工具來(lái)查看elf文件,用下述命令即可:
$ readelf -a test.o
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: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 200 (bytes into file)
Flags: 0x0
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
...
上面的就是被解讀出來(lái)的elf文件信息。
ELF Header中描述了操作系統(tǒng)是UNIX,體系結(jié)構(gòu)是80386。Section Header Table中有8個(gè)Section Header,在文件中的位置(或者叫文件地址)從200(0xc8)開(kāi)始,每個(gè)40字節(jié),共320字節(jié),到文件地址0x207結(jié)束。這個(gè)目標(biāo)文件沒(méi)有Program Header。
如果想要從目標(biāo)文件反匯編的話(huà),可以執(zhí)行下述命令即可。
$ objdump -d test.o
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
0: bf 00 00 00 00?mov $0x0,%edi
5: 8b 04 bd 00 00 00 00?mov 0x0(,%edi,4),%eax
c: 89 c3?mov %eax,%ebx
0000000e :
e: 83 f8 00?cmp $0x0,%eax
11: 74 10?je 23
13: 47?inc %edi
14: 8b 04 bd 00 00 00 00?mov 0x0(,%edi,4),%eax
1b: 39 d8?cmp %ebx,%eax
1d: 7e ef?jle e
1f: 89 c3?mov %eax,%ebx
21: eb eb?jmp e
00000023 :
23: b8 01 00 00 00?mov $0x1,%eax
28: cd 80?int $0x80
上面右邊的代碼就是反匯編后生成的代碼,對(duì)比一下本身的代碼和反匯編后的有何區(qū)別,會(huì)發(fā)現(xiàn)很多該出現(xiàn)地址的地方都是0,這是因?yàn)槌绦蛑挥性阪溄拥臅r(shí)候才會(huì)真正的把函數(shù)以及變量的地址加載進(jìn)代碼中來(lái)。
我們對(duì)可執(zhí)行程序反匯編一下,就知道結(jié)果了:
$ objdump -d test
test: file format elf32-i386
Disassembly of section .text:
08048074 <_start>:
8048074: bf 00 00 00 00?mov $0x0,%edi
8048079: 8b 04 bd a0 90 04 08?mov 0x80490a0(,%edi,4),%eax
8048080: 89 c3?mov %eax,%ebx
08048082 :
8048082: 83 f8 00?cmp $0x0,%eax
8048085: 74 10?je 8048097
8048087: 47?inc %edi
8048088: 8b 04 bd a0 90 04 08?mov 0x80490a0(,%edi,4),%eax
804808f: 39 d8?cmp %ebx,%eax
8048091: 7e ef?jle 8048082
8048093: 89 c3?mov %eax,%ebx
8048095: eb eb?jmp 8048082
08048097 :
8048097: b8 01 00 00 00?mov $0x1,%eax
804809c: cd 80?int $0x80現(xiàn)在反匯編的代碼中已經(jīng)把絕對(duì)地址都加在進(jìn)程序中了。從這個(gè)角度來(lái)理解編譯和鏈接應(yīng)該更深入一些,編譯只是檢查語(yǔ)法錯(cuò)誤,對(duì)應(yīng)的地址都是虛擬地址(即被MMU單元截獲了地址),鏈接時(shí),把虛擬地址轉(zhuǎn)化為絕對(duì)地址,加載進(jìn)可執(zhí)行文件中。
總結(jié)
以上是生活随笔為你收集整理的elf文件反编译C语言,ELF文件解析和反汇编的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: win7升级自带ie8到ie11版本(在
- 下一篇: 游戏的设计要素