Skip to content

Virtualization

exotic edited this page Feb 2, 2024 · 1 revision

Virtualization

The process of virtualization is very simple, we basically make a VM (virtual machine) that can interpret the JVM bytecode, this gives us a lot more power in terms of what information we can get.

A popular VM is SSVM by xxDark, it is very powerful and can be used for numerous things. The reason we need a VM is so we can virtualize stuff like method calls.

Let's say we have this obfuscated piece of code:

v7 = v5.void();
v14 = Main.import(v12, 556878214);
v17 = Main.boolean(v7, v14);
var1_1.setTitle(v17);

Now I mean this in the most respectful way possible, this is fucking dogshit but I can't really just introduce you into insanely obfuscated code, that will probably give you brain damage.

So as you could probably already figure out setTitle() takes a string. However we don't see that string, it's a local variable that we can only get at runtime. This is one of the situations where using virtualization is a good idea. Now of course the naming here violates every single convention of Java but that's the whole point.

Now I won't put the actual implementation of boolean() as it is obviously massive. Although I can see something very interesting:

v4 = new throw();
v7 = v4.throw();
v9 = Main.import(v7, -821449344);
var2_2 = Cipher.getInstance(v9);

import()'s descriptor is:

(Ljava/lang/String;I)Ljava/lang/String;

or simplified:

String (String str, int num)

now this is a classic pattern of XOR encryption, and this is backed up by the fact that we see this in the import() method:

v5 = (char)(s.toCharArray()[i] ^ num);

If you don't know, in Java the ^ character means the XOR operation. Now since I have some experience I can already understand what this whole method does. in the descriptor (let's use the simplified one for simplicity) we can see that a String and an integer primitive are passed in, basically this means the string that is passed in is the data that needs to be encrypted and the integer is obviously the key.

So armed with this knowledge we can go back to the boolean() method:

v4 = new throw();
v7 = v4.throw();
v9 = Main.import(v7, -821449344);
var2_2 = Cipher.getInstance(v9);

If you have any knowledge of Java then you know what getInstance() does. Now v9 in this case is a string meaning we can decrypt it by virtualizing the method call. Now let's virtualize this piece of code:

Main.import(v7, -821449344);

after virtualizing this using SSVM, the output is:

AES/ECB/PKCS5Padding

which means the code is:

var2_2 = Cipher.getInstance("AES/ECB/PKCS5Padding");

which is about right. Anyways now you know how to virtualize methods! This example was a bit off but you should be able to understand it.

Clone this wiki locally