Unhosing APKs

Recently, there has been some discussion in the press about a tool named “HoseDex2Jar”, which claims to prevent wily hackers from being able to decompile Android APK files back into Java class files. Such a tool would be very useful; it is claimed. It is purported to prevent said hackers enacting their nefarious actions and protect assets within an Android applications developers are trying very hard to protect. In fact, the president of the company offering the service is quoted as saying, “We realized if there was a way to stop Dex2Jar, we would stop all Android decompilation.”.

While we think it’s great to see folks moving in a direction to raise the security bar for mobile applications, claims such as this are a bit misleading. To understand why, it’s important to realize that there are a couple of very different things meant by “decompiling” when it comes to the Android platform.

The HoseDex2Jar tool claims to prevent people from running the tool “dex2jar”, which is a utility that converts the Android APK “classes.dex” file back into Java classes. The java classes can then be turned back into readable Java code using any one of various Java decompilers available (there are both open source and commercial versions of such tools).

What the HoseDex2Jar tool does not claim to do, is prevent the conversion of the classes.dex file back into the Dalvik disassembly, called smali. While it can be handy to convert APK files back into Java classes – because Java can be easier to read than smali - we’ve found that using the smali code tends to be provide better results. That is because, the smali code is more accurate, and because it is essentially Dalvik disassembly,  it is almost always easier to manipulate and alter when attempting to develop a meaningful attack. When converting APKs back into Java, the decompilers need to make a lot of guesses about the code, which results in a distortion from the original application. It’s useful as a quick overview, but it’s generally not able to be altered, and then successfully recompiled back into a new APK. (We wrote about this a bit a couple years ago.)

Because HoseDex2Jar only prevents the flawed “to Java” version of Android decompilation, completely ignoring the much more accurate decompliation into smali code,  the claim that HoseDex2Jar prevents all Android decompilation is not only completely false, it’s almost useless as a security measure.

As an example of how futile this is, we used the HoseDex2Jar tool to “protect” a small app we wrote. We registered with the web service, and obtained our “hosed” APK back. Sure enough, running dex2jar on the hosed APK failed, with a Java null pointer error:

dex2jar info.dc585.SMSniffer-1-HOSED-MUST-RESIGN.apk -> info.dc585.SMSniffer-1-HOSED-MUST-RESIGN-dex2jar.jar

at org.objectweb.asm.Type.getType(Unknown Source)
at com.googlecode.dex2jar.v3.V3ClassAdapter.build(V3ClassAdapter.java:193)
at com.googlecode.dex2jar.v3.V3ClassAdapter.visitField(V3ClassAdapter.java:247)
at com.googlecode.dex2jar.reader.DexFileReader.acceptField(DexFileReader.java:607)
at com.googlecode.dex2jar.reader.DexFileReader.acceptClass(DexFileReader.java:442)
at com.googlecode.dex2jar.reader.DexFileReader.accept(DexFileReader.java:333)
at com.googlecode.dex2jar.v3.Dex2jar.doTranslate(Dex2jar.java:82)
at com.googlecode.dex2jar.v3.Dex2jar.to(Dex2jar.java:219)
at com.googlecode.dex2jar.v3.Dex2jar.to(Dex2jar.java:210)
at com.googlecode.dex2jar.tools.Dex2jarCmd.doCommandLine(Dex2jarCmd.java:108)
at com.googlecode.dex2jar.tools.BaseCmd.doMain(BaseCmd.java:118)
at com.googlecode.dex2jar.tools.Dex2jarCmd.main(Dex2jarCmd.java:34)


However, baksmali had no problems, nor did apktool.

apktool d -d info.dc585.SMSniffer-1-HOSED-MUST-RESIGN.apk
I: Baksmaling...
testI: Loading resource table...
I: Loaded.
I: Loading resource table from file: C:\Users\user1\apktool\framework\1.apk
I: Loaded.
I: Decoding file-resources...
I: Decoding values*/* XMLs...
I: Done.
I: Copying assets and libs...


More interestingly, simply using apktool to repackage the directory, without making a single change to smali files, is also successful:

apktool b -d info.dc585.SMSniffer-1-HOSED-MUST-RESIGN info.dc585.SMSniffer-1-DEHOSED.apk
I: Checking whether sources has changed...
I: Smaling...
I: Checking whether resources has changed...
I: Building resources...
I: Building apk file...


And guess what? After running the two very simple commands above, we can now simply use Dex2Jar again, despite the fact that this APK was initially hosed:

dex2jar.bat info.dc585.SMSniffer-1-DEHOSED.apk
7 [main] INFO pxb.android.dex2jar.v3.Main - dex2jar info.dc585.SMSniffer-1-DEHOSED.apk -> info.dc585.SMSniffer-1-DEHOSED.apk.dex2jar.jar



Edit: So, it turns out that unhosing is even easier than we initially thought: if you use versions of dex2jar <, the hosed APK is able to be decompiled back to Java classes as though no changes occurred at all. It appears that the company offering this service only tested their success on the current version, and not on prior incarnations.

Published date:  05 October 2012

Written by:  jross

comments powered by Disqus