How is obfuscation done in Java?
Asked Answered
H

3

6

Today I came across an obfuscated class (well a lot of obfuscated classes in a jar) and I do not have a clue on how this kind of obfuscation is done.

An example:

  protected void a(ChannelHandlerContext ☃, ByteBuf ☃, ByteBuf ☃)
    throws Exception
  {
    int ☃ = ☃.readableBytes();
    if (☃ < this.c)
    {
      ☃.b(0);
      ☃.writeBytes(☃);
    }
    else
    {
      byte[] ☃ = new byte[☃];
      ☃.readBytes(☃);

      ☃.b(☃.length);

      this.b.setInput(☃, 0, ☃);
      this.b.finish();
      while (!this.b.finished())
      {
        int ☃ = this.b.deflate(this.a);
        ☃.writeBytes(this.a, 0, ☃);
      }
      this.b.reset();
    }
  }

}

As you see above, all the parameter variables are a snow-man. How can this be undone? Also how is it done in the first place; how is the JVM able to "process" those and execute the code without any problem?

To clarify, I am not going to use this code, it is just for educational purposes. I am taking the Computer Science course at school so since we are learning Java and talking of limitations such as decompilations. I am interested in learning more, so I decided to have a look into bigger projects especially servers. This piece of code is pulled out of the Spigot server for Minecraft (A game) that is a fork of Bukkit server for Minecraft that was supposed to be open source.

Henequen answered 22/6, 2015 at 20:58 Comment(3)
That's a Unicode character like any other Unicode character. Why would you expect it to not work?Oneirocritic
Well i see your point, i know it is and it is "\u2603" specifically but i dont understand how it can be done, and undone... :- ) Thanks.Callan
It's just like any other variable name. You can name a variable x, for example. This is just a variable whose name is . There's no "done" or "undone", it's just that you can write a variable name with whatever characters you want.Screwy
P
10

First of all, you should note that it is the parameters which have this unicode and not the methods. Why is this important? Parameters do not need to have names specified, as they are mostly indexed by a number reference. However it can be specified and I assume that most java runtimes do in fact not check this name as it is not needed for execution. In the opposite, class names, method names, and field names are however needed.

About you mentioning Spigot, Spigot is indeed open source. However you most likely decompiled a class which is originally from the original Mojang Minecraft server, which is not open source and is indeed obfuscated.

Edit: In the case you want to investigate these classes, I recently found a tool called Bytecode Viewer, which is available at https://github.com/Konloch/bytecode-viewer This tool has multiple decompilers as well as some options to view a more bytecode like version of the class file. An example of a function I found contains the following bytecode data:

     <localVar:index=1 , name=☃ , desc=D, sig=null, start=L1, end=L2>
     <localVar:index=3 , name=☃ , desc=D, sig=null, start=L1, end=L2>
     <localVar:index=5 , name=☃ , desc=D, sig=null, start=L1, end=L2>

Indeed as is visible, the unicode name has been set the same, but it does not matter as in the end the indexes (1,3,5) are used to reference these variables.

Phyllida answered 22/6, 2015 at 21:8 Comment(5)
Indeed it is from net.minecraft.server but in the past obfuscation was much frendlier :- ( The resource provided is EXACLY what i needed! Thanks so much!!! Also what function was that? so far i have a litle hard time reading the code because it either apears as the unicode value or as shown above but it is a litle corrupt :3 Thanks :- )Callan
Oof I didn't write it down I think it was a constructor of a class starting with Biome. Do note that the program has options to change the display/decompiler under View and then pane 1-3.Phyllida
Took a quick look. that specific class was BiomeBaseSub. You could try Fernflower to see readable java code and bytecode in a second pane. Also it has an option to not take variable names from the class debug information.Phyllida
I see! Thanks again! What i tryed: -Procyon -> Showed code but displayed the unicode as param -CFR -> deobfuscated the unicodes but casted everything to Class xD -FernFlower -> Worked but variable-names became: �2 Every single one. -Karaktau -> IOException :- ( -Bytecode -> Worked as you showed above -Smali/DEX -> Unreadable text -HEX -> Weird but i got some things out of it :D Cheers!Callan
Thanks! I tried bytecode viewer and using fernflower the variables are called , ☃1, ☃2 etc. so you can read and understand the code :)Benue
E
1
protected void a(ChannelHandlerContext ☃, ByteBuf ☃, ByteBuf ☃)

This isn't valid. You cannot have multiple parameters with the same name. It could be that you are not reading the unicode text with the right text format.

Epode answered 22/6, 2015 at 21:7 Comment(1)
You can indeed not compile it. However it is allowed in bytecode.Phyllida
I
1

Your Text editor is showing the value of the unicode character.

I just tested on eclipse and names with unicode characters are acceptable.

    public String publicationXmlUrl(int \u9090currentPage) {

But writing with values are not:

   public String publicationXmlUrl(int ♥currentPage) {
Imperfective answered 22/6, 2015 at 21:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.