Skip to content

Extracting Linux ELF binaries

extremecoders-re edited this page Apr 14, 2020 · 6 revisions

Pyinstxtractor can also extract Pyinstaller generated ELFs but you need to carve out a part of the ELF first.

The easy way

Using objcopy dump the section named pydata to a file.

$ objcopy --dump-section pydata=pydata-dump test

Now you can run pyinstxtractor on the dumped file.

$ python pyinstxtractor.py pydata-dump
[+] Processing pydata-dump
[+] Pyinstaller version: 2.1+
[+] Python version: 37
[+] Length of package: 10728118 bytes
[+] Found 52 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: test.pyc
[+] Found 133 files in PYZ archive
[+] Successfully extracted pyinstaller archive: pydata-dump

You can now use a python decompiler on the pyc files within the extracted directory

The long way

Use readelf to list the section headers.

$ readelf -s test
There are 29 section headers, starting at offset 0xa42e08:

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         0000000000400200  00000200
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             000000000040021c  0000021c
       0000000000000020  0000000000000000   A       0     0     4

--- [ snip ] ---

  [26] .comment          PROGBITS         0000000000000000  00007a10
       0000000000000040  0000000000000001  MS       0     0     1
  [27] pydata            PROGBITS         0000000000000000  00007a50
       0000000000a3b2b6  0000000000000000           0     0     1
  [28] .shstrtab         STRTAB           0000000000000000  00a42d06
       00000000000000ff  0000000000000000           0     0     1

Note the size and offset of the pydata section at the end. In this example, size=0xa3b2b6 and offset=0x7a50. Using the size and offset carve out the part.

$ dd if=test bs=1 skip=$((0x7a50)) count=$((0xa3b2b6)) of=pydata-dump

However this will run very slowly since the block size is 1.

Instead, you can split it into two head commands.

$ { head -c $((0x7a50)) >/dev/null; head -c $((0xa3b2b6)); } <test >pydata-dump

OR a tail and head.

$ tail -c +$((0x7a50+1)) test | head -c $((0xa3b2b6)) >pydata-dump

You can now run pyinstxtractor on the dumped file.

Clone this wiki locally