Etc./Python, PHP, ...

PyInstaller로 만든 exe를 py로 디컴파일 ! [ python 3.8 ]

JaeHoney 2021. 2. 8. 19:42

디컴파일을 해야할 일이 생겼는데, 구글링으로 찾은 결과는 전부 uncompyle6을 이용해서 pyc에서 소스를 뽑아내고 있었습니다.

 

저는 그 방법으로는 도저히 해결되지 않아서 관련 이슈를 찾아보다가 아래와 같은 설명문을 발견했습니다.

 

 

python 3.7 이상 버전에서는 Uncompyle6은 많은 문제가 발생하고, decompile3을 권장한다는 내용이었습니다.

사용법이 크게 다르진 않지만, decompile3을 다루는 포스팅이 거의 없어서 도움이 되고자 올렸습니다.

 


$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py.
$ python get-pip.py.

먼저 pip를 설치해야합니다. 이때 정상적이라면 설치하는 내용이 길게 출력될 것입니다.

 

만약 그냥 python. 또는 python 명령어를 찾을 수 없다. pip 명령어를 찾을 수 없다는 내용이 나오면 환경변수 Path에 파이썬 폴더와 파이썬/Scripts 폴더를 추가하셔야합니다.

 

어렵거나 잘 안되시는 분들은 설치할 때 Path를 자동으로 추가하도록 하는 체크박스가 있기 때문에, 설치된 python을 전부 지우시고 새로 설치하시길 권장드립니다.

# Linux
pip install --upgrade pip
# Windows
python -m pip install --upgrade pip

만약 pip가 구버전이라면 위 명령어로 최신버전으로 업데이트합니다.


https://sourceforge.net/projects/pyinstallerextractor/

위 경로에서 pyinstxtractor.py를 다운받습니다. exe에서 pyc를 추출하는 역할을 합니다.

python pyinstxtractor.py 파일명.exe

그러면 파일명.exe_extracted라는 폴더가 생성 됩니다. 눈여겨볼 파일은 아래 두 파일입니다.

test는 제가 돌린 파일명이 test.exe라서 test로 나오는 것입니다. 기존 파일명을 갖는 확장자가 없는 파일을 찾으시면 됩니다.

 

1. test파일을 이름바꾸기로 .pyc를 추가합니다.

2. base_library.zip에 있는 pyc파일을 아무거나 두 개를 골라서 가져옵니다.

3. 3개의 파일을 한 폴더에 보관합니다. (편의상)

 


base_library.zip에서 pyc파일을 두 개 가져온 이유는 pyinstaller는 py를 exe로 만들 때 Masic Number를 지워버립니다. 

 

즉, 지금 test.pyc에서는 Masic Number가 없는 상태고, Masic Number가 있어야 py파일로 디컴파일이 가능합니다. Masic Number가 있는 pyc파일을 두 개를 비교해서 Masic Number를 찾아서 test.pyc에 넣어줘야합니다.

https://mh-nexus.de/en/hxd/

위 링크로 가셔서 Hex Editor를 다운받습니다.

zip에서 얻은 pyc를 두개 까서 첫줄을 복사해서 메모장에 메모해둡니다.

공통점은 42 0D 0D 0A 01 00 00 00까지 입니다. 나머지를 전부 00으로 수정합니다.

 

그러면 42 0D 0D 0A 01 00 00 00 00 00 00 00 00 00 00 00가 됩니다. 드래그하고 복사합니다.

 

test.pyc를 까면 이렇게 나옵니다. 첫부분에 아까 복사한 부분을 붙혀넣습니다. 파일 크기를 변경하는데 괜찮냐고 물으면 예를 클릭합니다.

이제 저장합니다.


남은건 decompile 입니다.

https://github.com/rocky/python-decompile3

여기서 zip을 다운받은 후에 알집을 풀고 그 폴더로 갑니다.

pip install -e 
python setup.py install

알집에 있는 setup.py로 decompile3을 설치합니다.

 

그리고 아까 test.pyc가 있는 폴더로 가서 아래의 명령어를 입력합니다.

decompyle3 test.pyc

그러면 아래와 같이 원본의 소스 코드가 출력됩니다. (+ decompile 관련 주석)

이 소스를 그대로 py파일로 만드려면 아래의 명령어를 입력합니다.

decompyle3 test.pyc > test.py

 

무사히 나온 소스(py)의 모습입니다.

 

궁금하신 것은 질문해주세요.

 

 

-----------------------------------------

 

 

 

*  추가

 

Q. github에서 zip파일을 어떻게 받으면 되나요.

 

A. 개발 블로그이다 보니, github에 관한 설명은 '개발자'에게는 기본이라 배제했네요. 아래와 같이 하시면 됩니다.