-
Notifications
You must be signed in to change notification settings - Fork 627
Extracting Linux ELF binaries
Pyinstxtractor as of now can natively extract Pyinstaller generated ELF binaries (in the same way as Windows exe) without requiring additional tools. However if you face any errors in the process you can follow the old way described below.
First you need to carve out a part of the ELF first.
Using objcopy
dump the section named pydata
to a file.
$ objcopy --dump-section pydata=pydata.dump testfile.elf
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
Use readelf
to list the section headers.
$ readelf -s testfile.elf
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=testfile.elf 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)); } <testfile.elf >pydata.dump
OR a tail
and head
.
$ tail -c +$((0x7a50+1)) testfile.elf | head -c $((0xa3b2b6)) >pydata.dump
You can now run pyinstxtractor on the dumped file.