Taking a closer look at Zelix KlassMaster’s Flow Obfuscation

noverify
3 min readMay 10, 2018

--

Zelix KlassMaster is an expensive obfuscator for Java applications. But is it really worth its price?

Today we’ll be taking a look into the flow obfuscation of ZKM. If you do not know what flow obfuscation is, it is a technique to obfuscate jumps and loops in order to let decompilers fail to unscramble the basic java structure or inset a series of labels and illegal statements into the source code they produce.

I decided to obfuscate an example class with flow obfuscation settings set to “extraAggressive” and analyze the changes afterwards.

The original java file
The output (decompiled)

Now, lets take a closer look at the bytecode. I’m using JByteMod’s control flow graph view to analyze the changes ZKM made.

The original bytecode
The flow obfuscated bytecode

As you can see, ZKM added jumps to the code that made the graph structure more complex. It also created a junk field in the ExampleClass.class (boolean a.b) and another one in the main class (int MainMethod.f).

Every single jump that ZKM added to the bytecode uses an if operation that never leads to a jump. In other words, graph edges that are never used.

iload 1 - load local variable 1 (false)
ifne ? - if not equals zero, jump

Pretty easy concept, but nonetheless very effective.

Bytecode analysis

Finally, ZKM adds code before the return opcode that changes the junk field (a.b) value, but also surrounds it with an if statement that is never true (if f != 0). What does ZKM want to achieve by that? You could easily check for fields that never change and inline them in the code and most decompilers will automatically remove the resulting redundant jumps.

After removing all unnecessary ifne’s by hand the decompiler is again able to output it readable.

Decompiled code after removing unnecessary jumps

As you can see the code looks almost the same as the input code again.

Thank you for reading!

--

--