Let’s have a quick look at one feature of this well-known Android application protector, the string encryption mechanism. The app in question is a version of Cyanide.
First, access to strings inside a protected class are replaced by calls to a static private decryption routine. That routine accesses a static private array containing all protected strings within the class. That array is created by the class initializer upon loading:
The decryption routine usually takes 3 arguments, although in some simpler cases, it may only take two arguments. The arguments may also be shuffled. (Note: from a Dalvik standpoint, that routine is oddly structured. Although JEB’s decompiled output is structurally fine, a for-loop construct cannot be created, mainly because of the irregular jump inside the first if-cond branch.)
The screenshot below represents that decryption routine. The name was obfuscated by the app protector. Notice the constant numerals that have been circled in that code snippet: they are the decryption routine characteristics.
The following screenshot shows the same piece of code after marking it up. As you can see, the encryption algorithm is fairly simple: the current output character is derived from the previous character as well as the current byte of the encryptedStrings array. A constant (-8 in this case) is added to yield the final character. The initial length (length) as well as initial character (curChar) are also offset by hard-coded constants. These three constants (0x3E, 0x199, -8) characterize the decryption routine, and are unique for each routine. The curChar parameter acts as the decryption key.
You may customize this Python script to decrypt the strings:
#!/usr/bin/python # decryptor # customize strings = [0x4C, 0xE, 2, 9, -7, 0x10, -54, 0x3E, 0x17, -9, -44, 0x4C, 0xA, ...] c0, c1, c2 = (0x199, 0x3E, -8) def decrypt(length, curChar, pos): length += c0 curChar += c1 r = '' for i in range(length): r += chr(curChar & 0xFF) curEncodedChar = strings[pos] pos += 1 curChar = curChar + curEncodedChar + c2 return r
Combined with reflection (another feature of the protector), the protection can be pretty effective.
10 thoughts on “A look inside an Android app protector”
So, as I understood, it does not make any sense to spend money to buy Dexguard. Right?
I am thinking how to hide string data in apk. In .NET word it is easy…
Dexguard is effective for blanket processing. However, like nearly all protections, it will only slow down a determined attacker.
DexGuard has been updated a couple of times in the meanwhile, so the above techniques no longer work… DexGuard’s goal is to raise the bar against reverse engineering and cracking. It is pretty effective — even security experts spend a lot of time studying its output, which is different for every application.
(I am the developer of ProGuard and DexGuard)
Thanks for sharing!
I checked this, but found it is still an advanced Java obfuscation. Also I tried many ways except this one. You may try APK Protect PC Edition. This is free and have the same function.
I noticed a very effective method. APK Protect Professional Edition, this is very different from other methods: http://www.apkprotect.com.