如何在FernFlower中使用自定义重命名器?

时间:2014-12-30 20:44:00

标签: java decompiling

我目前有一个FernFlower的工作设置,就像这样;

我有fernflower.jarfern.bat文件,内容为:

title FernFlower
java -jar fernflower.jar -dgs=1 -ren=1 C:\Users\bernhardkiv\Desktop\test\test-obf.jar C:\Users\bernhardkiv\Desktop\test\src

参数-ren 1使得任何名称小于3个字符(或类似名称)的方法和字段都会重命名为func_blahfield_blah(相应地,方法获取func_名称和字段获取field_名称。

在fernflower的自述文件中有这一部分:

 5. Renaming identifiers

Some obfuscators give classes and their member elements short, meaningless and above all 
ambiguous names. Recompiling of such code leads to a great number of conflicts. Therefore it is
advisable to let the decompiler rename elements in its turn, ensuring uniqueness of each identifier.

Option 'ren' (i.e. -ren=1) activates renaming functionality. Default renaming strategy goes as follows:
 - rename an element if its name is a reserved word or is shorter than 3 characters
 - new names are built according to a simple pattern: (class|method|field)_<consecutive unique number>  
 You can overwrite this rules by providing your own implementation of the 4 key methods invoked by the decompiler while renaming. Simply pass a class that implements de.fernflower.main.extern.IIdentifierRenamer in the option 'urc' (e.g. -urc=com.mypackage.MyRenamer) to Fernflower.
 The class must be available on the application classpath.

通过它,我已经阅读并理解它是如何工作的,但我在添加自己的重命名功能实现时遇到了麻烦。

我创建了一个实现IIdentifierRenamer的类,其内容如下;

public class MyRenamer implements IIdentifierRenamer {

@Override
public String getNextClassname(String arg0, String arg1) {
    return "_" + arg0 + "_" + arg1;
}

@Override
public String getNextFieldname(String arg0, String arg1, String arg2) {
    return "_" + arg0 + "_" + arg1 + "_" + arg2;
}

@Override
public String getNextMethodname(String arg0, String arg1, String arg2) {
    return "_" + arg0 + "_" + arg1 + "_" + arg2;
}

@Override
public boolean toBeRenamed(int arg0, String arg1, String arg2, String arg3) {

    System.out.println(arg0 + ", " + arg1 + ", " + arg2 + ", arg3");
    return true;
}

}

首先,在你质疑为什么我返回nextMethod / Class / Field方法的所有参数之前,我可以探索并查看这些争论究竟是什么,因为绝对没有文档AFAIK。 / p>

我将这个类编译成一个名为custre.jar的jar,并将其放在与fern.bat相同的文件夹中。

我现在不确定该怎么做才能继续,如果你对FernFlower一无所知,请回复,如果你能帮助我的话。

2 个答案:

答案 0 :(得分:3)

好的,花了一些时间来解决这个问题。首先,请注意fernflower源中有一个实现默认重命名的类:

src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java

将此文件作为模板复制到您自己的位置,根据您的需要进行调整。我将包更改为:

package jimm3rs.renamer;

并将调试消息输出添加到toBeRenamed方法:

System.out.println("Custom Renamer: processing [" + classname + "]");

然后编译:

javac -cp ~/fernflower/trunk/fernflower.jar ConverterHelper.java

接下来是指示fernflower使用这个自定义重命名器:

java -classpath fernflower.jar:/home/martin/mycode/ org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=1 -ren=1 -urc=jimm3rs.renamer.ConverterHelper /home/martin/Downloads/idea-IC-141.1532.4/lib/boot.jar .

请注意,在上面的代码目录中,/home/martin/mycode/包含一个名为jimm3rs的子目录,该子目录又包含名为renamer的目录,该目录存储我们的自定义重命名器类。如果您想要额外的步骤,可以将其更改为使用jar。

调试类加载时,一个有用的提示是指定java的-Dsun.misc.URLClassPath.debug=true选项。

最后我想说使用-jar语法来运行fernflower.jar并不是这样做的 技巧:通过-classpath指定的自定义类对fernflower不可见。

答案 1 :(得分:0)

首先,您需要将custre.jar添加到类路径中。然后,您需要为FernFlower指定自定义重命名器类:

java -cp /path/to/custre.jar -jar fernflower.jar -dgs=1 -ren=1 -urc=MyRenamer C:\Users\bernhardkiv\Desktop\test\test-obf.jar C:\Users\bernhardkiv\Desktop\test\src

(将/path/to/custre.jar替换为系统上的实际路径),