hacktricks/forensics/basic-forensics-esp/.pyc.md

63 lines
2.3 KiB
Markdown

# .pyc
## Getting the code
For the .pyc binaries \("compiled" python\) you should start trying to **extract** the **original** **python** **code**:
```text
uncompyle6 binary.pyc > decompiled.py
```
**Be sure** that the binary has the **extension** "**.pyc**" \(if not, uncompyle6 is not going to work\)
After extracting it, it will be more easy to analyze.
## Analyzing python assembly
If you weren't able to extract the python "original" code following the previous steps, then you can try to **extract** the **assembly** \(but i**t isn't very descriptive**, so **try** to extract **again** the original code\).
In [here](https://bits.theorem.co/protecting-a-python-codebase/) I found a very simple code to **dissasemble** the _.pyc_ binary \(good luck understanding the code flow\). If the _.pyc_ is from python2, use python2:
```text
>>> import dis
>>> import marshal
>>> import struct
>>> import imp
>>>
>>> with open('hello.pyc', 'r') as f: # Read the binary file
... magic = f.read(4)
... timestamp = f.read(4)
... code = f.read()
...
>>>
>>> # Unpack the structure content and un-marshal the code
>>> magic = struct.unpack('<H', magic[:2])
>>> timestamp = struct.unpack('<I', timestamp)
>>> code = marshal.loads(code)
>>> magic, timestamp, code
((62211,), (1425911959,), <code object <module> at 0x7fd54f90d5b0, file "hello.py", line 1>)
>>>
>>> # Verify if magic number corresponds with the current python version
>>> struct.unpack('<H', imp.get_magic()[:2]) == magic
True
>>>
>>> # Disassemble the code object
>>> dis.disassemble(code)
1 0 LOAD_CONST 0 (<code object hello_world at 0x7f31b7240eb0, file "hello.py", line 1>)
3 MAKE_FUNCTION 0
6 STORE_NAME 0 (hello_world)
9 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>>
>>> # Also disassemble that const being loaded (our function)
>>> dis.disassemble(code.co_consts[0])
2 0 LOAD_CONST 1 ('Hello {0}')
3 LOAD_ATTR 0 (format)
6 LOAD_FAST 0 (name)
9 CALL_FUNCTION 1
12 PRINT_ITEM
13 PRINT_NEWLINE
14 LOAD_CONST 0 (None)
17 RETURN_VALUE
```