3

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.

pt123
  • 2,146
  • 1
  • 32
  • 57
  • If you used some deterministic common/general code best practice then it would likely be easy to detect and defeat and always call allow_something() – old_timer Jun 27 '13 at 05:49
  • would you be able to expand on what constitutes 'deterministic common/general code best practice'? – pt123 Jun 27 '13 at 07:04
  • You can check cryptographic hash value of `.so` library before loading. But then with what value you are going to compare, if you can keep that value safe becomes the next problem. – auselen Jun 27 '13 at 11:43
  • This is just an offtopic remark: Why not to put your procedural or license data on an application server and perform checks against it? – Vasiliy Stavenko Jul 04 '13 at 02:52
  • Vasily - too much overhead in purchasing a server and creating the application for it. I just wanted to know if there were coding techniques to make it difficult modify the jump codes. I have searched the internet and could not find any. – pt123 Jul 04 '13 at 02:57

4 Answers4

6

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.

Community
  • 1
  • 1
TheCodeArtist
  • 21,479
  • 4
  • 69
  • 130
  • Regarding >>all the "cracker" would need to do is patch the call in your java code to the verify() function<< lot of the other app logic is kept inside .so file, if that c++ object is not showing OK for verification other app logic in the .so file fails ......Java seems to be useless as a hacker can decompile it to source code and replace any verification, hence why my question is about c++ code and .so files, every poster seems to ignore this and just talks about java, dex files, and proguard. – pt123 Jul 04 '13 at 11:47
  • @pt123 Updated the answer with techniques to safeguard the `.so`. – TheCodeArtist Jul 05 '13 at 02:23
1

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.

trashkalmar
  • 883
  • 5
  • 11
  • is there another term for 'workflow obfuscating' when I searched Google I got no useful results. I just want to make it difficult, I don't want it where some script kiddie changes a line in binary file to break the protection – pt123 Jun 30 '13 at 00:47
  • Try Proguard. It renames symbols in your code, so one can not see that particular method is responsible for some verification. I beleive, it would be enough for simpliest protection. – trashkalmar Jul 03 '13 at 10:49
  • proguard is pretty much useless there are anti LVL tools that defeat it without much trouble – pt123 Jul 03 '13 at 12:09
  • So, clarify what level of protection do you want to achieve. – trashkalmar Jul 03 '13 at 19:09
  • like I said in the initial post I wanted code practices to to prevent a hacker from modifying the jump opcodes in the code I showed to bypass the verification check that I have written in C++ using NDK – pt123 Jul 03 '13 at 20:59
1

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.

Mason Hemmel
  • 185
  • 3
1

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.

jmkeyes
  • 3,751
  • 17
  • 20