:用 Python 把 EXE 反編譯復原流程封裝成可復用 Skill)
1. 為什么 EXE 復原總在重復造輪子手里拿到一個打包好的 EXE想還原成可讀的 Python 源碼這件事本身不復雜復雜的是每次都要重新走一遍相同的判斷這是 PyInstaller 還是別的打包器、提取出來的 pyc 用哪個版本反編譯、反編譯結(jié)果里哪些是函數(shù)錯位哪些是字符串丟失、重建之后怎么驗證不炸掉原目錄。做過三五次之后你會發(fā)現(xiàn)真正花時間的不是反編譯那一條命令而是圍繞它的證據(jù)盤點、結(jié)果比對和安全驗證。Codex 在這里的價值不是替你反編譯而是把「收集證據(jù) → 識別打包方式 → 對比反編譯結(jié)果 → 重建結(jié)構(gòu) → 驗證行為」這條鏈路固化成可重復調(diào)用的 Skill。你只需要說一句「用 DecodePyExe 繼續(xù)復原當前目錄」它就知道該看哪些文件、不該碰哪些目錄、先恢復什么后恢復什么、驗證到什么程度算通過。這篇就把這個 Skill 的目錄骨架、config.toml 配置片段和一次完整復原驗證動作拆開講清楚讓你能直接照著搭一套。適合誰看手頭有歷史打包程序需要還原結(jié)構(gòu)的后端或工具開發(fā)者、經(jīng)常處理 pyc 和反編譯產(chǎn)物的安全分析人員、以及想把零散命令沉淀成 Codex Skill 的工程效率愛好者。前置要求只有兩個本機裝好 Python 和 Codex能跑通一次模型對話確認鏈路正常。2. 用 TaoToken 打通 Codex 的模型調(diào)用鏈路Codex 執(zhí)行 Skill 時需要穩(wěn)定的模型入口否則你剛把流程跑順一次請求超時就前功盡棄。我這邊習慣用 TaoToken 作為統(tǒng)一入口它把模型對話、Coding Plan、API Keys 管理放在同一個控制臺里配置一次就能在 Codex 里長期復用不用每次換環(huán)境重新折騰。具體來說Codex 的 config.toml 里需要填一個 base_url 和 api_key。base_url 指向 TaoToken 的 API 地址api_key 在控制臺的 API Keys 頁面生成。這樣 Codex 發(fā)起的所有模型請求都會走這個入口Skill 里定義的復原步驟才能被穩(wěn)定執(zhí)行。如果你只是偶爾驗證一下模型輸出可以直接用模型對話頁面手動測如果是要長期跑編碼和 Agent 任務(wù)建議開 Coding Plan配額和并發(fā)更穩(wěn)。接入文檔里有完整的參數(shù)說明第一次配的時候?qū)χ匆槐槟苁〔簧倥挪闀r間。注意API 地址用 https://taotoken.net/api不要在后面拼多余的路徑config.toml 里的 base_url 填到這一層就夠了。3. Skill 目錄骨架與 config.toml 配置片段先把目錄結(jié)構(gòu)定下來。Codex Skill 的約定是放在項目根目錄的.codex/skills/下每個 Skill 一個文件夾里面至少有一個SKILL.md描述觸發(fā)條件和執(zhí)行步驟。我建議再加一個references/放流程細節(jié)一個scripts/放可復用的輔助腳本。.codex/ skills/ DecodePyExe/ SKILL.md references/ recovery-flow.md safety-checklist.md scripts/ inventory.py verify_recovered.pySKILL.md的頭部用 YAML front matter 寫觸發(fā)描述正文寫步驟。描述要寫清楚「什么時候用」和「禁止什么」這樣 Codex 在匹配任務(wù)時不會誤觸發(fā)。--- name: DecodePyExe description: Recover readable Python source from PyInstaller executables, extracted PYZ folders, .pyc files, and decompiler output. Use when asked to restore, reconstruct, clean up, or continue recovering source from Python exe artifacts while avoiding unrelated local source code. --- # DecodePyExe ## 使用時機 - 當前目錄存在 .exe、.pyc、PYZ 提取目錄或反編譯產(chǎn)物 - 用戶要求復原、重建、整理源碼 - 用戶說「繼續(xù)復原」并指向當前目錄 ## 證據(jù)邊界 只參考當前目錄內(nèi)的文件。禁止讀取其他本地項目的源碼。 ## 執(zhí)行步驟 1. 盤點目錄列出所有候選證據(jù)文件 2. 識別打包方式查找 pyiboot / pyimod / PYZ / pyi_rth 線索 3. 區(qū)分業(yè)務(wù)模塊與第三方依賴 4. 對比多個反編譯結(jié)果提取函數(shù)名、類名、調(diào)用順序、字符串常量 5. 重建為 xxx_recovered.py不覆蓋原始反編譯文件 6. 先 py_compile 再 import 驗證不貿(mào)然運行主入口 ## 輸出格式 - 重建文件列表 - 每步驗證命令與結(jié)果 - 不確定處的注釋標記config.toml 里除了模型入口還可以給這個 Skill 單獨指定溫度復原任務(wù)需要穩(wěn)定輸出溫度調(diào)低一點更合適。# ~/.codex/config.toml model claude-sonnet-4-20250514 model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY [skills.DecodePyExe] enabled true temperature 0.2api_key 不要硬編碼在 config.toml 里用環(huán)境變量注入。Windows 下在 PowerShell 里設(shè)一次$env:TAOTOKEN_API_KEY sk-你的keyLinux 或 macOS 寫進 shell 配置export TAOTOKEN_API_KEYsk-你的key配好之后跑一次模型對話確認鏈路通再進下一步。如果返回 401八成是 key 沒讀到或者 base_url 多寫了路徑。4. 一次完整的 EXE 復原驗證動作假設(shè)當前目錄里有一個legacy_tool.exe還有提取出來的PYZ-00.pyz_extracted/和一份反編譯結(jié)果decompiled/。下面按 Skill 定義的步驟走一遍。第一步盤點目錄。Skill 里的inventory.py負責把候選證據(jù)列出來避免手動翻。# scripts/inventory.py import os from pathlib import Path EVIDENCE_SUFFIXES {.exe, .pyc, .pyz, .pyi, .log, .json, .ini, .cfg} EVIDENCE_DIRS {PYZ-00.pyz_extracted, decompiled, resources} def inventory(root: str .): root_path Path(root) found {files: [], dirs: []} for p in root_path.rglob(*): if p.is_file() and p.suffix.lower() in EVIDENCE_SUFFIXES: found[files].append(str(p.relative_to(root_path))) if p.is_dir() and p.name in EVIDENCE_DIRS: found[dirs].append(str(p.relative_to(root_path))) return found if __name__ __main__: result inventory() print(候選文件:) for f in result[files]: print( , f) print(候選目錄:) for d in result[dirs]: print( , d)跑一下python scripts/inventory.py輸出會列出legacy_tool.exe、PYZ-00.pyz_extracted/下的 pyc、decompiled/下的 py 文件。這一步的目標是搞清楚手里有哪些證據(jù)不是馬上開始反編譯。第二步識別打包方式。在提取目錄里搜打包器特征文件rg --files PYZ-00.pyz_extracted | rg pyiboot|pyimod|pyi_rth如果命中pyiboot01_bootstrap或pyimod02_importers基本可以確認是 PyInstaller 打包。這一步?jīng)Q定了后續(xù)入口文件大概長什么樣。第三步區(qū)分業(yè)務(wù)模塊和依賴。提取目錄里通?;熘鴕equests、urllib3這類第三方庫不要陷進去。優(yōu)先找文件名帶業(yè)務(wù)語義的模塊比如config_loader.pyc、report_builder.pyc。第三方依賴只需要知道被引用了不需要復原。第四步對比反編譯結(jié)果。如果decompiled/下有兩份不同工具產(chǎn)出的結(jié)果分別看它們的優(yōu)勢一份可能字符串保留更全另一份函數(shù)邊界更清楚。重建時綜合兩邊證據(jù)而不是復制其中一份。第五步重建源碼。新建legacy_tool_recovered.py不要覆蓋decompiled/里的原始文件。重建順序按 Skill 定義走imports → 配置讀取 → 工具函數(shù) → 小模塊 → 核心類 → 主流程 → 異常處理。不確定的分支加注釋# Reconstructed from bytecode order; exact original branch may differ. if mode batch: run_batch() else: run_single()第六步安全驗證。先編譯檢查python -m py_compile legacy_tool_recovered.py沒有輸出就是通過。再做導入檢查# scripts/verify_recovered.py import importlib.util import sys def verify(module_path: str, module_name: str recovered): spec importlib.util.spec_from_file_location(module_name, module_path) module importlib.util.module_from_spec(spec) sys.modules[module_name] module try: spec.loader.exec_module(module) print(import ok) return True except Exception as e: print(fimport failed: {e}) return False if __name__ __main__: verify(legacy_tool_recovered.py)跑python scripts/verify_recovered.py輸出import ok說明模塊級代碼沒有副作用、語法和導入都正常。到這一步為止不要運行主入口因為打包程序的主流程可能寫文件、移動目錄或啟動外部程序。只有確認副作用可控后才考慮單獨測試純函數(shù)或配置解析函數(shù)。5. 復原過程中最容易踩的坑反編譯結(jié)果當答案直接跑。反編譯產(chǎn)物里函數(shù)錯位、try/except 丟失、return 位置錯誤都很常見。直接運行輕則報錯重則觸發(fā)主流程的副作用。正確做法是把它當證據(jù)提取結(jié)構(gòu)后重建。一上來就恢復細節(jié)。有人喜歡從第一行開始逐行還原結(jié)果卡在某個字符串亂碼上半天。先恢復 imports 和配置讀取拿到一個能 import 的骨架再往里填細節(jié)節(jié)奏會順很多。誤讀其他項目的源碼。如果用戶明確說「只參考當前目錄」就不要去翻本地其他項目。Skill 里把這條寫成硬約束Codex 執(zhí)行時不會越界。config.toml 里 base_url 寫錯。常見的是在https://taotoken.net/api后面又拼了/v1或/chat/completions導致 404。base_url 填到/api這一層剩下的路徑由 Codex 自己拼。api_key 沒注入環(huán)境變量。config.toml 里寫的是env_key TAOTOKEN_API_KEY如果環(huán)境變量沒設(shè)請求會直接 401。設(shè)完之后新開一個終端再跑避免舊會話讀不到。驗證時直接跑主入口。python legacy_tool_recovered.py這種命令在沒確認副作用前不要執(zhí)行。先用py_compile和import兩道檢查確認安全后再考慮局部測試。Codex 重啟后上下文丟失。這是最常見也最影響效率的問題。解決辦法是在項目根目錄維護一個PROJECT_STATE.md記錄當前目標、已完成、關(guān)鍵文件、注意事項和下一步。重啟后第一句說「先讀 PROJECT_STATE.md然后繼續(xù)」Codex 就能接上。# 當前目標 復原 legacy_tool.exe 為可讀 Python 源碼 # 已完成 - 盤點目錄確認 PyInstaller 打包 - 重建 legacy_tool_recovered.py 的 imports 和配置讀取 - py_compile 通過 # 關(guān)鍵文件 - legacy_tool_recovered.py - decompiled/ 下的兩份反編譯結(jié)果 # 注意事項 - 只參考當前目錄 - 不要運行主入口 # 下一步 - 恢復核心類結(jié)構(gòu) - 對比兩份反編譯結(jié)果的字符串常量6. 把流程固化下來之后Skill 搭好、config.toml 配好、PROJECT_STATE.md 維護起來之后下次遇到類似的 EXE 復原任務(wù)你只需要一句「使用 DecodePyExe繼續(xù)復原當前目錄里的程序」Codex 就會按既定步驟走盤點證據(jù)、識別打包方式、對比反編譯結(jié)果、重建源碼、安全驗證。不用每次重新解釋邊界和順序也不用擔心重啟后從零開始。如果你還沒配好模型入口先去控制臺生成一個 API Key然后對著接入文檔把 config.toml 填完。長期跑編碼和 Agent 任務(wù)的話Coding Plan 的配額更穩(wěn)適合把這類復原流程當成日常工具用。配好之后跑一次模型對話確認鏈路再回來把 Skill 目錄建起來整個流程就能跑通了。