博客專欄

        EEPW首頁 > 博客 > Linux下C程序的反匯編

        Linux下C程序的反匯編

        發布人:電子禪石 時間:2021-04-14 來源:工程師 發布文章

        Linux下C程序的反匯編


        objdump -s -d main.o > main.o.txt

        前言:本文主要介紹幾種反匯編的方法。


        gcc

        gcc的完整編譯過程大致為:預處理->編譯->匯編->鏈接


        前三個步驟分別對應了-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

        執行以下命令:


        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


        編譯階段 命令 截斷后的產物

        C源程序

        預處理 gcc -E 替換了宏的C源程序(沒有了#define,#include…), 刪除了注釋

        編譯 gcc -S 匯編源程序

        匯編 gcc -c 目標文件,二進制文件, 允許有不在此文件中的外部變量、函數

        鏈接 gcc 可執行程序,一般由多個目標文件或庫鏈接而成, 二進制文件,所有變量、函數都必須找得到

        objdump

        objdump是linux下一款反匯編工具,能夠反匯編目標文件、可執行文件。


        主要選項:


        objdump -f 

        顯示文件頭信息


        objdump -d 

        反匯編需要執行指令的那些section


        objdump -D 

        與-d類似,但反匯編中的所有section


        objdump -h 

        顯示Section Header信息


        objdump -x 

        顯示全部Header信息


        objdump -s 

        將所有段的內容以十六進制的方式打印出來

        1

        2

        3

        4

        5

        6

        7

        8

        9

        10

        11

        12

        13

        14

        15

        16

        17

        目標文件

        反匯編:


        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

        可執行文件

        反匯編:


        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 下目標文件(默認擴展名是.o)和可執行文件都是 ELF 格式(文件內容按照一定格式進行組織)的二進制文件; 類似的,Windows 下 VISUAL C++ 編譯出來的目標文件 (擴展名是.obj)采用 COFF 格式,而可執行文件 (擴展名是.exe)采用 PE 格式, ELF 和 PE 都是從 COFF 發展而來的。


        因為 linux 下目標文件和可執行文件的內容格式是一樣的, 所以 objdump 既可以反匯編可執行文件也可以反匯編目標文件。


        總結

        掌握了反匯編的方法,當你的程序遇到一些未知的變量錯誤等,可以直接反匯編來查看匯編代碼,一切一目了然。PS:匯編我已經忘得差不多了。


        參考

        https://github.com/1184893257/simplelinux

        反饋與建議

        微博:@AnSwEr不是答案

        github:AnSwErYWJ

        博客:AnSwEr不是答案的專欄

        ————————————————


        原文鏈接:https://blog.csdn.net/u011192270/article/details/50224267


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞:

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 尼玛县| 台湾省| 广饶县| 青岛市| 杭锦旗| 柳州市| 阿克苏市| 肇源县| 汕尾市| 绵阳市| 自治县| 清镇市| 太湖县| 阳原县| 喀喇| 赫章县| 高唐县| 阿拉善左旗| 富裕县| 敦煌市| 龙岩市| 宝鸡市| 福州市| 曲松县| 南和县| 上高县| 宽城| 兴化市| 桐乡市| 和平县| 梓潼县| 渭南市| 纳雍县| 碌曲县| 筠连县| 岳阳市| 夏津县| 建宁县| 苏尼特左旗| 二连浩特市| 丽水市|