如果通常可以使用readelf读取的ELF标头已经过手动操作,则可以说,通过增加“节标头的大小”的值,仍可以执行该二进制文件,并且效果很好。

这种操作似乎触发了GDC和GDB之类的逆向工程工具,给了我错误:not in executable format: File format not recognized

是否有一种方法可以修复ELF头文件,而无需知道其中的“节头的大小”的原始值。为了能够再次使用标准工具分析文件?

详细信息:

GDB无法运行二进制文件,因为它表示文件为not in executable format : File format not recognized,但可以在外部运行GDB。 libbfd解析器发生相同的事情,由于无法识别文件格式,因此无法解析。事实是我只更改了节标题的数量。 。

之前的ELF标头

#include <stdio.h>

int main()
{
    printf("Hello World!\n");
    return 0;
}


后面的ELF标头

$ readelf -h hello
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:               0x8048320
  Start of program headers:          52 (bytes into file)
  Start of section headers:          4472 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         9
  Size of section headers:           40 (bytes)
  Number of section headers:         30 <-- notice me!
  Section header string table index: 27


GDB将输出,


不是可执行文件格式:无法识别文件格式


但是如果我在GDB之外运行, br />
$ readelf -h hello
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:               0x8048320
  Start of program headers:          52 (bytes into file)
  Start of section headers:          4472 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         9
  Size of section headers:           40 (bytes)
  Number of section headers:         52 <-- already changed!
  Section header string table index: 27


那么,有没有一种方法可以在不知道正确值的情况下修复make hello的值,或者可以通过一种解决方法来在GDB中调试此文件?

#1 楼

在这种特殊情况下,可以自动修复接头。由于存在节标题字符串表,因此可以通过计算表中的字符串数来找到e_shnum的原始值。

原始值:
损坏:

$ readelf -h hello
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:                              DYN (Shared object file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x3e0
  Start of program headers:          52 (bytes into file)
  Start of section headers:          6056 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         9
  Size of section headers:           40 (bytes)
  Number of section headers:         29  <-----------------
  Section header string table index: 28


读取节标题字符串表:


$ readelf -h hello
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:                              DYN (Shared object file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x3e0
  Start of program headers:          52 (bytes into file)
  Start of section headers:          6056 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         9
  Size of section headers:           40 (bytes)
  Number of section headers:         52  <------------------
  Section header string table index: 28
readelf: Error: Reading 2080 bytes extends past end of file for section headers
readelf: Error: Reading 7216 bytes extends past end of file for dynamic string table


>
在带有损坏的标头的二进制文件上运行时,输出如下:

#!/usr/bin/python3

from elftools.elf.elffile import ELFFile

with open('hello', 'rb') as f:
    elffile = ELFFile(f)
    print("original e_shnum:\t" + str(len(elffile.get_section(28).data().decode('ascii').split('\x00')) + 1))



#2 楼

我重新创建了二进制文件,然后使用Radare像完全一样破坏了标头,将节头的数量更改为52。

readelf的调用。

r2 -w a.out -1c's 0; pfo elf64; .pf.elf_header.shnum=52'


但是我从GDB得到了类似的错误, br />

而且,如果我尝试调试该文件,则会得到


没有指定可执行文件。


我可以轻松地使用

$ readelf -h a.out 
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1050
  Start of program headers:          64 (bytes into file)
  Start of section headers:          14624 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         11
  Size of section headers:           64 (bytes)
  Number of section headers:         52
  Section header string table index: 28
readelf: Error: Reading 3328 bytes extends past end of file for section headers


但是要回答有关工具的问题,即使标头设置为52也可以使用它。您仍然可以调试它。

如果标头小于原始shnum,则可以使gdb工作,例如将其设置为1只会发出警告您,


BFD:警告:/tmp/a.out的字符串表索引已损坏-忽略


,但是您仍然可以调试编ram。