如何在Linux中使用十六进制编辑器生成可执行ELF文件?

如何在Linux中使用十六进制编辑器生成可执行ELF文件?,linux,assembly,elf,Linux,Assembly,Elf,只是好奇。对于实际编程来说,这显然不是一个很好的解决方案,但我想在Bless(十六进制编辑器)中创建一个可执行文件 我的架构是x86。我能做一个非常简单的程序是什么?你好,世界?无限循环?与问题类似,但在Linux中。正如我在评论中提到的,您将为可执行文件编写自己的elf头,从而消除不必要的部分。还有几个必需的部分。网站上的文档很好地解释了这个过程。为了好玩,这里有几个例子: 相当于/bin/true(45字节): 00000000 7F 45 4C 46 01 00 00 00 00 00

只是好奇。对于实际编程来说,这显然不是一个很好的解决方案,但我想在Bless(十六进制编辑器)中创建一个可执行文件


我的架构是x86。我能做一个非常简单的程序是什么?你好,世界?无限循环?与问题类似,但在Linux中。

正如我在评论中提到的,您将为可执行文件编写自己的elf头,从而消除不必要的部分。还有几个必需的部分。网站上的文档很好地解释了这个过程。为了好玩,这里有几个例子:

相当于/bin/true(45字节):

00000000  7F 45 4C 46 01 00 00 00  00 00 00 00 00 00 49 25  |.ELF..........I%|
00000010  02 00 03 00 1A 00 49 25  1A 00 49 25 04 00 00 00  |......I%..I%....|
00000020  5B 5F F2 AE 40 22 5F FB  CD 80 20 00 01           |[_..@"_... ..|
0000002d
00000000  7f 45 4c 46 01 01 01 03  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  74 80 04 08 34 00 00 00  |........t...4...|
00000020  00 00 00 00 00 00 00 00  34 00 20 00 02 00 28 00  |........4. ...(.|
00000030  00 00 00 00 01 00 00 00  74 00 00 00 74 80 04 08  |........t...t...|
00000040  74 80 04 08 1f 00 00 00  1f 00 00 00 05 00 00 00  |t...............|
00000050  00 10 00 00 01 00 00 00  93 00 00 00 93 90 04 08  |................|
00000060  93 90 04 08 0d 00 00 00  0d 00 00 00 06 00 00 00  |................|
00000070  00 10 00 00 b8 04 00 00  00 bb 01 00 00 00 b9 93  |................|
00000080  90 04 08 ba 0d 00 00 00  cd 80 b8 01 00 00 00 31  |...............1|
00000090  db cd 80 48 65 6c 6c 6f  20 77 6f 72 6c 64 21 0a  |...Hello world!.|
000000a0
你经典的“你好,世界!”(160字节):

00000000  7F 45 4C 46 01 00 00 00  00 00 00 00 00 00 49 25  |.ELF..........I%|
00000010  02 00 03 00 1A 00 49 25  1A 00 49 25 04 00 00 00  |......I%..I%....|
00000020  5B 5F F2 AE 40 22 5F FB  CD 80 20 00 01           |[_..@"_... ..|
0000002d
00000000  7f 45 4c 46 01 01 01 03  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  74 80 04 08 34 00 00 00  |........t...4...|
00000020  00 00 00 00 00 00 00 00  34 00 20 00 02 00 28 00  |........4. ...(.|
00000030  00 00 00 00 01 00 00 00  74 00 00 00 74 80 04 08  |........t...t...|
00000040  74 80 04 08 1f 00 00 00  1f 00 00 00 05 00 00 00  |t...............|
00000050  00 10 00 00 01 00 00 00  93 00 00 00 93 90 04 08  |................|
00000060  93 90 04 08 0d 00 00 00  0d 00 00 00 06 00 00 00  |................|
00000070  00 10 00 00 b8 04 00 00  00 bb 01 00 00 00 b9 93  |................|
00000080  90 04 08 ba 0d 00 00 00  cd 80 b8 01 00 00 00 31  |...............1|
00000090  db cd 80 48 65 6c 6c 6f  20 77 6f 72 6c 64 21 0a  |...Hello world!.|
000000a0
别忘了让它们可执行…

反编译NASM hello world并理解其中的每个字节 这个答案的版本有一个很好的TOC和更多的内容:(这里达到了30k字符的限制)

标准 ELF由LSB指定:

  • 核心通用:
  • 核心AMD64:
LSB基本上与其他标准链接,并进行了少量扩展,特别是:

  • 通用(均由上海合作组织提供):

    • System V ABI 4.1(1997),没有64位,但保留了一个幻数。核心文件也是如此
    • System V ABI更新草案17(2003),增加了64位。仅更新了前一份文件的第4章和第5章:其他章节仍然有效,并且仍然被引用
  • 特定于体系结构:

    • IA-32:,主要指向
    • AMD64:,主要指向
可在以下网址找到方便的摘要:

man elf
它的结构可以通过
readelf
objdump
等实用程序以人类可读的方式进行检查

生成示例 让我们分析一个最小的可运行Linux x86-64示例:

section .data
    hello_world db "Hello world!", 10
    hello_world_len  equ $ - hello_world
section .text
    global _start
    _start:
        mov rax, 1
        mov rdi, 1
        mov rsi, hello_world
        mov rdx, hello_world_len
        syscall
        mov rax, 60
        mov rdi, 0
        syscall
汇编时使用:

nasm -w+all -f elf64 -o 'hello_world.o' 'hello_world.asm'
ld -o 'hello_world.out' 'hello_world.o'
版本:

  • NASM 2.10.09
  • Binutils版本2.24(包含
    ld
  • Ubuntu 14.04
我们不使用C程序,因为这会使分析复杂化,这将是第2级:-)

六边形垃圾堆 输出在:

全局文件结构 ELF文件包含以下部分:

  • 精灵头。指向节标题表和程序标题表的位置

  • 节头表(可执行文件上可选)。每个都有
    e_shnum
    节标题,每个标题都指向节的位置


  • N节,带
    N我认为这篇文章顶部答案中建议的链接将有助于回答您的问题--提供的简单linux程序是引导一个简单的编译器最简单的方法显然是hello world。首先用C编写hello world,然后用
    gcc-S
    编译,并检查编译器的汇编输出和/或对生成的可执行文件使用
    objdump-d
    ,以获得操作码。在Linux上,您将为可执行文件编写自己的elf头,从而消除不必要的部分。这可能是我找到的最好的参考资料,最简单的?重新实现了
    true
    false
    。令人印象深刻。将其与NASM hello world的
    0x390
    字节进行比较。不推荐初学者使用:-)@ShankarDamodaran谢谢!已将TOC的改进版本上载到:并在此处进行了更新。感谢链接。我不知道这个答案怎么会被忽视。我忍不住要悬赏。太棒了。@ShankarDamodaran谢谢!这很可能是因为这是一个老问题的新答案。也许这个标题对于有机搜索来说措辞不太恰当。最重要的是:低级材料问题没有太多的代表性:-)@CiroSantilli,可以用较短的
    mov eax,1
    更改
    like指令,因为这将自动填充
    rax
    的0上半部分(寄存器将进行零扩展)。
    00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
    00000010  01 00 3e 00 01 00 00 00  00 00 00 00 00 00 00 00  |..>.............|
    00000020  00 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |........@.......|
    00000030  00 00 00 00 40 00 00 00  00 00 40 00 07 00 03 00  |....@.....@.....|
    
    00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
    00000010  02 00 3e 00 01 00 00 00  b0 00 40 00 00 00 00 00  |..>.......@.....|
    00000020  40 00 00 00 00 00 00 00  10 01 00 00 00 00 00 00  |@...............|
    00000030  00 00 00 00 40 00 38 00  02 00 40 00 06 00 03 00  |....@.8...@.....|
    
    typedef struct {
        unsigned char   e_ident[EI_NIDENT];
        Elf64_Half      e_type;
        Elf64_Half      e_machine;
        Elf64_Word      e_version;
        Elf64_Addr      e_entry;
        Elf64_Off       e_phoff;
        Elf64_Off       e_shoff;
        Elf64_Word      e_flags;
        Elf64_Half      e_ehsize;
        Elf64_Half      e_phentsize;
        Elf64_Half      e_phnum;
        Elf64_Half      e_shentsize;
        Elf64_Half      e_shnum;
        Elf64_Half      e_shstrndx;
    } Elf64_Ehdr;
    
    There are 7 section headers, starting at offset 0x40:
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .data             PROGBITS         0000000000000000  00000200
           000000000000000d  0000000000000000  WA       0     0     4
      [ 2] .text             PROGBITS         0000000000000000  00000210
           0000000000000027  0000000000000000  AX       0     0     16
      [ 3] .shstrtab         STRTAB           0000000000000000  00000240
           0000000000000032  0000000000000000           0     0     1
      [ 4] .symtab           SYMTAB           0000000000000000  00000280
           00000000000000a8  0000000000000018           5     6     4
      [ 5] .strtab           STRTAB           0000000000000000  00000330
           0000000000000034  0000000000000000           0     0     1
      [ 6] .rela.text        RELA             0000000000000000  00000370
           0000000000000018  0000000000000018           4     2     4
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
      I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
      O (extra OS processing required) o (OS specific), p (processor specific)
    
    typedef struct {
        Elf64_Word  sh_name;
        Elf64_Word  sh_type;
        Elf64_Xword sh_flags;
        Elf64_Addr  sh_addr;
        Elf64_Off   sh_offset;
        Elf64_Xword sh_size;
        Elf64_Word  sh_link;
        Elf64_Word  sh_info;
        Elf64_Xword sh_addralign;
        Elf64_Xword sh_entsize;
    } Elf64_Shdr;
    
    00000080  01 00 00 00 01 00 00 00  03 00 00 00 00 00 00 00  |................|
    00000090  00 00 00 00 00 00 00 00  00 02 00 00 00 00 00 00  |................|
    000000a0  0d 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    000000b0  04 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    
    00000200  48 65 6c 6c 6f 20 77 6f  72 6c 64 21 0a 00        |Hello world!..  |
    
    readelf -x .data hello_world.o
    
    Hex dump of section '.data':
      0x00000000 48656c6c 6f20776f 726c6421 0a       Hello world!.
    
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 2] .text             PROGBITS         0000000000000000  00000210
           0000000000000027  0000000000000000  AX       0     0     16
    
    objdump -d hello_world.o
    
    hello_world.o:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    0000000000000000 <_start>:
       0:       b8 01 00 00 00          mov    $0x1,%eax
       5:       bf 01 00 00 00          mov    $0x1,%edi
       a:       48 be 00 00 00 00 00    movabs $0x0,%rsi
      11:       00 00 00
      14:       ba 0d 00 00 00          mov    $0xd,%edx
      19:       0f 05                   syscall
      1b:       b8 3c 00 00 00          mov    $0x3c,%eax
      20:       bf 00 00 00 00          mov    $0x0,%edi
      25:       0f 05                   syscall
    
    movabs $0x0,%rsi
    
    4000ba: 48 be d8 00 60 00 00    movabs $0x6000d8,%rsi
    
    Data: \0 a b c \0 d e f \0
    Index: 0 1 2 3  4 5 6 7  8
    
    readelf -x .shstrtab hello_world.o
    
    Hex dump of section '.shstrtab':
      0x00000000 002e6461 7461002e 74657874 002e7368 ..data..text..sh
      0x00000010 73747274 6162002e 73796d74 6162002e strtab..symtab..
      0x00000020 73747274 6162002e 72656c61 2e746578 strtab..rela.tex
      0x00000030 7400                                t.
    
    nm hello_world.o
    
    0000000000000000 T _start
    0000000000000000 d hello_world
    000000000000000d a hello_world_len
    
    readelf -s hello_world.o
    
    Symbol table '.symtab' contains 7 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
         1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello_world.asm
         2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1
         3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2
         4: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 hello_world
         5: 000000000000000d     0 NOTYPE  LOCAL  DEFAULT  ABS hello_world_len
         6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    2 _start
    
    readelf -x .symtab hello_world.o
    
    Hex dump of section '.symtab':
      0x00000000 00000000 00000000 00000000 00000000 ................
      0x00000010 00000000 00000000 01000000 0400f1ff ................
      0x00000020 00000000 00000000 00000000 00000000 ................
      0x00000030 00000000 03000100 00000000 00000000 ................
      0x00000040 00000000 00000000 00000000 03000200 ................
      0x00000050 00000000 00000000 00000000 00000000 ................
      0x00000060 11000000 00000100 00000000 00000000 ................
      0x00000070 00000000 00000000 1d000000 0000f1ff ................
      0x00000080 0d000000 00000000 00000000 00000000 ................
      0x00000090 2d000000 10000200 00000000 00000000 -...............
      0x000000a0 00000000 00000000                   ........
    
    typedef struct {
        Elf64_Word  st_name;
        unsigned char   st_info;
        unsigned char   st_other;
        Elf64_Half  st_shndx;
        Elf64_Addr  st_value;
        Elf64_Xword st_size;
    } Elf64_Sym;
    
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1
      3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2
    
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      4: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 hello_world
      5: 000000000000000d     0 NOTYPE  LOCAL  DEFAULT  ABS hello_world_len
      6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    2 _start
    
    global _start
    
    readelf -x .strtab hello_world.o
    
    Hex dump of section '.strtab':
      0x00000000 0068656c 6c6f5f77 6f726c64 2e61736d .hello_world.asm
      0x00000010 0068656c 6c6f5f77 6f726c64 0068656c .hello_world.hel
      0x00000020 6c6f5f77 6f726c64 5f6c656e 005f7374 lo_world_len._st
      0x00000030 61727400                            art.
    
       a:       48 be 00 00 00 00 00    movabs $0x0,%rsi
      11:       00 00 00
    
    4000ba: 48 be d8 00 60 00 00    movabs $0x6000d8,%rsi
    4000c1: 00 00 00
    
    Relocation section '.rela.text' at offset 0x3b0 contains 1 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    00000000000c  000200000001 R_X86_64_64       0000000000000000 .data + 0
    
    00000370  0c 00 00 00 00 00 00 00  01 00 00 00 02 00 00 00  |................|
    00000380  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    
    typedef struct {
        Elf64_Addr  r_offset;
        Elf64_Xword r_info;
        Elf64_Sxword    r_addend;
    } Elf64_Rela;
    
    Elf file type is EXEC (Executable file)
    Entry point 0x4000b0
    There are 2 program headers, starting at offset 64
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                     0x00000000000000d7 0x00000000000000d7  R E    200000
      LOAD           0x00000000000000d8 0x00000000006000d8 0x00000000006000d8
                     0x000000000000000d 0x000000000000000d  RW     200000
    
     Section to Segment mapping:
      Segment Sections...
       00     .text
       01     .data
    
    00000040  01 00 00 00 05 00 00 00  00 00 00 00 00 00 00 00  |................|
    00000050  00 00 40 00 00 00 00 00  00 00 40 00 00 00 00 00  |..@.......@.....|
    00000060  d7 00 00 00 00 00 00 00  d7 00 00 00 00 00 00 00  |................|
    00000070  00 00 20 00 00 00 00 00                           |.. .....        |
    
    00000070                           01 00 00 00 06 00 00 00  |        ........|
    00000080  d8 00 00 00 00 00 00 00  d8 00 60 00 00 00 00 00  |..........`.....|
    00000090  d8 00 60 00 00 00 00 00  0d 00 00 00 00 00 00 00  |..`.............|
    000000a0  0d 00 00 00 00 00 00 00  00 00 20 00 00 00 00 00  |.......... .....|
    
    typedef struct {
        Elf64_Word  p_type;
        Elf64_Word  p_flags;
        Elf64_Off   p_offset;
        Elf64_Addr  p_vaddr;
        Elf64_Addr  p_paddr;
        Elf64_Xword p_filesz;
        Elf64_Xword p_memsz;
        Elf64_Xword p_align;
    } Elf64_Phdr;
    
     Section to Segment mapping: