【Python3】Pyinstallerでexe化した.pyファイルをデコンパイルして中身を覗いてみる【uncompyle6】

Generative Art by Python3Python3

はいどーも、まるです。
最近、exe化したPythonファイルの中身を再編集しようとしたら、元のソースコードを見失ってしまい・・・。折角なのでデコンパイルして中身を取り出すことにしました。

元の手順である.pyファイルのexeアプリケーション化については、下記記事をご覧ください。

では早速中身を取り出していきましょう。

exeファイルのソースコードをPython3にデコンパイルする方法

python-exe-unpacker のダウンロード

こちら(公式サイト)より、デコンパイルに必要なモジュールをダウンロードします。

ダウンロードしたら、Desktopなどターミナルから開きやすいパスに置きましょう。

この中のpyinstxtractor.py をダウンロードを使っていきます。

exe ファイルの展開

cmdを開き、以下コマンドでexeファイルの中身を展開していきます。

python pyinstxtractor.py ○○.exe
Code language: CSS (css)

※この時、pyinstxtractor.pyと○○.exe それぞれカレントディレクトリにない場合は適宜パスを指定してください。

うまいくいけば同ディレクトリに、「○○.exe_extracted」というフォルダが生成されます。

拡張子の追加

「○○.exe_extracted」フォルダの中の○○ファイル(拡張子なし)に、.pycと拡張子を追加します。

.pyc拡張子ファイルはコンパイルした結果のバイトコードのキャッシュを記載するファイルです。
Python3では、__pycache__というディレクトリが自動的に生成されてその中に.pycファイルが作成されるようになっています。詳しくはこちらのサイトをご覧ください。⇒ __pycache__と.pycファイル

欠損したヘッダの補完

続いて、○○.pyc ファイルをバイナリエディタで開きます。

バイナリエディタとは、2bit毎に配列されたデータ形式で、ファイルを開く(編集する)ソフトの事です。少し古いですが、私はStirlingというフリーエディタを使用しています。誰か何か推しあったら教えてください

まだ持っていなかったら、インストールしましょう。(フリーソフトで十分です)

この.pyc ファイルの先頭には本来、exeにパッケージングした際のPythonのバージョン情報と、タイムスタンプ等が埋め込まれています。が、今回のやり方で展開した場合、それがありません。

これらがないと、次のデコンパイルする作業で

ValueError: bad marshal data (unknown type code)
Code language: HTTP (http)

と怒られてしまいます。ファイル情報が不正と見なされ、デコンパイル出来ません。

続いて先頭を補足していきます。


0x00~0x01にはPythonのバージョンを示すマジックナンバーを、
0x02~0x03には 0x0D 0x0A の固定値を入れていきます。

後続の部分はネット上の記事によって、32bit(4byte)埋めたり16bit(8byte)だったりして上記エラーが出てうまくいかなかったので以下私のやり方を紹介。

作業するディレクトリ(どこでもいいです)に hoge.py を作成。

次に、デコンパイルしたいVerのPython(.exeのプロパティより確認出来ます)を対話型シェルなどで実行し、

import py_compile
python -m py_compile hoge.py 

と入力。hoge.py と同ディレクトリに、__pycache__というディレクトリが作成されその中に.pycファイルが出来ています。

そちらをStirling等のテキストエディタで開き、
先頭を確認します。

私の場合、以下のような表記になっていました。ここは人によって異なるので気を付けてください。

33 0D 0D 0A B5 D6 DE 9E 7U BE 4L 2C E3 00 00 00

続いて先頭が抜け落ちている○○.pycのほうを見ると、

E3 00 00 00 ..

と始まっています。なので、先頭に抜け落ちた部分をInsertで置き換えでなく挿入していきます。

ここも、間違えて16bit埋めようと残り8bitに 00 00 00 00 を入れて、E3が2行目の先頭に来るようにしたりすると動かなくなるので注意してください。

これでコードの補完は完了です。

uncompyle6 のインストール

pip install uncompyle6

にて、デコンパイラをインストールします。

 デコンパイル

該当ディレクトリにて

uncompyle6 ○○.pyc > kai.py

とすると、同一ディレクトリに kai.py ファイルが作成されます。

~エラーが出てうまくいかない場合~

ここで

ValueError: bad marshal data (unknown type code)
Code language: HTTP (http)

というエラーが出る場合、ヘッダの補完に失敗しています。

リトルエンディアンとビッグエンディアンを間違えていないか、
解凍したいexeファイルのPythonバージョンとマジックナンバー、入力bit数や入れ方の間違いがないか、いま一度確認してみましょう。

↓こちらの記事で起動しているPythonバージョンのマジックナンバーを確認する方法もご紹介しています。参考にご覧ください。

【.pyc】現行のPythonバージョンのマジックナンバーを求める方法
Pythonにはバージョンごとに、8bit(1Byte)で構成されるバージョン情報が存在しています。これらはマジックナンバーと呼ばれています。普段あまり気にする機会はないかもしれませんが、今日はこのマジックナンバーの調べ方を紹介し...

ソースコードのチェック


では、VS Codeなどのコードエディタで中身を確認してみましょう!
無事、ソースコードが復号されていますね!!お疲れ様でした。

(参考)

pyinstallerで作成されたexeをデコンパイルする方法
PYTHON製マルウェアをデコンパイルしてみたら、珍しい子だった件

まる。

Python歴3年のフルスタックエンジニア兼ブロガー兼ヨギー。大学は心理学、趣味はヨガ。
名刺・HP制作やハタヨガレッスンやってます。

まる。をフォローする
タイトルとURLをコピーしました