- Disassembler
- A disassembler is a software tool which transforms machine code into a human readable mnemonic representation called assembly language.
- Decompiler
- Software used to revert the process of compilation. Decompiler takes a binary program file as input and output the same program expressed in a structured higher-level language.
這裡就不說明 python 的編譯、執行方法
可以上網找找 pyc, pyo 的資料,他們說明的都比我清楚
一、開始囉
Python 的反編譯方法相當地簡單,網路上可以找到很多現成的工具它們可以把編譯好的 pyc, pyo,還原為原始碼 py
而 Pyinstaller 可以將 pyc 打包成一個可執行檔,也可以增加了一些反編譯的難度
下圖是我用 7z 打開在 linux 使用 Pyinstaller 包好的執行檔的樣子…
在 linux 跑執行檔時,它會將打包的檔案解開放到 _MEIxxxxxx 的暫存資料夾
然後再進行執行,故會多出解壓縮的時間
如果你認為這樣就已經把執行檔解開了,那就太天真了
我們是RD,一定要用聰明一點的方法
二、利用 archive_viewer.py
Pyinstaller 有提供方便的作法,讓我們大家節省了很多時間記得要下載新的版本,不然 archive_viewer.py 程式可能就會說版本不支援
既然是使用 Pyinstaller 打包程式,那麼使用它所提供的 Tools 當然是得心應手
我沒有用它去打開像是 py2exe 打包的執行檔,不知道能不能通用 (但我想是不行)
操作上不難,直接打指令
# help python archive_viewer.py # view python archive_viewer.py pyi_archive
上圖利用 archive_viewer.py 成功打開了執行檔
有 4 個指令可以使用
U : 回到上一層
O : 打開 archive file,屬性為 'z'。像是 out00-PYZ.pyz 就是 python 壓縮檔
X : 解開,可以選擇直接顯示在螢幕上,或是輸出為一個檔案
Q : 離開
引用的 package 都會放在 out00-PYZ.pyz 裡頭,下 O 打開看看
我以 Python 內建的 package 'string' 做後面的測試
先直接顯示在螢幕上
輸出為一個檔案,命名為 string_extract.pyc
果然是 Python standard,註解寫得很詳細
如果是打開我自已寫的pyc,就會是一堆亂碼了 XD
三、利用 Easy Python Decompiler
我們已經得到 pyc 檔案了,那麼接下來要做的事情就直接反編譯 pyc欸,怎麼不行,你這騙子!
呵呵,magic value 不正確
不知道什麼原因,pyinstaller包成執行檔之後,magic value就不見了
如果有人知道原因,請告訢我
py 編成 pyc 時,會在文件開頭加上 magic value,包含
- A magic number (four bytes)
- A timestamp (four bytes)
- A code object (marshalled code)
magic number 就是編譯時 python 的版本。可以用查表的方法
timestamp 為編譯時的時間
marshalled …我還真的不知道,請其它大大補充
主要功能是可以確認 Python 版本是否相同、有沒有必要重新編譯等等(不過好像也沒其它的了)
詳細說明可以參考 中文 的,或是 英文 的
PS. Python3 magic value 長度似乎多了 tag (4 byte maybe)
Python 2 no attribute 'get_tag'
Python 3 tag is 'cpython-34'
原本我是用 archive_viewer.py 去看裡頭使用了哪一版的 python,然後就用查表的方式去找 magic number
後來有發現簡單的方式 (但不保證百分之百、一定沒問題)
像這一包是用 python 2.7,那可以查表了
另一種方式是利用 archive_viewer.py 顯示前幾包的內容,開頭的 4 bytes 就是 magic number
'03 F3 0D 0A'
下面這包是用 python 3.4,一樣可以查表
或是利用 archive_viewer.py 顯示前幾包的內容,開頭的 4 bytes 就是 magic number
'EE 0C 0D 0A'
我們回到一開始 string_extract.pyc
插入 magic value 後,再反編譯
這次就成功了!
最後一部份
依照前面的步驟,不過這次是從 python 3 的執行檔中取出 python standard 'string'
特別注意的是,要用 python3 跑 archive_viewer.py,不然解 python 3 的檔案會失敗
加上 magic value,不同於 python 2 的長度,多了 4 bytes
上工具
成功畫面~
結案,灑花,收工
pyd能反编译吗?
回覆刪除我雖然很有興趣,不過目前還沒有時間去研究
刪除這一篇的回覆也許可以幫助你
https://www.quora.com/How-do-I-protect-Python-code-from-a-rebuilder