Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a custom renamer with FernFlower?

I currently have a working setup of FernFlower, which is like this;

I have the fernflower.jar and a fern.bat file which contents are:

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

And the argument -ren 1 makes it so any methods and fields that have names lower than 3 characters (or something like that) get renamed to func_blah or field_blah (respectivally, methods get the func_ name and fields get the field_ name.

In the readme of fernflower there is this section:

 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.

Through which, I have read through and understand how it works, but I am having trouble with adding my own implementation of the renaming function.

I have created a class, which implements IIdentifierRenamer, which contents are as follows;

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;
}

}

First things first, before you question why I return all of the arguments for the nextMethod/Class/Field methods, it is so that I could explore and see what those arguements actually are, because there is absolutely no documentation AFAIK.

I compiled this class into a jar, named custre.jar, and put it in the same folder as my fern.bat.

I am now unsure of what to do to continue, please reply if you know anything about FernFlower, and if you can help me.


1 Answers

Okay, it took some time to figure this out. First, notice that there is a class in fernflower source that implements default renaming:

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

Copy this file as a template to your own location, adjust to suit your needs. I changed package to:

package jimm3rs.renamer;

And added debug message output to the toBeRenamed method:

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

Then compiled:

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

Next thing is to instruct fernflower to use this custom renamer:

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 .

Note that in the above code directory /home/martin/mycode/ contains a subdirectory named jimm3rs which in turn contains directory named renamer which stores our custom renamer class. This could be changed to use a jar if you wish with an extra step.

One useful tip when debugging class loading is to specify -Dsun.misc.URLClassPath.debug=true option to java.

Finally I'd like to say that using -jar syntax to run fernflower.jar didn't do the trick: custom class specified via -classpath is not visible to fernflower.

like image 69
jimmers Avatar answered Nov 09 '25 06:11

jimmers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!