Update .pyc.md

This commit is contained in:
Taleb Qasem 2022-09-10 22:16:16 +06:00 committed by GitHub
parent dbc6540ab4
commit 9f27afdedf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -30,7 +30,7 @@ From an **ELF** compiled binary you can **get the .pyc** with:
```bash
pyi-archive_viewer <binary>
# The list of python modules will be given like here:
# The list of python modules will be given here:
[(0, 230, 311, 1, 'm', 'struct'),
(230, 1061, 1792, 1, 'm', 'pyimod01_os_path'),
(1291, 4071, 8907, 1, 'm', 'pyimod02_archive'),
@ -47,7 +47,7 @@ pyi-archive_viewer <binary>
to filename? /tmp/binary.pyc
```
In an **python exe binary** compiled you can **get the .pyc** by running:
In a **python exe binary** compiled you can **get the .pyc** by running:
```bash
python pyinstxtractor.py executable.exe
@ -72,9 +72,9 @@ While executing **uncompyle6** you might find the **following errors**:
Unknown magic number 227 in /tmp/binary.pyc
```
In order to fix this you need to **add the correct magic number** at the begging of the generated fil.
To fix this you need to **add the correct magic number** at the beginning of the generated file.
**Magic numbers vary with the python version**, to get the magic number of **python3.8** you will need to **open a python3.8** terminal and execute:
**Magic numbers vary with the python version**, to get the magic number of **python 3.8** you will need to **open a python 3.8** terminal and execute:
```
>> import imp
@ -86,7 +86,7 @@ The **magic number** in this case for python3.8 is **`0x550d0d0a`**, then, to fi
**Once** you have **added** that magic header, the **error should be fixed.**
This is how a correctly added **.pyc python3.8 magic header** will looks like:
This is how a correctly added **.pyc python3.8 magic header** will look like:
```bash
hexdump 'binary.pyc' | head
@ -106,13 +106,13 @@ Check the previous error documentation.
## Automatic Tool
The tool [https://github.com/countercept/python-exe-unpacker](https://github.com/countercept/python-exe-unpacker) glues together several tools available to the community that **helps researcher to unpack and decompile executable** written in python (py2exe and pyinstaller).
The tool [https://github.com/countercept/python-exe-unpacker](https://github.com/countercept/python-exe-unpacker) glues together several tools available to the community that **help researchers to unpack and decompile executable** written in python (py2exe and pyinstaller).
Several YARA rules are available to determine if the executable is written in python (This script also confirms if the executable is created with either py2exe or pyinstaller).
### ImportError: File name: 'unpacked/malware\_3.exe/**pycache**/archive.cpython-35.pyc' doesn't exist
Currently with unpy2exe or pyinstxtractor the Python bytecode file we get might not be complete and in turn it **cant be recognized by uncompyle6 to get the plain Python source code**. This is caused by a missing Python **bytecode version number**. Therefore we included a prepend option; this will include a Python bytecode version number into it and help to ease the process of decompiling. When we try to use uncompyle6 to decompile the .pyc file it returns an error. However, **once we use the prepend option we can see that the Python source code has been decompiled successfully**.
Currently, with unpy2exe or pyinstxtractor the Python bytecode file we get might not be complete and in turn, it **cant be recognized by uncompyle6 to get the plain Python source code**. This is caused by a missing Python **bytecode version number**. Therefore we included a prepend option; this will include a Python bytecode version number into it and help to ease the process of decompiling. When we try to use uncompyle6 to decompile the .pyc file it returns an error. However, **once we use the prepend option we can see that the Python source code has been decompiled successfully**.
```
test@test: uncompyle6 unpacked/malware_3.exe/archive.py
@ -124,7 +124,7 @@ ImportError: File name: 'unpacked/malware_3.exe/__pycache__/archive.cpython-35.p
```
test@test:python python_exe_unpack.py -p unpacked/malware_3.exe/archive
[*] On Python 2.7
[+] Magic bytes is already appeneded.
[+] Magic bytes are already appended.
# Successfully decompiled file
[+] Successfully decompiled.
@ -132,7 +132,7 @@ test@test:python python_exe_unpack.py -p unpacked/malware_3.exe/archive
## 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:
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 **disassemble** the _.pyc_ binary (good luck understanding the code flow). If the _.pyc_ is from python2, use python2:
```bash
>>> import dis
@ -146,14 +146,14 @@ If you weren't able to extract the python "original" code following the previous
... code = f.read()
...
>>>
>>> # Unpack the structure content and un-marshal the code
>>> # Unpack the structured 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
>>> # Verify if the magic number corresponds with the current python version
>>> struct.unpack('<H', imp.get_magic()[:2]) == magic
True
>>>
@ -179,12 +179,12 @@ True
## Python to Executable
To start off were going to show you how payloads can be compiled in py2exe and PyInstaller.
To start, were going to show you how payloads can be compiled in py2exe and PyInstaller.
### To create a payload using py2exe:
1. Install the py2exe package from [http://www.py2exe.org/](http://www.py2exe.org)
2. For the payload (in this case, we will name it hello.py), use a script like the one in Figure 1. The option “bundle\_files” with the value of 1 will bundle everything including Python interpreter into one exe.
2. For the payload (in this case, we will name it hello.py), use a script like the one in Figure 1. The option “bundle\_files” with the value of 1 will bundle everything including the Python interpreter into one exe.
3. Once the script is ready, we will issue the command “python setup.py py2exe”. This will create the executable, just like in Figure 2.
```