mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-16 01:38:20 +00:00
63 lines
2.3 KiB
Markdown
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
|
|
```
|
|
|