Extreme OBF [Java-Reverse]

Ahmet Göker
6 min readAug 20, 2023

--

Hello everyone,

Today, I intend to write a blog post about Extreme Obfuscated Java code, wherein we need to deobfuscate the code to uncover the password. To comprehend this blog post, it’s essential for you to have a grasp of Java bytecode. Prior to diving into this content, I suggest you take a look at: https://en.wikipedia.org/wiki/List_of_Java_bytecode_instructions

Tip: This corresponds to the final level of my previous blog on Java reverse engineering, which I have elucidated in a comprehensive manner.

Please take a look: JVM | Reverse-Engineering. Hello everyone, | by Ahmet Göker | Jul, 2023 | Medium

If you are ready, let's dive into it.

Analyzing the file

First of all, it is always recommended to analyze the file before reversing it.

As you can see, this file is in “jar” format. It might be good to use jd-gui tool → Java reversing tool.

It is strange; we can see that 0,1, c classes appeared to me, but what about the strange file?

It would be superb to unzip the file to see more in detail:

In /META-INF, we can see which class file is the main class. Main-Class: 0 is the main class. This is in our pocket.

If we run “java — jar” we can execute this .jar file. As you can see it requires a password. If we enter a wrong password “Please provide a password” is showing to me.

The question should be: “Are we able to find any file into .jar file” can we use binwalk to analyze the file correctly. I will try to use binwalk to extract some known files hidden.

Hmm interesting! We have an extracted version of BasicstringObfuscation.

Wala! We already know about the known classes, but what about the “4F.zip”?

let me show the classes respectively

0.class
1.class
c.class

As I mentioned earlier, I have already discussed these codes in my previous blog. You can perform the same procedure as described in the previous blog: Utilize Krakatau’s `disassemble.py` to obtain the bytecode, make modifications to the bytecode, and then employ `assemble.py` to compile it into a JAR file.

We should be able to get the .j file format, this represents the bytecode where I use the manipulation method.

As you can see, GOTO instructions have been essentially added in multiple places.

I won’t delve extensively into the code here, as I comprehensively covered it in my previous article. The flow and the code remain unchanged; our focus should be on identifying terms such as ‘incorrect,’ ‘please provide a password,’ and so on.

As you know that Invokevirtual would be used for puts and prints so it could be the case that this bytecode shall give us “provided string” such as “Please provide a password”

There were 5 Invokevirtual bytecodes, but 3 of them were the same → InvokeVirtual [97].

Why 3 InvokeVirtual[97]? 1. Please provide a password; 2. Incorrect; 3. Correct should be given to us.

InvokeVirtual[97] → Println();

It’s akin to a puzzle. I am now going to manipulate the bytecode in order to extract the string embedded within this code.

After experimenting, I have arrived at a solution:

The 4, 42 is the place that outputs the “Please provide a password”, and we modify it to 1, 77, which outputs the correct password!

In order to assemble .j files we can use the above command

Java -cp is a parameter in the Java Virtual Machine or Java compiler that specifies the location of classes and packages defined by the user.

we know that this code is being xored “WpUtETnF1JGrDkSsTd5G1w2dN0h” we need to find a way to crack the password.

We found that (1, 77) is the string, so the trick is finding where it is cracked! We just need to follow the code.

c.class

Oke, here is the trick we ought to find c.class where the string will be xored. Once we find it, we can replace it when we execute the program.

After discovering a solution, I realized that `Invokestatic [76]` corresponds to the XOR method, which can provide the accurate string.

invoke a static method and puts the result on the stack (might be void); the method is identified by method reference index in constant pool (indexbyte1 << 8 | indexbyte2)

The whole code:

After assembling the code:

Conclusion

I must say that dynamically reversing was the most challenging part. I learned a lot about dealing with bytecode, which is crucial for optimizing and altering runtime behavior. I had a lot of fun while writing and explaining this topic. It is highly recommended to learn programming languages to have a better understanding of them during the reverse engineering process.

As I said: Bytecode manipulation is a technique used in software development, particularly in the context of languages that are compiled to bytecode, such as Java and Kotlin. It involves programmatically modifying the bytecode of a program at runtime, before or during its execution. This allows developers to add, remove, or modify instructions within the compiled code, which can be useful for various purposes.

Thank you for reading my blog. I will see you!!

Ahmet | Security Researcher

--

--