Recently, I found my application is crack by some anti-lvl tools.
This tool could easily crack the "Android License Verification Library" in my application, and generate a new cracked apk.
It also provide lots of function hooks to prevent the developer from detecting their application is cracked. Such as get file length function or check signature function ...
Any one know how to defeat it?
Thanks.
I don't like the standard response of "go check the google i/o presentation" simply because many of the techniques mentioned are defeated by antilvl. It is bad advice in my opinion as the topics, such as reflection and crc checking are already defeated.
Doing further research on antilvl, i came across the svn trunk to antilvl, with a very descriptive hint in a readme.txt file. Here is to prevent antilvl according to the author, prettied up by me. this will return true/false depending on the presence of smaliHook.java, which antilvl uses to hook normal package checks. This only works as a first line of defense, since the class name could be changed with a modded version of antilvl which is likely circulating somewhere. This is a good first check however, since it will defeat the average script kiddie.
protected boolean isAntiLVL(){
try{
Class.forName("smaliHook");
return true;
}catch(Exception e){}
return false;
}
In general - there is no way to fully protect your application in the wild. User might have root access on his/her device and then all bets are off. You can introduce some manual "hackarounds", but if your app is a high-profile one, you will be cracked anyway.
Its just power-play between you and crackers. And if you fight crackers too hard you might hurt your fair users as well.
I'd also refer you to check out this from Google I/O 2011:
Taken from: Avoid apk cracked
Thought it may be very useful to you!
Evading Pirates and Stopping Vampires
http://www.youtube.com/watch?v=TnSNCXR9fbY
EDIT The Presentation Notes: https://docs.google.com/viewer?url=http%3A%2F%2Fwww.google.com%2Fevents%2Fio%2F2011%2Fstatic%2Fpresofiles%2Fdgalpin_android_pirates_and_vampires.pdf
Some basic keypoints
Modify the LVL
Implement LVL Tamper Resistance
Use obfuscation
Use reflection
Related
The Anti-LVL tools make the LVL protection totally unuseful, just a click and you can get the cracked APK.
I have also try to change some switch in if-else in LVL library, to rename lvl package and methods, the tool detect LVL and remove it.
I have also tried
protected boolean isAntiLVL(){
try{
Class.forName("smaliHook");
return true;
}catch(Exception e){}
return false;
}
Without any success.
Any suggestion?
How this tool identify LVL fingerprint?
Please don't reply to this question with something like
-Every protection can be cracked
-A cracker can reverse you source and crack the app anyway
How this tool identify LVL fingerprint?
This page here clearly lists how the Anti LVL works:
Under the hood, AntiLVL is a configurable Smali code patcher with
rules defined in user-modifiable XML files stored inside the jar
called fingerprints. Brief summary of how it works:
Decompiles the Apk
Perform regular expression matching
Carrie out defined modifications
Recompile, update classes.dex
Resign and zipalign
My guess is that simply messing around with package names and checking for your classes will not make a good anti Anti LVL measure.
If you don't want LVL to be cracked by off the shelf software, don't use LVL in your app. Roll your own system that monitors Google Play purchases, and checks them against your server. By doing this, you create a fingerprint different from LVL, so standard tools won't work.
However, the point that anyone can decompile your code, remove this check, and recompile it still stands. Do keep in mind though that those who use pirated copies of your app are very unlikely to have actually been paying for it in the first place, so you are losing very very few customers over this. Those who want to pay, will pay.
you can't edit it, you need your own License System
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.
Is there a way to protect my app from those tools that change the dalvik cache?
I use licensing (heavily modified) and I want to protect it against "lucky patcher tool" found here.
Any idea how?
Please help
Thanks a lot
Have you actually researched it?
To quote from that site linky:
Lucky Patcher is a great Android tool to bypass premium applications
license verification, remove ads, modify Permissions, and more.
To use this application, you need a rooted device.
Know: Although stable, functioning of Lucky Patcher can't be
guaranteed at 100%. So you are solely responsible of use of this
application. Under no circumstances Netbew be responsible for any
problems caused to your device (rebooting loop, unstable system,
etc...).
Do not bother wasting time in protecting your app from that!
Sorry, if this answer is not what you're looking for, but it is plain and simple, forget anti-cracking - use proguard.
One is bound to find out how to crack it, don't use LVL, regardless if you claim its heavily modified.
And anyway, crackers out there has the time and resource to pirate and crack apps and any anti-cracking is bound to be broken in a very short space of time!
Focus on functionality and satisfying your end users!
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.