Removing Zelix string encryption

Out of nostalgia and dismay at the lack of Classic knowledge left in the community, I have been trying to retrieve the source code of old RuneScape Classic bots. Saevion’s deobfuscator is woefully inadequate to the task; I hacked it beyond the point of reason before deciding that it would be simpler to write my own program. Having overcome my colossal apathy toward potentially time-consuming projects, I wrote a string decryption component last night.

Everyone knows that the official RuneScape client is subjected to minimal obfuscation in the interest of compatibility. You are probably aware that Zelix Klassmaster has various options for encrypting constant strings within a class, and that cheat authors often use this in conjunction with the highest control-flow mangling. If you have made a particular study, you are most likely aware that it is a weak XOR cipher.

Usually, ZKM copies all string constants to a static String array and runs them through an XOR algorithm using a randomly generated key array. It then replaces string push instructions with references to the static array. The array is initialized and decrypted inside a static initializer, which contains ZKM’s inlined decryption code. My program works against classes mangled in this way: it copies the keys and strings from the initializer, decrypts them, and replaces the array references with push instructions for whatever string.

First problem: some classes have multiple string arrays or use a decryption method instead of inlining. I don’t know what triggers Zelix to use these, but countering them should be trivial once I know how to detect them efficiently. I doubt anyone has looked at Zelix in depth, but if you happen to know what distiguishes classes to the string encryption routine, I would appreciate the information.

Secondly, a side effect of including decrypted string constants is a bloated constant pool - the now-unused encrypted constants remain in the pool, sometimes adding kilobytes of size. I know of no efficient method for removing a pool entry and correcting reference indicies. If there is a better way to compress a constant pool than comparing a list of all reference indicies with the constant pool itself, I would appreciate that information as well.

Finally, I have attached the source code to this post - just in case anyone feels like commenting on, improving upon, or using my code :stuck_out_tongue:

Kriche, gj. That’s not encryption… but alot of +, -, and equals lol!

And krich, there’s an easier way? LOL I know it’s xor’ed 3 ways in the static initiliazer… I’ve cracked this ages ago.

Now, why not reflect the decryptor method? Lol, and replace the method call with it? Doesn’t that just seem more clever and less dependant on that silly array that if anyone with a brain would change in some way to mangle that? Hell BCEL can execute code, cal the code grab the array values and put er der.

ZKM also mangles strings in another way by replacing strings with a method call to a hashtable, ever tried that one or are you only working on RSC?

“That’s not encryption… but alot of +, -, and equals lol!”
you need to read up encryption, encripytion involves theses!

I think this is for RSC.

Obfuscation does, encryption? Not so much. :-p krypta latin meaning hidden? Cryptology, the field im going into, the study of secret writing.

Looks good Krichevskoy, nice job. I did something like this a long while ago, but it simply modified the pre-decompiled source instead of the actual class files like yours. I think the bcel method is nicer though :slight_smile:

Agreed! <3

I assumed it was brainfuck :stuck_out_tongue:

[quote=“pplsuqbawlz, post:2, topic:19057”]Now, why not reflect the decryptor method? Lol, and replace the method call with it? Doesn’t that just seem more clever and less dependant on that silly array that if anyone with a brain would change in some way to mangle that? Hell BCEL can execute code, cal the code grab the array values and put er der.

ZKM also mangles strings in another way by replacing strings with a method call to a hashtable, ever tried that one or are you only working on RSC?[/quote]

It’s supposed to be a static tool, so reflection doesn’t seem applicable (perhaps I misunderstood you).

Agreed, this is a vulnerable solution - but so is any hack for which someone creates a specific countermeasure. It’s intended to be part of my larger general-anti-Zelix suite, but for now I’m mostly developing this against the playray game applets (I find it easier to analyse Zelix techniques outside the confusion of RuneScape code; also I want to hack minigolf :P) and I haven’t come across any hashtables. What version of ZKM began using it?

Thanks for all the comments.

bumped for usefulness

useful it is.