i am using ndk and android studio to secure my api-key and it works now.
also i am trying dirty code to harden disassembling... .
but i can still decompile and see native methods in java classes.
also pre-built .so(shared object) files are available in apk and wil be used again!
Questions:
After releasing the apk, all hackers can see .so file and they can use custom settings in .mk file and program specific native methods like my class for extracting the api-key only. they call my functions related to api-key without knowing the implementation. am i eliminating something here?
is proguard necessary for this way ?
That's right, there is no way to prevent .so reuse by malicious agent. Therefore, your native API should never reveal secret information to the Java side. You can perform some validation in your native methods to check if the calling Java actually belongs to the legitimate APK.
On the other hand, don't underestimate another vulnerability of native code: your .so can be disassembled with relevant tools, and any protection may be torn off. There exist means of obfuscation and resilience to reverse engineering for native code, but the earning curve for them is much steeper than with ProGuard.
Still, it's worthwhile to at least not keep the api-key in plain text in your C++ code. Try yourself to run
strings libnative.so
(here libnative.so is the .so file extracted from your APK) and you may discover important information that is waiting to be stolen from your library, no sophisticated reverse engineering necessary.
As far as ProGuard is concerned, it does not add protection to the native methods you use. You cannot even obfuscate the class name and method name for a native method. (Well, it is possible, but very tricky, and there are no tools that can help with such setup).
You increase the time hackers will need to decompile and understand the .so file. Estimate how hard it is, and change the way your api authentification works from time to time. Doing so makes previous hacking attempt obsolete, even if they have been successful.
To clarify : put the api-key and the authentification process in the native methods. For instance, for an HTTPS api, send the uri, json content, usertoken, to a native method. Then in the native code, use these and the api-key and some hash functions to create a hash. And output that hash to the Java code to be send in the HTTP request. By doing so, it will be hard to guess the authentification recipe by simply monitoring entries and output. Attackers will have to decompile the native code.
Activate Proguard, compile, decompile, and see for yourself. On my opinion it does raise a good level of complexity for a very easy set up.
We have created a gradle plugin to hide keys in the Android NDK, you can check all the implementation on github : https://github.com/klaxit/hidden-secrets-gradle-plugin
The goal is to make it as hard as possible to reverse engineer keys. We encourage to add a custom encrypt algorithm then keys are stored in the NDK as hexadecimal arrays.
We would love to have feedbacks on our solution !
Related
I am not sure if the terminology is correct what code practices can you use to make it difficult for someone to modify the binary/assembly to bypass a check:
eg in the source code.
bool verificationResult = verify();
if (verificationResult){
allow_Something();
}else{
prevent_Something();
}
If a person looking at the disassembly version of the above code can modify the 'jump opcodes(?)' to run allow_Something even when the verification result is false.
Something similar is covered here
http://www.codeproject.com/Articles/18961/Tamper-Aware-and-Self-Healing-Code#pre0
Note I am creating the binary in C++ for it to be used via NDK on Android.
As the general consensus is so far, its impossible to prevent anyone hell-bent upon "cracking" your APK from doing so. Obfuscation techniques will only increase the complexity required to "crack" the APK once. After it gets uploaded to the myriad of the sites that offer to host APKs for free, its just a google search away from even the "noob-est" of Android noobs.
Also security through obscurity will NOT get you far.
Regarding protecting your APK from being hacked, i would recommend the following article that discusses the current state of license validation of APKs on Android. The techniques described in it should give you an idea of the common attack-vectors that you need to safeguard against.
Proguard is a good place to start obfuscating your APK.
After you manage to obtain an obfuscated APK, DO run it through the following tools and observe the de-compiled source. All these are free and open-source tools that are very popular and will surely be the first thing that any decent "cracker" will try :
1. baksmali
2. apktool
3. Dex2Jar + JD-Gui
Keep adding layers of obfuscation to your code until you are satisfied that the output of the above tools is fairly complicated to make sense. (Again do NOT under-estimate what a college-grad armed with coke, pizza and the knowledge of DVM opcodes can accomplish over a weekend).
Regarding the techniques discussed in the link you shared, i fail to see how they can be implemented to protect the .dex on Android. And if you end up implementing the verification logic in a separate .so then all the "cracker" would need to do is patch the call in your java code to the verify() function inside the .so.
UPDATE:
Additional obfuscation steps to secure the .so.
1. Do NOT follow a more or less linear path.
Adding additional jumps all over the place works by flooding the "cracker" with so many potential targets which need to be individually modified and patched and verified if the protection has been bypassed.
2. Add timing checks
This is mainly to throw off the "cracker" by making the code follow different paths during debug and actual run-time. If the time spent between two points is a lot more than usual then its a clear indication that your program is being debugged. i.e time to jump into that part of junk code that calculates the number of pianos in the world.
3. Write self modifying code
Again this thwarts static analysis. For example if your jump into the verification function does not exist in the binary but is patched everywhere as part of some init() function in the .so.
All the above techniques(and more) are described with examples in the following article on anti-debugging techniques.
A more comprehensive guide is Ultimate Anti Debugging Reference by Peter Ferrie.
Avoid using too transparent checks. Try some basic workflow obfuscating (for example XOR-ing result), this can help to defend against simple opcode replacing. But I assure you, that if someone wants (very-very) to crack you, he can do it regardless of complexity of your protection.
Dexguard is made by the same people who did Proguard, but it allows for even finer-grained options. That said, Proguard is more or less the industry standard for Android obfuscation. Though, as said above, if someone with the know-how wants to crack your app, there's no protection to be had for love or money.
The simple truth: you can't.
You can purchase utilities to obfuscate your object code but they are all trivially bypassed by any slightly motivated attacker. If your user can write to the program image (on disk or in memory) no amount of obfuscation will defend against it.
If it is extremely important, I recommend moving the important component to a device you control and provide some form of challenge-response code to access it. It won't prevent people from cracking it, but it can put up a much more significant barrier against it.
So I published my android app, I proguarded it, applied LVL and even changed some of the LVL code but offcourse, I found it cracked somewhere using a tool called Lucky Patcher. I am not going to ask how can I protect against 1 click tools like that, as I guess there is no single answer ( unless you have an idea and can point me toward).
I need to ask you to help figure out how my code was cracked. I understand that this tool takes APK file and removes licensing. Now given that, how can I take this APK file and reverse engineer it back to Java files to see how the tool cracked my code (so I fix it)
Please help me
Thanks
After Proguard, there's no way to decompile your code into humanly-readable Java.
While it makes the reverse engineering process more difficult, it's not impossible for a clever reverser to figure out the hidden algorithm.
As for tools,
Use android-apktool to decompile to smali and extract all the encoded xml resources.
Use dex2jar to translate Dalvik into jar
and finally jd-gui to see the resulting reversed java code
There's a lot of info here on how to go from a DEX file back to Java source. Also, have you looked at this blog post which addresses many of the ways to protect your source?
piracy is a big issue , and i don't think that any platform or OS can be fully protected from it .
however , google already made some tutorials regarding protection against it , for example:
http://www.google.com/events/io/2011/sessions/evading-pirates-and-stopping-vampires-using-license-verification-library-in-app-billing-and-app-engine.html
also:
http://android-developers.blogspot.co.il/2010/09/securing-android-lvl-applications.html
i think that you can also put some sophisticated obstacles using C instead of java.
also , as google suggests, consider using a different approach : make the core features free , and make the rest purchaseable via in-app billing . you can also add ads and a feature to remove them by in-app billing as well .
I was thinking about this and it seems like if you really wanted to secure your application from hackers there is really only 1 way to do it. You can implement all kinds of fancy methods of insuring your application is licensed and paid for as described in the google article but all it takes is a good hacker to decompile your application and find where the code is and then comment it out or change a function to always return true.
Instead, implement some portion of your application that is required for use in jni/ndk, and check for validation in that code. It doesn't have to be extremely complicated code but you can't just put something like a function (eg. checkValidity) as a user could easily comment the java call that calls into the ndk. Instead you should make some call to your ndk to actually do something that is non-trivial for your application to run -- something the user can't just comment out or switch out with a defined function that does the same thing. From within the ndk code do the verification of your application's integrity/licensing and if it fails kill the application or whatever you need to do.
In order to bypass this the hacker would need to re-implement the ndk code or reverse engineer it.. Which should be much more complicated and not worth while.
This obviously isn't a simple solution and still won't guarantee your application never gets hacked, but it should be much harder to break than the other methods..
I personally think that Obfuscation {Proguard, Dexguard} and native {.so} are pretty effective way to go if used properly.
It definitely deters less experienced 'players' and definitely complicates the life of even experienced 'players'
Don't simply copy/paste the Google android example codes....
Just about to release a free version of my app and I'm looking towards the free-mium model to give extra options to users. However, I'm definitely worried about it being pirated too quickly for me to make any anything.
Does anybody have some quality copy-protection techniques for Android? And I'm not talking about the pos LVL that is provided. I'm looking for some sneaky traps to detect if my code has been tampered with. Any ideas welcome; gotta make it hard enough on them that its just not worth it.
It will only get pirated if it's popular, so you have a long way to go :). Generally, obfuscate your code, don't use the LVL as is since there are tools that disable it automatically. Not sure what your idea of a 'sneaky trap' is, but watch this for some ideas on how to protect your app.
Those are mentioned in the video, but:
use ProGuard to obfuscate your code
to detect if your code has been changed, you can check the CRC of classes.dex or check if the APK has been signed with your certificate (if someone changes your code, they'll have to resign it). However the antilvl tool effectively disables the APIs you would use to check for tampering. So you need to do it in native code if you want it to be effective.
don't do your checks on startup, but later on so they are harder to detect.
if possible, have a server side component to your license/tampering checking. Think about how your app should behave if there is no network connection. Cache server responses? For how long? Deny access right away? Allow access always?, etc.
Protection can always be broken, all you can do is make it harder to break.
Something you might do would be writing some essential part(s) of your code in C and call it via the NDK. Then you can do some testing in there, because decompiling the C part will be much harder than decompiling bytecode.
You can use ProGuard in eclipse to obfuscate your code. It optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names. The result is a smaller sized .apk file that is more difficult to reverse engineer. That way your code will be more tamper proof.
Reference : developer.android
Is there any way to protect an Android applications source code from reverse engineering, as explain in this post: http://blog.darrylsite.com/?p=23 ?
Hm, you are linking to an article in French...
Anyway, using ProGuard should make reverse engineering more difficult, although it can't prevent it completely: Dalvik bytecode contains sufficient clues about an application's structure. Obfuscation (as performed by ProGuard) makes this harder to understand, but given sufficient effort, one will still be able to figure out what is going on.
Your two tools will be code obfuscation and server side-processing.
For the first, obfuscating, the Android team encourages the use of Proguard..
The second is to do your sensitive processing on a server and set up good licensing model. This makes it so the user doesn't have access to even your compiled code. They only get the results of the code and in order to run it you can use licensing to verify they are a valid user. For more information about licensing on Android see Licensing.
Did you take a look at ProGuard?
I want to be a able to securely send data from my Android App to my server using HTTPS and JSON.
With HTTPS i am secure against sniffing but not against decompilation so i will also use Proguard to Obfuscate.
My question is with JSON being a plain text method of sending data a skilled decompiler will be able to work out what is being sent and received. So what is a better way of sending this data - If i assume that at some point someone will decompile the APK or JAR (depending on how i launch the program).
I could obfuscate the JSON
"x":{"xx":12345678}
But again i think it will just be a matter of time before someone works out that i am trying to send a time code etc.
Well... you can't. Sorry. If you could figure this one out, the music and movie industry would make you a hero.
There is no way to prevent decompilation. Obfuscation makes the decompiled results harder to use but a dedicated black hat will still be able to use that.
The best combination I've found is the DojoToolkit and the Closure Compiler in Advanced Mode.
Closure in Advanced Mode makes JavaScript code almost impossible to reverse-engineer, even after passing through a beautifier. Once your JavaScript code is obfuscated beyond any recognition and any possibility to reverse-engineer, your HTML won't disclose much of your secrets.
This link for using the Dojo Toolkit with the Closure Compiler in Advanced Mode for mobile applications:
http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t
If you use the Closure Compiler, you can then throw in an encryption engine writting in JavaScript, then encrypt your JSON data. With the level obfuscation provided by the Closure Compiler, it will be very difficult for people to reverse-engineer your code to discover the key you use to decrypt.