Q :為什麼還需要另一個反編譯器,尤其是一個有缺陷的反編譯器?
答:一個可悲的事實是大多數反編譯器都有缺陷。許多人無法反編譯瑣碎的結構,其他人無法反編譯更高級的結構,那些看似可以處理它們的人,卻因僅支援無聊的體系結構和作業系統而陷入癱瘓。幾乎所有的編寫方式都使得調整它或添加新的架構變得複雜。反編譯器是一種逆向工程工具,但諷刺的是,如果您想有效地使用典型的反編譯器或使其滿足您的需求,首先您需要對反編譯器本身進行逆向工程,這很容易需要數月(或數年) 。
反編譯器(以及任何程式轉換框架)的核心部分是中間表示(IR)。反編譯器應該在IR 上工作,並且應該將其作為輸入,並且特定架構的彙編器到該IR 的轉換應該與反編譯器很好地解耦,否則需要付出巨大的努力來添加對另一種架構的支援(這反過來又限制了反編譯器的用戶群)。
反編譯是一項複雜的任務,因此應該輕鬆了解反編譯過程。這意味著反編譯器使用的 IR 應該是人性化的,例如使用程式設計師熟悉的語法、盡可能直接映射到典型的機器彙編器等。
上述要求本身應該是非常明顯的。如果沒有,可以從有關此事的書籍中學習,例如:
“編譯器編寫者還需要讓人們輕鬆直接地檢查 IR 程式的機制。自身利益應該確保編譯器編寫者註意最後一點。”
(Keith Cooper、Linda Torczon,「設計編譯器」)
然而,反編譯器項目,包括開源項目,經常違反這些要求:它們與特定的機器架構緊密耦合,不允許輸入 IR,並且通常根本不向使用者公開或記錄它。
ScratchABlock就是試圖對這種做法說“不”,並根據上述要求開發一個反編譯框架。請注意,ScratchABlock 可以被視為一個學習/研究項目,除了良好的意圖和對其他項目的批評之外,可能不會為臨時用戶提供太多東西 - 目前或可能根本沒有。當然,它也可以在很多方面受到批評。
ScratchABlock 是根據 GNU 通用公共授權 v3 (GPLv3) 的條款發布的。
ScratchABlock 是用 Python3 語言編寫的,並在 3.3 及更高版本上進行了測試,但也可能適用於 3.2 或更低版本(不適用於舊版 Python2 版本)。有一些依賴關係:
在 Debian/Ubuntu Linux 上,可以使用sudo apt-get install python3-yaml python3-nose
安裝它們。或者,您可以透過 Python 自己的pip
套件管理器安裝它們(應該適用於任何作業系統): pip3 install -r requirements.txt
。
ScratchABlock 使用PseudoC彙編器作為其 IR。它是一種盡可能使用熟悉的C語言語法來表達的彙編語言。這個想法是任何 C 程式設計師都會直觀地理解它(範例),但人們正在努力更正式地記錄 PseudoC。
請注意,根據文件上一節中描述的要求,並遵循眾所周知的“Unix範式”,ScratchABlock 只做“一件事”——對 PseudoC 程序進行分析和轉換,並且明確不關心轉換特定體系結構的機器指令進入 PseudoC(至少目前如此)。這意味著 ScratchABlock 不會強迫您使用任何特定的轉換器/升降機 - 您可以使用任何您喜歡的。警告:您需要有一個才能使用它。有關這方面的一些提示,請參閱文件末尾。
原始碼和介面腳本位於儲存庫的根目錄中。最重要的腳本是:
apply_xform.py
- 中央驅動程序,允許將一系列轉換(或一般來說,高級分析/轉換腳本)應用於單一檔案或檔案目錄(「專案目錄」)。
inter_dataflow.py
- 過程間(全域)資料流分析驅動程式(WIP)。
script_*.py
- apply_xform.py
的進階分析/轉換腳本( --script
開關)。
script_i_*.py
- inter_dataflow.py
的分析腳本。
run_tests
- 回歸測試套件運行程式。大多數測試套件都是高級的,包括對檔案進行不同的傳遞來運行 apply_xform.py 並檢查預期結果。
儲存庫的其他子目錄:
tests_unit
- Python 模組的經典單元測試,用 Python 寫。
tests
- 主要測試套件。雖然本質上是整合的,但它通常對一個簡單文件進行一次測試,因此遵循單元測試原理。測試表示為 PseudoC 輸入文件,而預期結果 - 表示為帶有基本區塊註釋的 PseudoC 和(如果適用).dot 格式的 CFG。查看這些測試案例,嘗試修改它們並查看結果是了解 ScratchABlock 工作原理的最佳方式。
docs
- 不斷成長的文檔集合。例如,有一個作為 ScratchABlock 的中間表示 (IR) 的 PseudoC 彙編語言規範,以及一項為何不選擇另一個現有 IR 的調查。
ScratchABlock 目前的方法是開發一組相對鬆散耦合的演算法(「pass」),用於程式分析和轉換,對它們進行測試,並允許使用者輕鬆存取它們。反編譯的魔力在於以正確的順序和正確的次數應用這些演算法。然後,為了提高反編譯的效能,這些通道通常需要更緊密的耦合。在實施如上所述的通行證清單之後,探索這些方向是下一個優先事項。
ScratchABlock 實作的演算法與轉換:
圖演算法:
靜態單一作業表(SSA):
資料流分析:
傳播:
死碼消除 (DCE)
重寫:
控制流結構:
輸出格式:
ScratchABlock 的合作夥伴工具是 ScratchABit,它是一個互動式反彙編程序,旨在執行反編譯過程的最低層級任務,例如將程式碼與資料分開以及識別函數邊界。 ScratchABit 通常使用本機架構彙編器語法,但對於某些架構(通常是忠實的 RISC),如果有合適的插件可用,它可以輸出 PseudoC 語法,該語法可以作為 ScratchABlock 的輸入。