People embrace the open nature of Android, and that is something that empowers innovators to build groundbreaking products. But only a few know the dark side of this openness, Vulnerability. Our apps are always vulnerable to attack as Android does not render its code into machine code, leaving it prone to extraction. The vulnerable code can then be used for a variety of reasons, which should be daunting for any serious mobile app business.
An extracted code can result in decreased security, freely available in-app purchases and can lead to misleading user data that could result in bad pricing elasticity. These are some of the common reasons why someone would decompile your code, and you can now understand a little bit of the damage they can put you through. Security is even more of a concern when your app deals with healthcare or financial data.
I often come across threads like this one,
A good company will never go behind their clients back and develop a similar app for a rival, and most developers won’t leave their name within the app’s code. However, a few developers leave their name inside the comments, which can then be used to extract the agency or freelancer that developed it. But that isn’t what I want you to take from this thread. By now, you should understand and notice that people are actively trying to decompile your apps, and you need to do something about it.
To further illustrate the seriousness, this thread clearly outlines how easily one can decompile your APK, even if it’s encrypted. Brendan was able to decompile a TwoFish encrypted paid app using just a few tools.
See how easy it gets when you use a decompiler
Decompiled an Android app back to Java code. Surprisingly easy when used to decompiling native code. Bytecode is almost Java code 🙂
— Maya Posch (@MayaPosch) June 21, 2015
So, how do you stop anyone from gaining access to the source code?
Put important code on a Server
You may rely on remote procedure calls to a well protected server. This reduces the chance of your codes being stolen as the code will always remain on the server and nothing other than the results can be seen. However this does have a shortcoming, if your app is going to be used by a lot of users(millions), you will need to have a huge server farm.
A server farm is a huge expense and most of the time, is not a viable solution. Furthermore, in the case of low network connectivity, it leaves your code fragile and adds frustration for your users.
100% code security is costly, but the good news is that you probably won’t need it. A better solution is to keep the code that you don’t want to get out, in a hardware that you control. When you stop distributing the key parts, it makes the attacker’s work much more painful. Trying to protect all client apps also means a heavy investment and less ROI. Whereas safeguarding a server is much easier- both electronically and physically.
To add more security, you can also add double obfuscation to tackle any “man in the middle” attacks. Furthermore, the app will always send the received token to the server to request actions to be taken. Google Wallet is one such example, they rely heavily on tokens to process requests.
What else can you do?
It is an obfuscation tool that helps safeguard applications using a licensed server. It increases the difficulty of ‘reversing’ your code. DexGuard, a commercial version of Proguard, goes an extra mile and helps a little more. But your code can always be converted into samli, which can be used by developers to learn what you do with it. Again, if you don’t want others to see your code, don’t store it on their device.
Debugger Detection Techniques
There are some other creative ways to safeguard your code They involve using debugger detection techniques that you can utilize to prevent run-time-analysis and combine it with encryption of portions of binary codes. But, any enthusiastic attacker can find a way to work around it. If you are looking for more information on a specific debugger detection technique, you should have a look at OpenRCE Anti Reverse Engineering Techniques Database. It provides analysis and descriptions for various anti debugging, disassembly and dumping tricks. Many of the techniques are listed in conjunction with a specific target, but they may be adaptable to other targets.
Write important parts of code in C/C++
You can also write the important parts of your code in C/C++ and add them as a compiled library. While it can be disassembled into assembly code, reverse engineering a large library from assembly is extremely time-consuming. Java is easier to decompile in comparison to C/C++.
Write files natively into .so files
Using NDK you can write the files natively into .so files, which are much less likely to be decompiled than APKs. There are a few good decompilers available, but that would require the attacker to be proficient in ARM processor architecture, assembler language, JNI Conventions, and Compiler ABI. You are giving the proficient attacker a few sleepless nights.
Obfuscate values when storing them on mobile
For protecting your app’s resources when storing values on the device, don’t store them in a raw format. Store them in the form of some algorithm, i.e. 50 reward points in your app could be (x*(x^2 + 1 – Neutralizing factor))/(x+1). However, you need to optimize your algorithm so that you don’t end up on compromising while rounding up values.
Add multi-factor security
It is extremely important to stop the attacker from getting any access from the user’s device itself. You can also make the attackers work difficult by adding multi-factor security by remembering the information about the devices, and providing additional channels for identifying a login attempt from an unfamiliar device.
Some even suggest usage of tools like HoseDex2Jar, but it is very easy to defeat. In fact, tools like smali and apktools work fine with these APK’s.
What Matlab did
One inspirational anti-piracy measure comes from Matlab, a desktop based software. Matlab protects the source of a deployed application by ‘Deploying as P-code’ or ‘Compiling into binary format’ This however does not apply to android, as it is open and rootable. The attacker can easily find the key from the system itself. Having access to the system implies having access to the keys.
The idea is to stall the attacker as much as possible. Sadly, a determined hacker can always access your codes, reach your server, watch your requests and find the keywords.
Take good note of the text below which arises from the principles of foundation of Information Technology security:
- Whenever someone gains physical or electronic access to the machine, the machine belongs to the attacker.
- An attacker cannot penetrate the code in your systems, but attacker can penetrate the code when it leaves the impenetrable physical boundaries.
- When information leaves inaccessible boundaries, an attacker can always get that information.
Have some tips and tricks in mind? Shoot us a comment!