Showing posts with label obfuscation. Show all posts
Showing posts with label obfuscation. Show all posts

Monday, December 8, 2014

Simplify - Android Deobfuscator / Decryptor

Here it is: https://github.com/CalebFenton/simplify
I'd build you a jar, but there have been a lot of commits recently, and you'll probably want to build it yourself.

It decrypts most types of string encryption and can remove some types of obfuscation, especially code that doesn't actually do anything.

This may be all you want to know. But this has got me thinking about optimization and deobfuscation, so continue on if you're into that sort of thing.

App obfuscation and string encryption are getting more popular, and they can be annoying as fuck. But, fundamentally, obfuscators just apply a set of rules to code, and the rules aren't that complex, because complex is really hard. It's just a thin layer of changes added on top. Intuitively, this means a general solution for undoing the changes probably takes a little more effort to undo than it did to conceive the original rules. So no matter how bad things get for crackers, it should always be possible to make a tool to fix things up.

In the PC scene, obfuscators are more evolved, but so are the deobfuscators. Just look at the feature list on this: https://github.com/0xd4d/de4dot. It's a deobfuscator and an unpacker, plus it supports a huge list of stuff.

There are a few tools like this for Android, but they are not nearly as complex (yet). Time for bullet points!
Simplify deobfuscates by virtually executing an app and analyzing the execution afterwards. So if there is an encrypted string that gets decrypted at run time, Simplify will see the encrypted, see it passed to the decryption method, and see it get get decrypted. And after it knows the value, it can remove the encrypted value and the decryption method call as redundant and replace it with a 'const-string' instruction with the decrypted literal.

It's not all the way cooked yet, but the idea is solid, and there are some interesting issues github page I'd quite like to see implemented. One of them is deobfuscating reflection.

Also, anyone who takes the time to create issues on github and follow through with closing them when they're resolved, is probably more than a little obsessive. Should be fun to watch.

Saturday, January 26, 2013

string decryption with dex2jar

i have been getting a lot of questions about string decryption lately, so let's talk.

let's say you have an app and notice encrypted strings. strings are an easy way to get a basic idea of what code is doing so naturally you want to decrypt them. but how? there are many different ways to encrypt strings and then decrypt at runtime but in practices there are some assumptions we can make in decreasing order of likelihood.

1. the encryption must be reversible. the strings must be decrypted at run time somehow. this is good but we can assume even more.

2. the process is automated. when Alice wants to release her app she puts the source code through an automated modification process which iterates over every string literal, encrypts it and replaces it with a call to a decryption method with the encrypted string as a parameter.

3. decryption is the same or nearly the same for each string. there is only one decryption method.

4. the type signature of the method is:
static String decryptMethod(String)

while these assumptions hold, it is not very difficult to create a general technique by which we can decrypt all of the strings of an app in place. the real question is do you want to do it at the java or smali level? if you primarily look at decompiled code you can work at the java level. and you're in luck, such a tool already exists in dex2jar: http://code.google.com/p/dex2jar/

there is a wiki article about it here: http://code.google.com/p/dex2jar/wiki/DecryptStrings but it is unfinished. you can at least get a visual for what the decompiled code will look like before and after. if you're a good person, you will update the wiki. i leave that as a task for some good reader.

the tool is currently incorrectly spelled as d2j-decrpyt-string.(sh|bat). it takes at least two parameters and sometimes needs three. they are:
  1. method name, -mn : in our case, decryptMethod
  2. method owner, -mo : let's say com.alice.utils
  3. class path, -cp : if decryptMethod makes use of any framework api, you will need to give the path to a framework.jar from the android.sdk
d2j-decrpyt-string -mn decryptMethod -mo com.alice.utils -cp ~/android/sdk/platforms/android-4/framework.jar

doing this at the smali level requires access to a dalvik vm, so in that regard it is trickier, but there are many emulators and you can even use your phone. here's how the process can work:
  • pull out all of the strings and put into a file
  • write some java code, unless you're comfortable with smali, to open the file and iterate over each line and call the decryption method on each string.
  • compile java bytecode and convert to dalvik executable with dx from the android sdk
  • run the code on a dalvik vm

Sunday, February 13, 2011

antilvl 1.1.3

just put up antilvl 1.1.3. a few small but annoying bugs fixed and some improvements with the hooks. pick it up from the usual spot: http://androidcracking.blogspot.com/p/antilvl_01.html

also had to do some major refactoring so people could make use of the source once it's released, and i think i got most of the kinks out.

while working on this, i noticed a few more apps that were using string encryption. maybe it will start to get popular? i wrote a proof of concept decryptor just to see how feasible it would be to convert dex to java .class files and run the apk's own methods to decrypt the strings. it worked but i want to make something more general. here's my idea:

  • start with an apk and disassemble
  • chose to decode literal strings (ex: const-string "some-encoded-string") or assume strings are the result of a function call (ex: invoke-static LStringHolder;->getString(v0)).
  • show all lines that match the above selection and allow for regex filtering. this way, if you pick literal strings and not all strings are encoded, you can filter for just the ones that are
  • decode strings by one of several methods: run the function, in the case of function-call encryption, built-in stuff like base 64, etc. or by using reflection on the classes of the apk. this way if every literal string in the apk is decoded through some function, i could use dex2jar to get the java class, dynamically load that and run each string through it.
the goal is to make the tool generic enough so that it's useful in the most situations. shouldn't be too hard. half of the work will be making my patching and apk libraries more generic and useful, so it wont be a total waste of time.

Friday, November 5, 2010

string obfuscation

a common practice in pc apps is string encryption. when a program is compiled all literal strings are replaced with function calls with a parameter that retrieve that specific string. the result is when the program is decompiled it is not possible to simply search for strings. string searching makes finding interesting locations in code much easier so preventing this makes cracking more difficult for more people. recently, i came across some string obfuscation. this is the first time i have seen it "in the wild". proguard does not do it because it necessarily requires more work from the processor and may slow things down slightly.

how can we defeat it? it is difficult to analyze dalvik code and perform the encryption process in reverse without damaging other code (at least for me), but it is very simple to merely call the function for every possible string. here is an example: StringDumper.smali

StringDumper will output decrypted strings to the log file. the encrypted strings in my case were held inside StringHolder.smali and were retrieved using getString(I)Ljava/lang/String. there were only 0x15 strings, but if you run into this specific type of encryption there may be more or less.

it is not likely you will see this exact, specific encrypter implementation since i suspect it was developed in-house and is not open source. at least you will have a general idea of how to defeat such protection.