ELF文件格式一例分析

ELF文件格式一例分析:以nasm生成一尽量小的ELF文件,以二进制方式,以objdump方式,以readelf方式,分析加载入内存及运行规律,得出结论。 编辑一个小的asm文件如下:
crq@ $ cat new18.asm
global _start

_start:
        ud0
        ud1
        ud2
很简单,只有 ud0, ud1, ud2 三个指令,都是产生非法 Opcode 码所用。编译生成ELF如下:
crq@ $ nasm -f elf new18.asm
crq@ $ ld new18.o
这样就生成了a.out是ELF格式文件,再使用objcopy除去无关紧要的节:
crq@ $ objcopy -S -R .comment -R .bss a.out
运行:
crq@ $ ./a.out
Illegal instruction
果如所料,程序接收到一个 SIGILL 信号默认动作是被 kill 掉了,再使用 objdump 反汇编一下:
crq@ $ objdump -d a.out

a.out:     file format elf32-i386

Disassembly of section .text:

08048080 <.text>:
 8048080:       0f ff                   (bad)
 8048082:       0f b9                   ud2b
 8048084:       0f 0b                   ud2a
正文段只有三行汇编语言指令。文件大小:
crq@ $ ls -l a.out
-rwxr-xr-x    1 crq      users         272 Nov 22 09:22 a.out
剩余 272 Bytes. 再使用 readelf 分析:
crq@ $ readelf -a a.out
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:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8048080
  Start of program headers:          52 (bytes into file)
  Start of section headers:          152 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         1
  Size of section headers:           40 (bytes)
  Number of section headers:         3
  Section header string table index: 2

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        08048080 000080 000006 00  AX  0   0 16
  [ 2] .shstrtab         STRTAB          00000000 000086 000011 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x00086 0x00086 R E 0x1000

 Section to Segment mapping:
  Segment Sections...
   00     .text

There is no dynamic segment in this file.

There are no relocations in this file.

There are no unwind sections in this file.

No version information found in this file.
ELF Header部分正常,Section Headers中有三项,第一项按惯例为空的。 Program Headers只有一项。再印出二进制码如下:
crq@ $ hexdump -C a.out
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  80 80 04 08 34 00 00 00  |............4...|
00000020  98 00 00 00 00 00 00 00  34 00 20 00 01 00 28 00  |........4. ...(.|
00000030  03 00 02 00 01 00 00 00  00 00 00 00 00 80 04 08  |................|
00000040  00 80 04 08 86 00 00 00  86 00 00 00 05 00 00 00  |................|
00000050  00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000080  0f ff 0f b9 0f 0b 00 2e  73 68 73 74 72 74 61 62  |........shstrtab|
00000090  00 2e 74 65 78 74 00 00  00 00 00 00 00 00 00 00  |..text..........|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000c0  0b 00 00 00 01 00 00 00  06 00 00 00 80 80 04 08  |................|
000000d0  80 00 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |................|
000000e0  10 00 00 00 00 00 00 00  01 00 00 00 03 00 00 00  |................|
000000f0  00 00 00 00 00 00 00 00  86 00 00 00 11 00 00 00  |................|
00000100  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00000110
0x000~0x034 是 ELF Header; 0x034~0x054 是一项Program Headers; 0x054~0x080 是填充零字节; 0x080~0x086 是 .text 段内容; 0x086~0x098 是 .shstrtab 段内容; 0x098~0x110 是三项Section Headers; 对照 elf.h 文件分析如下:
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  80 80 04 08 34 00 00 00  |............4...|
00000020  98 00 00 00 00 00 00 00  34 00 20 00 01 00 28 00  |........4. ...(.|
00000030  03 00 02 00                                       |....            |

typedef struct elf32_hdr {
  unsigned char e_ident[EI_NIDENT];
  Elf32_Half    e_type;
  Elf32_Half    e_machine;
  Elf32_Word    e_version;
  Elf32_Addr    e_entry;  /* Entry point */
  Elf32_Off     e_phoff;
  Elf32_Off     e_shoff;
  Elf32_Word    e_flags;
  Elf32_Half    e_ehsize;
  Elf32_Half    e_phentsize;
  Elf32_Half    e_phnum;
  Elf32_Half    e_shentsize;
  Elf32_Half    e_shnum;
  Elf32_Half    e_shstrndx;
} Elf32_Ehdr;
其中 ELF32_Half 是16位,其余类型 ELF32_Word, ELF32_Addr, ELF32_Off 等都是32位。 宏 EI_NIDENT 定义为 16,即 ELF Header 头部有16Bytes特征字节。
00000030              01 00 00 00  00 00 00 00 00 80 04 08  |    ............|
00000040  00 80 04 08 86 00 00 00  86 00 00 00 05 00 00 00  |................|
00000050  00 10 00 00                                       |....            |

typedef struct elf32_phdr{
  Elf32_Word    p_type;
  Elf32_Off     p_offset;
  Elf32_Addr    p_vaddr;
  Elf32_Addr    p_paddr;
  Elf32_Word    p_filesz;
  Elf32_Word    p_memsz;
  Elf32_Word    p_flags;
  Elf32_Word    p_align;
} Elf32_Phdr;
00000080  0f ff 0f b9 0f 0b                                 |......          |
00000080                    00 2e  73 68 73 74 72 74 61 62  |      ..shstrtab|
00000090  00 2e 74 65 78 74 00 00                           |..text..        |
00000090                           00 00 00 00 00 00 00 00  |        ........|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

000000c0  0b 00 00 00 01 00 00 00  06 00 00 00 80 80 04 08  |................|
000000d0  80 00 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |................|
000000e0  10 00 00 00 00 00 00 00                           |........        |

000000e0                           01 00 00 00 03 00 00 00  |        ........|
000000f0  00 00 00 00 00 00 00 00  86 00 00 00 11 00 00 00  |................|
00000100  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|

typedef struct {
  Elf32_Word    sh_name;
  Elf32_Word    sh_type;
  Elf32_Word    sh_flags;
  Elf32_Addr    sh_addr;
  Elf32_Off     sh_offset;
  Elf32_Word    sh_size;
  Elf32_Word    sh_link;
  Elf32_Word    sh_info;
  Elf32_Word    sh_addralign;
  Elf32_Word    sh_entsize;
} Elf32_Shdr;
又查阅 nasmdoc.txt 一文中对这三个 UD 指令的描述如下:
B.4.320 `UD0', `UD1', `UD2': Undefined Instruction

       UD0                           ; 0F FF                [186,UNDOC] 
       UD1                           ; 0F B9                [186,UNDOC] 
       UD2                           ; 0F 0B                [186]

       `UDx' can be used to generate an invalid opcode exception, for
       testing purposes.

       `UD0' is specifically documented by AMD as being reserved for this
       purpose.

       `UD1' is documented by Intel as being available for this purpose.

       `UD2' is specifically documented by Intel as being reserved for this
       purpose. Intel document this as the preferred method of generating
       an invalid opcode exception.

       All these opcodes can be used to generate invalid opcode exceptions
       on all currently available processors.
有趣的是,注意 objdump 的这一段输出:
 8048080:       0f ff                   (bad)
 8048082:       0f b9                   ud2b
 8048084:       0f 0b                   ud2a
在 nasm 中的三条合法指令在 GNU as 中是只有两条合法的,并且名称也不相同,ud2a 和 ud2b,三条用途都是产生 opcode 异常。


 

Tags: ELF Linux assembly

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值