[Python] PyInstaller로 컴파일한 코드를 decompyle3로 디컴파일 하기
카테고리: Python
PyInstaller
PyInstaller는 Python 애플리케이션과 모든 종속 요소를 단일 패키지로 묶는 소프트웨어이다. 이를 통해 프로그램 사용자는 파이썬 인터프리터나 모듈을 설치하지 않고도 프로그램을 실행할 수 있다. PyInstaller는 Python 3.8 이상을 지원하며 numpy, matplotlib, PyQt, wxPython 등과 같은 많은 주요 Python 라이브러리들을 패키징한다.
※ 해당 프로그램이 무엇으로 패킹 되었는지는 Exeinfo PE를 사용하여 확인한다.
언패킹
python-exe-unpacker 스크립트를 사용하여 PyInstaller로 묶인 파일들을 언패킹해준다.
git clone https://github.com/countercept/python-exe-unpacker
cd python-exe-unpacker
python3 -m pip install -r requirements.txt
python3 python_exe_unpack.py -i 파일명.exe
[*] On Python 3.10
[*] Processing file.exe
[*] Pyinstaller version: 2.1+
[*] This exe is packed using pyinstaller
[*] Unpacking the binary now
[*] Python version: 308
[*] Length of package: 82331858 bytes
[*] Found 1138 files in CArchive
[*] Beginning extraction...please standby
[!] Warning: The script is running in a different python version than the one used to build the executable
Run this script in Python308 to prevent extraction errors(if any) during unmarshalling
[*] Found 1099 files in PYZ archive
[*] Successfully extracted pyinstaller exe.
언패킹을 완료하면 unpacked/파일명.exe 폴더가 생기며 .exe 내부의 파일들이 저장된다.
파일 정리
아래의 파일을 삭제하면 분석하기 쉽다.
- tcl이나 tk로 시작하는 파일
- .dll 파일
- .pyd 파일
매직 넘버
PyInstaller가 패키징하는 과정에서 메인 파일(보통 파일 명으로 되어 있으며, 파일 확장자가 없음)의 헤더에 해당하는 Python magic number라는 값을 제거한다. 하지만, 이는 base_library.zip의 다른 파일들을 바탕으로 복구할 수 있다.
다른 파일들을 확인한 결과 첫 줄의 55 0D 0D 0A 01 00 00 00 00 00 00 00 00 00 00 00을 메인 파일에 추가해줘야 한다. 아래와 같이 매직 넘버를 추가하고 파일 확장자를 .pyc로 바꾸고 저장한다.
※ 프로그램마다 상이하므로, 꼭 확인하고 매직 넘버를 수정해야한다.
디컴파일
pip install decompyle3
decompyle3 파일명.pyc > 파일명.py
디컴파일한 결과인 파일명.py를 열어보면 아래와 같이 원본과 비슷하게 복원되었음을 알 수 있다.
참고
https://github.com/ExeinfoASL/ASL/releases/tag/exeinfo
https://github.com/rocky/python-decompile3
https://item4.blog/2018-11-04/Extract-Python-Code-from-PyInstaller-EXE-File/
https://jaehoney.tistory.com/72
https://lemongreen.tistory.com/3