Linux下C程序的反匯編
Linux下C程序的反匯編
objdump -s -d main.o > main.o.txt
前言:本文主要介紹幾種反匯編的方法。
gcc
gcc的完整編譯過程大致為:預(yù)處理->編譯->匯編->鏈接
前三個步驟分別對應(yīng)了-E、-S、-c三個選項。
今天我要介紹的第一種方法就是使用-S這個選項。
源程序main.c:
/*************************************************************************
> File Name: main.c
> Author: AnSwEr
> Mail: 1045837697@qq.com
> Created Time: 2015年12月08日 星期二 20時06分19秒
************************************************************************/
#include<stdio.h>
int i = 1;
int main(void)
{
++i;
printf("%d\n",i);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
執(zhí)行以下命令:
gcc -S -o main.s main.c
1
查看匯編源程序main.s:
.file "main.c"
.globl i
.data
.align 4
.type i, @object
.size i, 4
i:
.long 1
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl i(%rip), %eax
addl $1, %eax
movl %eax, i(%rip)
movl i(%rip), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
哈哈,大家看是不是成功了?至于匯編程序的具體解釋則不在本文的討論范疇。
最后介紹一下gcc的具體過程:
參考: https://github.com/1184893257/simplelinux/blob/master/gcc.md#top
編譯階段 命令 截斷后的產(chǎn)物
C源程序
預(yù)處理 gcc -E 替換了宏的C源程序(沒有了#define,#include…), 刪除了注釋
編譯 gcc -S 匯編源程序
匯編 gcc -c 目標(biāo)文件,二進制文件, 允許有不在此文件中的外部變量、函數(shù)
鏈接 gcc 可執(zhí)行程序,一般由多個目標(biāo)文件或庫鏈接而成, 二進制文件,所有變量、函數(shù)都必須找得到
objdump
objdump是linux下一款反匯編工具,能夠反匯編目標(biāo)文件、可執(zhí)行文件。
主要選項:
objdump -f
顯示文件頭信息
objdump -d
反匯編需要執(zhí)行指令的那些section
objdump -D
與-d類似,但反匯編中的所有section
objdump -h
顯示Section Header信息
objdump -x
顯示全部Header信息
objdump -s
將所有段的內(nèi)容以十六進制的方式打印出來
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
目標(biāo)文件
反匯編:
gcc -c -o main.o main.c
objdump -s -d main.o > main.o.txt
1
2
查看匯編文件:
main.o: 文件格式 elf64-x86-64
Contents of section .text:
0000 554889e5 8b050000 000083c0 01890500 UH..............
0010 0000008b 05000000 0089c6bf 00000000 ................
0020 b8000000 00e80000 0000b800 0000005d ...............]
0030 c3 .
Contents of section .data:
0000 01000000 ....
Contents of section .rodata:
0000 25640a00 %d..
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520342e .GCC: (Ubuntu 4.
0010 382e322d 31397562 756e7475 31292034 8.2-19ubuntu1) 4
0020 2e382e32 00 .8.2.
Contents of section .eh_frame:
0000 14000000 00000000 017a5200 01781001 .........zR..x..
0010 1b0c0708 90010000 1c000000 1c000000 ................
0020 00000000 31000000 00410e10 8602430d ....1....A....C.
0030 066c0c07 08000000 .l......
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # a <main+0xa>
a: 83 c0 01 add $0x1,%eax
d: 89 05 00 00 00 00 mov %eax,0x0(%rip) # 13 <main+0x13>
13: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 19 <main+0x19>
19: 89 c6 mov %eax,%esi
1b: bf 00 00 00 00 mov $0x0,%edi
20: b8 00 00 00 00 mov $0x0,%eax
25: e8 00 00 00 00 callq 2a <main+0x2a>
2a: b8 00 00 00 00 mov $0x0,%eax
2f: 5d pop %rbp
30: c3 retq
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
可執(zhí)行文件
反匯編:
gcc -o main main.c
objdump -s -d main > main.txt
1
2
查看匯編文件(由于文件較大,只取部分展示):
Disassembly of section .init:
00000000004003e0 <_init>:
4003e0: 48 83 ec 08 sub $0x8,%rsp
4003e4: 48 8b 05 0d 0c 20 00 mov 0x200c0d(%rip),%rax # 600ff8 <_DYNAMIC+0x1d0>
4003eb: 48 85 c0 test %rax,%rax
4003ee: 74 05 je 4003f5 <_init+0x15>
4003f0: e8 3b 00 00 00 callq 400430 <__gmon_start__@plt>
4003f5: 48 83 c4 08 add $0x8,%rsp
4003f9: c3 retq
Disassembly of section .plt:
0000000000400400 <printf@plt-0x10>:
400400: ff 35 02 0c 20 00 pushq 0x200c02(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
400406: ff 25 04 0c 20 00 jmpq *0x200c04(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
40040c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000400410 <printf@plt>:
400410: ff 25 02 0c 20 00 jmpq *0x200c02(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
400416: 68 00 00 00 00 pushq $0x0
40041b: e9 e0 ff ff ff jmpq 400400 <_init+0x20>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
linux 下目標(biāo)文件(默認(rèn)擴展名是.o)和可執(zhí)行文件都是 ELF 格式(文件內(nèi)容按照一定格式進行組織)的二進制文件; 類似的,Windows 下 VISUAL C++ 編譯出來的目標(biāo)文件 (擴展名是.obj)采用 COFF 格式,而可執(zhí)行文件 (擴展名是.exe)采用 PE 格式, ELF 和 PE 都是從 COFF 發(fā)展而來的。
因為 linux 下目標(biāo)文件和可執(zhí)行文件的內(nèi)容格式是一樣的, 所以 objdump 既可以反匯編可執(zhí)行文件也可以反匯編目標(biāo)文件。
總結(jié)
掌握了反匯編的方法,當(dāng)你的程序遇到一些未知的變量錯誤等,可以直接反匯編來查看匯編代碼,一切一目了然。PS:匯編我已經(jīng)忘得差不多了。
參考
https://github.com/1184893257/simplelinux
反饋與建議
微博:@AnSwEr不是答案
github:AnSwErYWJ
博客:AnSwEr不是答案的專欄
————————————————
原文鏈接:https://blog.csdn.net/u011192270/article/details/50224267
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。