I am developing a payment processing app for Android, and I want to prevent a hacker from accessing any resources, assets or source code from the APK file.
If someone changes the .apk extension to .zip then they can unzip it and easily access all the app's resources and assets, and using dex2jar and a Java decompiler, they can also access the source code. It's very easy to reverse engineer an Android APK file - for more details see Stack Overflow question Reverse engineering from an APK file to a project.
I have used the Proguard tool provided with the Android SDK. When I reverse engineer an APK file generated using a signed keystore and Proguard, I get obfuscated code.
However, the names of Android components remain unchanged and some code, like key-values used in the app, remains unchanged. As per Proguard documentation the tool can't obfuscate components mentioned in the Manifest file.
Now my questions are:
- How can I completely prevent reverse engineering of an Android APK? Is this possible?
- How can I protect all the app's resources, assets and source code so that hackers can't hack the APK file in any way?
- Is there a way to make hacking more tough or even impossible? What more can I do to protect the source code in my APK file?
Its not possible to completely avoid RE but By making them more complex internally, you put make it more difficult for attackers to see the clear operation of the app, which may reduce the number of attack vectors.
If the application handles highly sensitive data, Various techniques exist which can increase the complexity of reverse engineering your code. One technique is to use C/C++ to limit easy runtime manipulation by the attacker. There are ample C and C++ libraries that are very mature and easy to integrate with Android offers JNI. An attacker must first circumvent the debugging restrictions in order to attack the application on a low level. This adds further complexity to an attack. Android applications should have android:debuggable=”false” set in the application manifest to prevent easy run time manipulation by an attacker or malware.
Trace Checking – An application can determine whether or not it is currently being traced by a debugger or other debugging tool. If being traced, the application can perform any number of possible attack response actions, such as discarding encryption keys to protect user data, notifying a server administrator, or other such type responses in an attempt to defend itself. This can be determined by checking the process status flags or using other techniques like comparing the return value of ptrace attach, checking parent process, blacklist debuggers in the process list or comparing timestamps on different places of the program.
Optimizations - To hide advanced mathematical computations and other types of complex logic, utilizing compiler optimizations can help obfuscate the object code so that it cannot easily be disassembled by an attacker, making it more difficult for an attacker to gain an understanding of the particular code. In Android this can more easily be achieved by utilizing natively compiled libraries with the NDK. In addition, using an LLVM Obfuscator or any protector SDK will provide better machine code obfuscation.
Stripping binaries – Stripping native binaries is an effective way to increase the amount of time and skill level required of an attacker in order to view the makeup of your application’s low level functions. By stripping a binary, the symbol table of the binary is stripped, so that an attacker cannot easily debug or reverse engineer an application.You can refer techniques used on GNU/Linux systems like sstriping or using UPX.
And at last you must be aware about obfuscation and tools like ProGuard.
AFAIK, you cannot protect the files in the /res directory anymore than they are protected right now.
However, there are steps you can take to protect your source code, or at least what it does if not everything.
10000
coins. Instead of saving10000
directly, save it using an algorithm like((currency*2)+1)/13
. So instead of10000
, you save1538.53846154
into the SharedPreferences. However, the above example isn't perfect, and you'll have to work to come up with an equation that won't lose currency to rounding errors etc.$200
. Instead of sending a raw$200
value to the server, send a series of smaller, predefined, values that add up to$200
. For example, have a file or table on your server that equates words with values. So let's say thatCharlie
corresponds to$47
, andJohn
to$3
. So instead of sending$200
, you can sendCharlie
four times andJohn
four times. On the server, interpret what they mean and add it up. This prevents a hacker from sending arbitrary values to your server, as they do not know what word corresponds to what value. As an added measure of security, you could have an equation similar to point 3 for this as well, and change the keywords everyn
number of days.All in all, there's no way to protect your app 100%. You can make it harder, but not impossible. Your web server could be compromised, the hacker could figure out your keywords by monitoring multiple transaction amounts and the keywords you send for it, the hacker could painstakingly go through the source and figure out which code is a dummy.
You can only fight back, but never win.
Developers can take following steps to prevent an APK from theft somehow,
the most basic way is to use tools like
ProGuard
to obfuscate their code, but up until now, it has been quite difficult to completely prevent someone from decompiling an app.Also I have heard about a tool HoseDex2Jar. It stops
Dex2Jar
by inserting harmless code in an Android APK that confuses and disablesDex2Jar
and protects the code from decompilation. It could somehow prevent hackers from decompiling an APK into readable java code.Use some server side application to communicate with the application only when it is needed. It could help prevent the important data.
At all, you can not completely protect your code from the potential hackers. Somehow, you could make it difficult and a bit frustrating task for them to decompile your code. One of the most efficient way is to write in native code(C/C++) and store it as compiled libraries.
Impossible
Impossible
More tough - possible, but in fact it will be more tough mostly for the average user, who is just googling for hacking guides. If somebody really wants to hack your app - it will be hacked, sooner or later.
Here are few methods you can try:
Aren't TPM chips (Trusted Platform Module) supposed to manage protected code for you ? They are becoming common on PCs (especially Apple ones) and they may already exist in today's smartphone chips. Unfortunately there is no OS API to make use of it yet. Hopefully Android will add support for this one day. That's also the key to clean content DRM (which Google is working on for WebM).