adq


Andrew de Quincey's livejournal


Previous Entry Share Next Entry
jrename: a Java deobfuscator
adq
Investigating decompiled obfuscated Java code is interesting. It isn't as difficult as looking at raw assembly code since you're generally looking at Java source. Also, you know what is grouped into which classes, you know method and field signatures, and there is no possibility of tricks such as self modifying code, and so on.

However, most obfuscators will intentionally scramble the class, method and field names so it isn't obvious what they do. Additionally, they do their best to make them all conflicting. For example having two methods in the same class with the signature "void test()" and "String test()" is illegal in Java source. However it isn't in the binary class files. Obfuscators will tend to use this fact to break the decompiled source code.

The only thing they have to be careful about is method overriding; if a method with exactly the same name/return type/arguments matches one in a superclass or interface, you're guaranteed it is an overridden method, even in an obfuscated file.

Most decompilers do not fix this issue; you end up with some nice java source, but unfortunately with many conflicting method, field, and class names. Enter jrename: This takes a set of binary .class files, analyses and fixes the names of them and their members, and spits out a second set of processed .class files. You can then run these through a decompiler with hopefully zero errors caused by illegal names.

After that, you load it  into Eclipse, and start figuring out what methods do what. Eclipse has some very nice code refactoring features, so you can use  those to rename methods/fields/classes as you determine what they are and have them globally affect any uses across the rest of the source.

Jrename's source is here, and there's a binary release here. It uses the extremely cool ASM library for all binary class file access.

Incidentally, the "NeedsRenamed()" method is pulled pretty much exactly from another Java deobfuscator project, JDO, which is written in C#. I decided to write my own from scratch in Java as I wanted to be able to modify the deobfuscator easily: I found the code in JDO rather more complex than I felt it had to be, and maintaining a complete Java .class file parser also seemed an unnecessary overhead, given the existence of ASM. I also felt writing it in Java was more suitable than C#, and I wanted a simple command line interface, not a GUI.

Don't get me wrong though, I much prefer C# coding to Java coding!

  • 1
Hmm, this renamed my classes, but didn't rename any of my methods or fields. I'm trying to poke around the code to see why this might be the case.

Fixed! Patch posted at http://code.google.com/p/adqmisc/issues/list?thanks=2&ts=1288759427

Many thanks! Just applied, sorry for delay!

Error when using on Kindle's framework-impl.jar

(Anonymous)
java.lang.NullPointerException
at net.lidskialf.jrename.ClassProcessor.FixFieldName(ClassProcessor.java:342)
at net.lidskialf.jrename.ClassProcessor.FixFieldName(ClassProcessor.java:352)
at net.lidskialf.jrename.ClassProcessor.FixFieldName(ClassProcessor.java:333)
at
Hi Andrew,

Just lettin you know that jrename fails whilst procssing Kindle 3's framework-impl.jar with this exception:

net.lidskialf.jrename.Phase3DeObfuscatorMethodVisitor.visitFieldInsn(Phase3DeObfuscatorMethodVisitor.java:52)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at net.lidskialf.jrename.ClassProcessor.ProcessPhase3(ClassProcessor.java:129)
at net.lidskialf.jrename.jrename.Process(jrename.java:117)
at net.lidskialf.jrename.jrename.ProcessZip(jrename.java:92)
at net.lidskialf.jrename.jrename.main(jrename.java:60)

Warm regards from downsouth,

Alexey D. ;-)

Re: Error when using on Kindle's framework-impl.jar

Hey! not seen you in ages, hows it going? I see you've sent a patch for the error in; I'll pull it in

Recover of the inner classes names is not always complete

(Anonymous)
Hi Andrew,

Great tool, have been using it to investigate Kindle internals. Did a small fix (which I also suggested on google source pages to add extra check for the interfaces) and discovered a small issue as well. Jrename will try to recover the obfuscated inner classes names but it does not seem to update the references to them properly. This is especially if the inner classes are public and used/referenced by some other classes within the same package. An example from kindle for you to try out would be com.amazon.ebook.framework.b.a package - using jrename on that you will end up with references to non existing classes after renaming.

I'll have a look to see if I can fix jrename to avoid this but that won't be soon so wanted to let you know.

Regards from Orbital colleague,

Alexey

Re: Recover of the inner classes names is not always complete

Thanks! been rather lazy with email recently so I'm only just getting round to catch up!

I have an obfuscated file which has several case-conflicts (i.E. e/h.class and E/H.class) -- while I can fix the class names in jrename easily, it currently doesn't touch package names. Any chance that package renaming could be implemented in jrename?

Re: package name/rename

Hmm, probably reasonably straightforward, but I'm very limited for time :(

  • 1
?

Log in