關於蕨花
FernFlower 是第一個實際工作的 Java 分析反編譯器,也可能是一般高階程式語言的分析反編譯器。當然,它仍在開發中,請將您的錯誤報告和改進建議發送到[問題追蹤器](https://youtrack.jetbrains.com/newIssue?project=IDEA&clearDraft=true&c=Subsystem+Java.Decompiler)。
FernFlower 和 ForgeFlower
FernFlower 包含來自 ForgeFlower 的一些補丁。衷心感謝 ForgeFlower 的維護者所做的寶貴貢獻和改進。
執照
FernFlower 根據 Apache 授權版本 2.0 取得授權。
從命令列運行
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
* 表示0次或多次
+表示1次或多次
<source>:包含要反編譯的檔案的檔案或目錄。目錄被遞歸掃描。允許的檔案副檔名是 class、zip 和 jar。以 -e= 為前綴的來源表示不會被反編譯的「函式庫」文件,但在分析類別或方法之間的關係時會考慮。特別是標識符的重新命名(s.選項“ren”)可以從有關外部類別的資訊中受益。
<目標>:目標目錄
<選項>、<值>:具有對應值的命令列選項(請參閱下方的「命令列選項」)。
範例:
java -jar fernflower.jar -hes=0 -hdc=0 c:Tempbinary -e=c:Javart.jar c:Tempsource
java -jar fernflower.jar -dgs=1 c:Tempbinarylibrary.jar c:TempbinaryBoot.class c:Tempsource
命令列選項
除 mpm 和 urc 之外,值 1 表示該選項已激活,0 表示該選項已停用。預設值(如果有)在括號之間給出。
通常,以下選項將由使用者更改(如果有):hes、hdc、dgs、mpm、ren、urc 其餘選項可以保留原樣:它們針對專業逆向工程師。
- rbr(1):隱藏橋接方法
- rsy (0):隱藏合成類成員
- din(1):反編譯內部類
- dc4(1):折疊1.4類別引用
- das(1):反編譯斷言
- hes (1): 隱藏空的超級調用
- hdc(1):隱藏空的預設建構函數
- dgs(0):反編譯通用簽名
- ner (1):假設回傳不拋出例外
- den (1):反編譯枚舉
- rgn (1):當 getClass() 呼叫是合格的 new 語句的一部分時,刪除它
- lit (0):「原樣」輸出數位文字
- asc (0):將字串和字元文字中的非 ASCII 字元編碼為 Unicode 轉義符
- bto (1):將 int 1 解釋為布林值 true(解決編譯器錯誤)
- nns (0):允許不設定合成屬性(解決編譯器錯誤)
- uto (1):將無名型別視為 java.lang.Object (解決編譯器架構缺陷的方法)
- udv (1):根據偵錯資訊重建變數名稱(如果存在)
- ump (1):根據對應的屬性重建參數名稱(如果存在)
- rer(1):刪除空異常範圍
- fdi (1):去內聯的finally結構
- mpm (0):每個反編譯方法允許的最大處理時間,以秒為單位。 0表示沒有上限
- ren (0):重新命名不明確(或混淆)的類別和類別元素
- urc (-):使用者提供的實作 IIdentifierRenamer 介面的類別的全名。它用於確定應重命名哪些類別標識符並提供新的標識符名稱(請參閱“重命名標識符”)
- inn (1):檢查 IntelliJ IDEA 特定的 @NotNull 註解並刪除插入的程式碼(如果找到)
- lac(0):將lambda表達式反編譯為匿名類
- nls(0):定義用於輸出的換行符號。 0 - 'rn' (Windows),1 - 'n' (Unix),預設值取決於作業系統
- ind:縮排字串(預設為3個空格)
- crp (0):盡可能使用記錄模式
- cps (0):在可能的情況下使用具有模式的開關
- log (INFO):日誌記錄級別,可能的值為 TRACE、INFO、WARN、ERROR
- iec (0):反編譯時將整個類別路徑包含到上下文中
- isl (1):內聯簡單 lambda 表達式
- ucrc (1):隱藏不必要的記錄建構子和 getter
- cci (1): 檢查try-with-resources中的資源是否真正實現了
AutoCloseable
接口 - jvn (0):用 JAD 樣式名稱覆寫任何局部變數名稱
- jpr (0):在 JAD 命名中包含參數名稱
重新命名標識符
一些混淆器賦予類別及其成員元素簡短、無意義、最重要的是模糊的名稱。重新編譯此類程式碼會導致大量衝突。因此,建議讓反編譯器依序重命名元素,以確保每個識別碼的唯一性。
選項“ren”(即-ren=1)啟動重新命名功能。預設重命名策略如下:
- 如果元素的名稱是保留字或少於 3 個字符,則重新命名該元素
- 新名稱根據簡單的模式建構:(類別|方法|欄位)_<連續唯一編號>
您可以透過提供您自己的重命名時反編譯器呼叫的 4 個關鍵方法的實作來覆寫此規則。只需將選項「urc」中實作 org.jetbrains.java.decompiler.main.extern.IIdentifierRenamer 的類別(例如 -urc=com.example.MyRenamer)傳遞給 FernFlower。該類別必須在應用程式類別路徑上可用。
每個方法的含義從命名上就應該很清楚了:toBeRenamed 確定元素是否會被重新命名,而其他三個方法分別為類別、方法和欄位提供新的名稱。