关于蕨花
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 确定元素是否会被重命名,而其他三个方法分别为类、方法和字段提供新的名称。