I'm new to android and I don't know much about software engineering. I wanna know about things should be done to make it harder to decompile an app. I made some research about it and I ran into this debugger JEB which seems like it can monitor some stuff while app running. Yet I don't know the advantages of using it since I don't get the critical points of an android app which is being monitored by JEB. for example:
enter image description here
appearantly the right side shows local variables. what does x / xh means for an int? or for the string value "secretKey" is the value of string seriously? if it is then all variables in my code are at risk!!!??
I think maybe one of the attempts is to make a lot of fake variables in code so that the real ones can't be seen easily. Does it make sense? And are there other leaks that I should try to prevent for example about this JEB? Does proguard have anything to do with this? As I said I donno much about soft-eng and I didn't get to understand what proguard actually does.
And another thing I've seen is https://ibotpeaches.github.io/Apktool. How to make it more mixed up for such tool to handle?
The last question, I code in java and don't think yet I have the opportunity to start native coding but for future; I've seen people say its safer to code natively. Is it by itself? or there are more libraries to keep more safety? or its because of the final apk structure?
sorry if some words look dumb. thanks in advance
You should not try to prevent reverse engineering, because doing so is largely futile. Instead, you should design your app to minimize the effect that reverse engineering would have (i.e. you should not include secret data like keys or passwords in the app).
The amount of effort that people are willing to put into reverse engineering your app depends on how important and popular it is, while obfuscation increases the effort required to reverse engineer the app. However, if your app becomes popular, no amount of obfuscation will stop people, while if it languishes in obscurity, nobody's going to bother to look at it, even if you post the source code on Github. Also, in rare cases, adding obfuscation will make people crack it just for the challenge.
Apart from that, there is the risk that obfuscation will give you a false sense of security. Anyone can devise a system that they themselves cannot break, but if you aren't an expert at reverse engineering, the measures you come up with are unlikely to stop those who are. It is best to instead assume that everything in your app is public information and design accordingly.
You can protect your code by using some powerful obfuscator tool like: Bg+Anti Decompile/Reverse Java
It has a lot of protection options:
Hide string value (helpful when you keep some sensitive info in java source, ex: "Hello world" ->ߤª )
Obfuscate with unicode characters
Hide packagename
Add fakecode to trap the decompiler tools
Check resource-string (helpful when someone try to edit the resources of your APK)
....
Related
I have given up trying to get Proguard to work on either Eclipse or Android Studio. The docs are arcane and whatever I try, the Proguard obfuscated apk blows. Also questions regarding Proguard don't get much attention on this forum.
Standard Android apk files are designed to almost invite reverse engineering and I'm looking for some ways to protect my code. Not all my code just some methods.
Before I started writing Android apps, I wrote apps in C and in C# and I'm familiar with both of those languages and actually prefer either of them to Java so I've recently been reading about the NDK.
Of course the NDK is about speed but I'm wondering if it also would help protect my code against reverse engineering and inspection from hackers. I understand that it is "compiled" code so I imagine that the source code would not be visible.
Am I barking up the right tree?
Thanks,
Dean
This depends on what kind of protection you are looking for. If that is a revolutionary algorithm that will allow you do some very popular task much much faster than it takes today, then your code will be reverse engineered, no matter how you obfuscate it; you need patent protection. If you want to hide some unfriendly behavior (like spying on your users), it will be discovered. So don't do it. If you want to protect some protocol of client-server communication, it may be subject to easy attack elsewhere.
But in some cases going C++ does really help; it may be easier to distribute a monolithic shared library "black box" than to deal with Java API. I don't think obfuscation can work on code that you sell as library.
When we were selling a huge communication SDK, we followed this approach, and all our Java code was simply open to customers (part was intended to be changed/customized, but some classes carried a warning in the header "Please don't modify this class, there is very high chance that the product will not work properly if you mess with it".
Native C code is harder to decompile but it can be decompiled easily using the right tools.
Especially if you only develop small parts in C and then communicate with it using JNI which is a clear interface, anybody who decompiles your app can also use it. Who needs to know how your code works if you can simply execute it?
Conclusion: native code can be harder to decompile. But usually the only difference is that you need different tools and you need more knowledge & practice to decompile. Also modifying something is usually more complex.
Just implementing some methods in NDK alone will not likely help a lot. However, the resistance to reverse engineering can be improved if you also apply obfuscation and even run-time protection techniques to your NDK code. A simply web search gives a list of free tools. You could also work with commercial solution providers like Arxan. In addition, the level of obfuscation can generally be improved if you put more logic of your app in native code.
Yes if you use the NDK you can make it very difficult to reverse engineer your code and it is unlikely anybody would try.
Is there a way to somehow 'protect' a native shared library (.so) for the Android platform against binary changing?
E.g. someone could overwrite a JMP instruction with a NOP after reverse engineering the application, and distribute that library to rooted devices.
Is there anything someone can do?
What I'm looking for here is ideas about implementing a series of checks (e.g. encryption, checksumming etc).
Of course since the platform does not look like it offers support for this (correct me if I'm wrong) it would have to be all 'client-side'. Thus the whole thing is a bit futile, but at least will hinder reverse engineering some.
Yes there are things you can do, and they will make it very challenging for the Reverse Engineer, but I doubt you'd be able to do anything that would stop Chris Eagle.
The best way to protect from modification is to take a SHA-2 of the .so after you compile it, and rehash each time at runtime, matching it against the known value. This check will be enforced on the client side, so a skilled RE could just modify the binary to ignore the check. It does make it a bit harder though. If you put checks all throughout your code and use different checking techniques then it extends the amount of work the RE has to do. Do know however that Microsoft has poured millions of dollars into anti-RE techniques and there are still pirated copies of Office and Windows out there. You'll never stop them all. My personal philosophy (now that I've studied RE myself) is that it is ultimately too much of a pain to try and stop them. Just make a good app, make it cheap, and people will buy. The miscreants that steal your stuff wouldn't have bought it anyway.
If your app calls home you could also submit the hash to the server for verification. Of course and RE can still bypass this but it is one more thing to do.
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....
For the paid version of my app I'm opting for the unlocker app route because it's easy to implement, allows for individual stats in the Developer Console but mostly because I wouldn't need to maintain 2 code bases (one for the free version and another for the paid version). Even If I used a CVS (which I do) it would still be a pain in the neck to keep merging features and bug fixes. The unlocker app is much easier to implement overall...
But this comes with a serious disadvantage, it's really easy to overrun the security check; unless I'm missing something here.
No matter what I do, such implementation will always lead to a simple if, like this:
if(Program.isPremiumVersion()) {
// Remove ads...
}
The isPremiumVersion() method is the one responsible for all the work in checking for the paid unlocker app installation, if the certificates match and all that stuff. Yes, the unlocker app is protected by the LVL (although I've read a few articles mentioning how insecure LVL is, but that's not the point right now). But in the end, no matter how complex the code inside isPremiumVersion() gets, it always results in returning a true or false value.
Overriding such security feature is just a matter of reverse engineering the code and get it to always return true. Is it not? How can we protect our Android apps against this? And yes, the code is obfuscated with ProGuard. Still, shouldn't be too hard for someone skilled enough.
Please note that I'm not trying to fight the crackers, we simply cannot win. I'm not going to lose sleep over this, wasting countless hours on the "perfect solution". I'm just looking for a way to make it a little more secure. This just seems so simple to crack, in theory at least. Am I wrong though?
Any ideas to improve the security of such feature?
There is no easy way around this.
You have to try to mask it. Here are a few tips:
Tip 1: Returning boolean is too obvious. Try returning a value (int, for example). Then, use a comparison to see if that is a valid known return value.
For example: get the md5 of a string that contains something from which you can tell if it's premium or not. Say that you've got a static final string on each app. Maybe the md5 of one starts with a 9 and the other starts with a 1. In this case, calculate the md5 and see if it's greater than a "random" number that you know it's in between the other two numbers. Say that the md5 of "premium" is 987 and the md5 of "free" is 123. You can calculate the md5 and compare it to 456.
Tip 2 - Even better: duplicate some code and use different values every time (instead of 456)! Hopefully this will make it more difficult to decode the obfuscated code.
I know that all these checks will eventually be mapped to a boolean (if(1 > 2) will be evaluated to if(true) ) but it should be more difficult to reverse engineer your app.
Tip 3: don't run the checks for "isPremium" in the most obvious places. For example, don't do the check when you start your app as this is the most obvious place to do it. It might be difficult to avoid certain obvious spots if you want to have conditional logic depending on the version of the app, but do your best here!
Tip 4: build and obfuscate your app. Run reverse engineering tools against your apk. Read it and see how it looks.
Finally, watch this Google IO presentation everyday at breakfast: Evading Pirates and Stopping Vampires using License Verification Library, In-App Billing, and App Engine
[EDIT - a few more tips]
Tip 6: try to use the code you use to check in perfectly valid places. This might disguise what you are really doing in there. This might include calling the code to check which version of the app this is, but doing nothing meaningful with it. Or, in my previous example, comparing the md5 with 012 or 999, just for the sake of diluting the real use of these variables.
Tip 7: instead of relying in a single string, you might considerer constructing the string at run time. Finals and statics might draw too much attention too, so avoiding those could be a good thing.
Tip 8: don't ever use the LVL code as provided in google tutorials. Modify it. A lot!
Note: I'm not sure if any of these tips will actually make a big difference, but you should have good chances of at least making crackers' life a bit harder.
You may have already seen this, but here is some code for implementing what you are talking about:
http://groups.google.com/group/android-developers/browse_thread/thread/4ad3d67f735f16d7/948b4f9eee2490a3?pli=1
It checks that the signatures on the free and unlocker app are the same. So it is not possible for someone to artifically create an app with the correct name as the signitures will be different. However, it is still possible for people to rip the apk off the phone and distribute that. The only way to combat that would be to use some sort of server authentication but this adds cost and complexity.
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