HexHive / retrowrite

RetroWrite -- Retrofitting compiler passes through binary rewriting
Other
664 stars 77 forks source link

Add support for binaries with MiniDebugInfo/.gnu_debugdata section #25

Open impost0r opened 3 years ago

impost0r commented 3 years ago

Initial reference: https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html

LZMA compressed debug symbols can often be found in binaries (particularly CentOS, to my experience), in the .gnu_debugdata segment. The ability to support these would expand the capabilities of retrowrite greatly, though it doesn't seem that I don't believe elftools has support for the .gnu_debugdata segment. Anyhow, as seen in the screenshot attached, this provides almost full debug info for a binary once parsed -- the issue is, of course, de-compressing the symbols and applying them. I'm not the greatest Python developer (I've started thinking more in C than in Python), so I leave this as a suggestion/feature request.

An example from the readelf tool.

[user@CentOS-F5 bin]$ readelf -e telnet
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:               0x4b19
  Start of program headers:          64 (bytes into file)
  Start of section headers:          99912 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000000238  00000238
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000000254  00000254
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.bu[...] NOTE             0000000000000274  00000274
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000000298  00000298
       0000000000000038  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           00000000000002d0  000002d0
       00000000000009f0  0000000000000018   A       6     2     8
  [ 6] .dynstr           STRTAB           0000000000000cc0  00000cc0
       0000000000000421  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           00000000000010e2  000010e2
       00000000000000d4  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          00000000000011b8  000011b8
       0000000000000080  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000001238  00001238
       0000000000002748  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             0000000000003980  00003980
       0000000000000828  0000000000000018  AI       5    12     8
  [11] .init             PROGBITS         00000000000041a8  000041a8
       000000000000001a  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         00000000000041d0  000041d0
       0000000000000580  0000000000000010  AX       0     0     16
  [13] .text             PROGBITS         0000000000004750  00004750
       000000000000bad2  0000000000000000  AX       0     0     16
  [14] .fini             PROGBITS         0000000000010224  00010224
       0000000000000009  0000000000000000  AX       0     0     4
  [15] .rodata           PROGBITS         0000000000010230  00010230
       0000000000002cb0  0000000000000000   A       0     0     8
  [16] .eh_frame_hdr     PROGBITS         0000000000012ee0  00012ee0
       00000000000005a4  0000000000000000   A       0     0     4
  [17] .eh_frame         PROGBITS         0000000000013488  00013488
       0000000000001ef4  0000000000000000   A       0     0     8
  [18] .init_array       INIT_ARRAY       0000000000215a90  00015a90
       0000000000000008  0000000000000000  WA       0     0     8
  [19] .fini_array       FINI_ARRAY       0000000000215a98  00015a98
       0000000000000008  0000000000000000  WA       0     0     8
  [20] .jcr              PROGBITS         0000000000215aa0  00015aa0
       0000000000000008  0000000000000000  WA       0     0     8
  [21] .data.rel.ro      PROGBITS         0000000000215aa8  00015aa8
       0000000000000008  0000000000000000  WA       0     0     8
  [22] .dynamic          DYNAMIC          0000000000215ab0  00015ab0
       0000000000000220  0000000000000010  WA       6     0     8
  [23] .got              PROGBITS         0000000000215cd0  00015cd0
       0000000000000330  0000000000000008  WA       0     0     8
  [24] .data             PROGBITS         0000000000216000  00016000
       0000000000001ac8  0000000000000000  WA       0     0     32
  [25] .bss              NOBITS           0000000000217ae0  00017ac8
       000000000000cf48  0000000000000000  WA       0     0     32
  [26] .gnu_debuglink    PROGBITS         0000000000000000  00017ac8
       0000000000000014  0000000000000000           0     0     4
  [27] .gnu_debugdata    PROGBITS         0000000000000000  00017adc
       0000000000000a58  0000000000000000           0     0     1
  [28] .shstrtab         STRTAB           0000000000000000  00018534
       0000000000000111  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000001f8 0x00000000000001f8  R E    0x8
  INTERP         0x0000000000000238 0x0000000000000238 0x0000000000000238
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x000000000001537c 0x000000000001537c  R E    0x200000
  LOAD           0x0000000000015a90 0x0000000000215a90 0x0000000000215a90
                 0x0000000000002038 0x000000000000ef98  RW     0x200000
  DYNAMIC        0x0000000000015ab0 0x0000000000215ab0 0x0000000000215ab0
                 0x0000000000000220 0x0000000000000220  RW     0x8
  NOTE           0x0000000000000254 0x0000000000000254 0x0000000000000254
                 0x0000000000000044 0x0000000000000044  R      0x4
  GNU_EH_FRAME   0x0000000000012ee0 0x0000000000012ee0 0x0000000000012ee0
                 0x00000000000005a4 0x00000000000005a4  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x0000000000015a90 0x0000000000215a90 0x0000000000215a90
                 0x0000000000000570 0x0000000000000570  R      0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .init_array .fini_array .jcr .data.rel.ro .dynamic .got .data .bss 
   04     .dynamic 
   05     .note.ABI-tag .note.gnu.build-id 
   06     .eh_frame_hdr 
   07     
   08     .init_array .fini_array .jcr .data.rel.ro .dynamic .got 

As you'll see from the readelf output, there also exists the issue of lacking a proper section-to-segment mapping for .gnu_debugdata. I believe the issue may be able to be solved with a fork of PyELFTools, though that's up to you all as it would complicate installation.

Screen Shot 2021-05-05 at 5 05 21 PM

Regards,

impost0r