What does obfuscating an API mean? - android

I am currently reading a research paper on obfuscation. Here's the portion of the paper that relates to my question.
"while current obfuscation schemes elevate some islets of static analysis, such as changing layout of the source code, changing control flow, and modifying data, they are easily exposed to reverse engineering analysis due to a lack of API concealment. Therefore, a quantitative evaluation scheme is needed to ensure that obfuscation is applied to an appropriate API with an adequate degree of resistance to reverse engineering."

"Obfuscating the API" probably means changing the names of identifiers, like class names, method names, field names, etc, to very un-descriptive names. so that readers of your code wouldn't know what your code is doing.
Proguard is such a tool. Here is a post I found, involving using Proguard to obfuscate private methods in a simple class. You can see how privateStaticMethod turned into a, and how the parameter names turned into paramString1 and paramString2.
By doing so, readers won't know what a does just by looking, because a tells them literally nothing about what the method actually does. The methods that a calls might also be obfuscated as b or c, which makes it even harder to know what your code is doing.
Reverse-engineering here refers to trying to figure out how obfuscated code looked originally. Obviously, changing the names of methods and parameters makes it harder to reverse-engineer than just changing control flow and code layout.

Related

Prevent/Make it difficult to patch Binary Assembly

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.

Using strict access to class members and modular code make it harder to reverse engineer APK

Does using private methods and private fields make it harder for someone to reverse engineer code with the common decompilers floating around.
Like the ones mentioned here
Decompile .smali files on an APK
Or does it have no effect as these decompilers allow the person to read each line of obfuscated code in a class.
What about using final on classes and methods to avoid classes being extended and methods being overridden, do they help as I read that the decompilers can not produce decompiled working code. Or is it inconsequential as it is simple to removing the final attribute inthe decompiled classes.
Does using many small modular classes make it harder for someone to decompile and hack the code or using big classes with long methods make it harder to read the obfuscated code.
I am sorry if these come across as noob questions.
Or does it have no effect as these decompilers allow the person to read each line of obfuscated code in a class.
Decompilers decompile all code, including private methods.
What about using final on classes and methods to avoid classes being extended and methods being overridden, do they help as I read that the decompilers can not produce decompiled working code.
Changing that requires pressing the Delete key five times (per final). This will not be a significant challenge for most people.
Does using many small modular classes make it harder for someone to decompile and hack the code or using big classes with long methods make it harder to read the obfuscated code.
Not materially, IMHO.
FWIW, I completely agree with Simon's comment.
Nope. Obfuscation can help, but all it really does is add an extra hurdle for attackers. Security through obscurity does not exist. There are expensive tools around this coming into existence, created by companies such as Arxan, Via Forensics, and others.

Protection from reflection - android

Even a private member/function of my class can be accessed by reflection by using setAccessible(true). Is there a way to prevent this kind of access from outside code?
I read something, here on stack-overflow, that I can use SecurityManager for prevention of reflection in applets(not sure how it works, though), but is there a similar mechanism for Android as well? Maybe an annotation or clever-programming?
Taking a step back, what you're observing is a difference in security philosophy, between the Java execution model as originally embodied in JVMs at Sun and the execution model of Android.
The original Java VM design was intended for a system wherein multiple, mutually-suspicious applications (or "applets" in the Java parlance) would simultaneously inhabit a single address space, running in a single VM. Because the designers didn't want one app to be able to mess with another, they went through great pains to define an intra-VM security model that would disallow things such as one object touching the private fields of another object of a different class.
That said, the Java library ended up having various "escape hatches" out of the security model. One of those is setAccessible() on reflection objects, as you note.
Android's model is different: Android uses processes as the security boundary and unit of application isolation, instead of trying to insinuate it into the process as was done with traditional JVMs. This renders moot the entirety of the Java security model, except in that it helps an application "save it from itself." That is, it's good design to not have an object poke into another object's private parts, and the default Java security model provides just that.
Leaving aside the question of people modifying your code, with Android, as an application author, you control all the code that ends up running inside the process of your app. If you choose to include code that calls setAccessible() that's your business. You might be shooting yourself in the foot, but you certainly won't be shooting any other apps' feet, since the Android security model, running as it as at the layer of processes, inherently doesn't let that happen. Likewise, using native code will totally break you out of the Java object model, which allows for the possibility of things going totally higgledy-piggledy in the process but also allows you to express some things in a more productive manner than you could in Java. It's a trade-off, but it's a per-application-developer tradeoff and not one that particularly impacts anything else that's happening on your phone / device.
I know this doesn't directly answer your question, but I hope it provided some useful context.
Is there a way to prevent this kind of access from outside code?
Not really.
is there a similar mechanism for Android as well?
Even if there is (and I am not aware that such a thing exists), anyone can remove it, by decompiling your code (assuming they do not have your source already), getting rid of the protection, and recompiling the code.
Bear in mind that ProGuard, when used properly, will obfuscate your private classes and methods for your production APK builds. That, plus a lack of documentation, will make it tedious for anyone to gain access to those private classes and methods.
I don't believe that you can ever really 100% protect from users using reflection on your project with malicious intent. You can make it more difficult for users to do it by doing things like obfuscating your code, but it is still possible to reflect on the obfuscated code.
I don't believe SecurityManager can be used for the purpose that you are suggesting, though I could be wrong.

Get bytecode at runtime

On Android, I need to retrieve the bytecode from the executing class at runtime.
If you're wondering why, the reason is that I'd like to compute a hash of it in order ton implement some anti-piracy mechanism that would check that the file hasn't been tampered.
Anyway, I'm trying it like this:
InputStream is = this.getClass().getClassLoader()
.getResourceAsStream("org/foo/bar");
Whichever parameter I pass in the getResourceAsStream(), it always return null.
Is there actually a way to get access ti the bytecode at runtime on Android?
Not sure if that is possible, you should trust the signature system used for APK's. The only hack that I have seen with these is wrapping that app in another app that contains the malicious code and Google fixed that ( I think ). Classes already have a hash code but I'm sure that will not give the same results to what you want to do.
If someone can change your code they will also disable your checks.
I have seen and tried a reverse engineering app to check the security of Android's byte code with an app of my own and it only worked on rooted systems and the disabled code is so horrendous it's unusable. It's not the same as dissembling a Java app.
Pirating a game does not require it to be modified.

Is using ProGuard worth the trouble?

From what I've seen and read, if someone really wants to reverse-engineer your software or decompile it, ProGuard is not going to stop them. But is it at least a modest deterrent? I'm not sure if it's worth the hassle of translating my stack traces later on.
I would recommend ProGuard. Even without obfuscation (which can significantly shorten the names used in the constant pool) it can remove "dead code" (unused methods) of used libraries, etc. (It can also be used to conveniently merge everything together).
It takes a little bit of fiddling to "get correct", esp. if there is dynamically loaded classes -- but very recommended. The actual benefit from space-saving, however, "depends" on what can be eliminated and generally goes up with more external libraries.
Now, for obfuscation -- it does as much as any obfuscator: Makes "decompiling" code into things with meaningful names impossible.
Obfuscation won't save your super-secret-algorithm or hide your private keys, though: if the JVM (or Dalvik after a transformation) must understand it, then so can a decompiler and anyone who really wants to get access can. Your code could even be lifted in bytecode-form and used simply via. reflection (just imagine a terrible API with zero documentation): anyone who really wants to get access can. But perhaps obfuscation will make this task unfeasible for the cost/payout: "It depends".
Don't want to translate stack-traces? Simple: don't use it for debugging (not as useful for getting traces from users) or don't enable obfuscation (other benefits still apply) ;-)
Happy coding.
Pro guard is at least enabling you to have the app become as small as possible regarding the filesize!
That's a real plus.
It's automatically used when developing and compiling with eclipse, provided if you have proguard.config=proguard.cfg to the project's default.properties file.
That's also a real plus.

Categories

Resources