I'm creating an app for android and ios, and i already know that it's theoretically possible to decompile an android app. The app contains sensitive information that i don't want users to have access to as the app interfaces with a webserver. If a user gained access to some information available in the source code, they could potentially spam my web server with requests.
Is there any way to authenticate a connection between the app and the server, assuming that the source code is accessible, or is there any way to obfuscate my code to prevent a malicious user from spamming my webserver.
Thankss
[UPDATE]
**
When you build your application using Android gradle plugin version > 3.4.0, the plugin chooses R8 to optimize and obfuscate the code. The rules can now be configured on proguard-rules.pro or proguard-app.conf files. the rules to indicate what to exclude from the obfuscation are similar to the ones in proguard.cfg used earlier.
You can import your proguard files in your build.gradle like
buildTypes{
...
release{
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
R8 picks up all the existing proguard rules files as long as they're included in the build.gradle. You can also configure what pieces to obfuscate for different product flavors that you may have.
**
[OLD BUT RELEVANT INFO]
Proguard is a tool that will help you obfusate your code. This comes as part of your android tools and you just need to activate it. This link and this will help further.
Proguard's default configuration (in proguard.cfg) will be enough to sufficiently obfuscate your code. However you might want to tweak your proguard configuration when you have methods/classes that are being dynamically accessed.
For instance, accessing classes/methods with Reflection will need you to have the code to be intact. You might sometimes experience ClassNotFoundException if proguard obfuscates it.
If you have classes that are being accessed in the AndroidManifest/ Layout Files, you should prevent proguard from obfuscating them.
This can be done by adding
-keep public class <MyPackage.MyClass>
to your proguard.cfg.
**
While Proguard makes static analysis harder, DexGuard protects from both static and dynamic analysis. DexGuard is specifially for android applications and is only commercially available while Proguard is open source and is for any java bytecode obfuscation / optimization.
You cannot prevent decompiling android apk, you can just increase the difficulty of decompilation, proguard is the best option.
DexGuard provides even better security then ProGuard but it is NOT free: https://www.saikoa.com/dexguard
DexGuard can even obfuscate String constants.
Related
I am trying to improve my understanding about usage of ProGuard for Android build. Am not very sure what to keep ( not obfuscate ) exactly and what to obfuscate.
Couple of libraries are being used in my App, some of them are listed below
com.android.support:appcompat
com.android.support:design
io.reactivex:rxandroid
io.reactivex:rxjava
com.jakewharton.rxbinding
com.trello:rxlifecycle
Question 1:
Should I obfuscate above libraries ? they are already open source.. will it not be wise to keep all support libraries using proguard rule:
keep class android.support.** { *; }
Similar way I can do with io.reactivex and jakewharton libraries
Question 2
Other than support and external libraries, I have application specific classes, coded for this application. Is it ok to keep the class names which are mentioned in AndroidManifest.xml and specifically their public members, and let obfuscate rest of the code.
Let me know if I am missing something or my understanding is not correct. just to repeat this is not a question on how to do it technically, but more on what to include and what to exclude for obfuscation/optimization/ shrink.. and more specifically reason behind it ....Definitely it will be espresso tested after build.
Question 1: Should I obfuscate above libraries?
Yes. If you add -keep <library> rules then the entire library will be included in your APK, which bloats it and might cause problems such as making your app exceed the 64k method limit and require Multidex. It's always a good idea to apply the ProGuard rules provided by the library. You can usually find .pro files in the libraries source code or in websites such as https://github.com/krschultz/android-proguard-snippets.
Question 2: Is it ok to keep the class names which are mentioned in AndroidManifest.xml and specifically their public members, and let obfuscate rest of the code.
The Android plugin already does that for you. The plugin scans all classes whose names need to be preserved (e.g. Activities, Services, BroadcastReceivers, Views, etc) and doesn't obfuscate them. This includes everything that you declare in AndroidManifest.xml.
I've been doing Android development for a little bit and I'm getting to a point in one of my projects where I would like to use Proguard to shrink the size of my APk and help with the dex limit. Unfortunately, I am getting a few errors and stack overflow has answers but they seem to be targeted for those with more experience.
My question is what is the relationship with your proguard-android.txt and proguard-rules.pro? Why are there two separate files and why are they in separate formats? When are the statements in these files called and in what order? I am just looking for an explanation of the overall context of using Progurad in a development environment.
Thank you in advance.
ProGuard manipulates Java bytecode the way you tell it with your configuration files and the rules they contain. ProGuard can do many things. And it can completely break your app so you have to make sure to add the correct rules.
I assume you use Gradle based builds for your apps. Then you've probably encountered this snippet that enables ProGuard for release builds of your app (or Android library):
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
'proguard-rules.pro'
}
}
...
}
In the config the list proguardFiles tells the build what files that contain ProGuard rules it has to use. This list can contain any number of files.
Why are the files (proguard-android.txt and proguard-rules.pro) defined differently?
The magical getDefaultProguardFile(‘proguard-android.txt') loads file named proguard-android.txt from the standard location in the Android SDK (the location is ${ANDROID_SDK}/tools/proguard/).
Other config files are resolved locally, so file proguard-rules.pro is expected to be at the root of the current Gradle module.
Why are there two separate files? And what is the relationship between proguard-android.txt and proguard-rules.pro?
ProGuard configuration is additive. You can define some rules in one file and other in other files. The rules are internally concatenated into single list of rules.
File getDefaultProguardFile(‘proguard-android.txt') contains several general rules for all Android apps (check them yourself, in the file in your SDK). The local proguard-rules.pro is expected to contain rules specific for your own app. For example you want to make sure that a class is not stripped away when you use it only through reflection (I'll get to that later).
Note that having multiple local files is very useful. For example you can use two local config files for debug builds - one with the release rules for your app and the second containing rules disabling obfuscation.
Also note that the additive behaviour of the configurations can be a bit troubling. If you add a rule in one config file, you cannot remove it in another. So be careful with very general rules (e.g. imagine adding -keep class ** { *; }).
When are the statements in these files called and in what order?
You can define them in any order, there's no difference. And you can define the same rule in multiple files, it doesn't matter. The order of the specified files doesn't matter either.
ProGuard itself is run as a single job within the Android build (single Gradle task to be precise). The task is provided all the inputs:
classes to manipulate
library classes to use but not manipulate
output path for generated processed jar
ProGuard rules specifying the manipulation
output paths for various output information (what was removed, mapping, …)
And then it processes the files and generates an output which is further processed by the Gradle build.
How does ProGuard actually work? And why do I need the rules?
ProGuard traverses the whole call graph of classes/methods/fields/…. It starts with the classes/methods/… defined by the provided rules. Then traverses the call graph and marks classes/methods/fields/… as necessary and keeps them for the output. So if you call it with no matching keep rules it will generate an empty output (or maybe it will throw an error and tell you to define some, I don't remember now). ProGuard doesn't recognize calls done via reflection, so you have to add some rules to handle that. There are many other cases that require you to add some rules, check the documentation for that.
Final notes
If you check ProGuard documentation you can find various rules
you can use. But not all of the rules are good for Android (ProGuard is a general Java tool).
Some rules are generated by Android build itself, you don't have to define them yourself. There are 2 types of such rules:
General config rules like -injars, -libraryjars, …
Rules generated from AndroidManifest.xml and resources (layouts). Android build (aapt tool) generates rules to keep classes mentioned in the manifest (activities, services, receivers, …) and custom views used in layouts. You can check these generated rules in build/intermediates/proguard-rules/${PRODUCT_FLAVOR}/${BUILD_TYPE}/aapt_rules.txt
Some rules can come from aar libraries. The libraries can contain ProGuard config necessary for the library to work (there can be proguard.txt file inside).
When writing Android libraries yourself be extremely careful with the rules you want to add to the aar. Because of the additive nature of the rules, it can cause problems for the app that bundles the library.
I have enabled Proguard by uncommenting the following line in project.properties file:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
When I tried to extract the classes and resources using dex2jar , I was able to extract them as it is. Do I have to change some other files / properties / configurations in my project to prevent direct extraction of classes? Should I add some configuration parameters in the project.properties(project root location) or proguard.android file(SDK location)?
It seems you're using the "standard" Proguard obfuscator properties file. Try using the "advanced" Proguard obfuscator properties file. It's here:
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt
Your codes will be obfuscated a bit further, but not all. For example, activities, services, Java classes you've declared in the manifest file, or declared with -keep directives in Proguard, will not be completely obfuscated.
On a side note: Even if you use the commercial DexGuard, you're still not 100% protected from decompilation. Experienced hackers can use smali/baksmali techniques to reverse engineer your codes, read it, modify it at will. Remember, if codes can be read as 0s and 1s, it can be hacked.
Did this occur after you built your application in release mode and exported it using valid certificate and the Export Wizard in Eclipse ? If no - do the steps: right click on your project, choose "Export", type "export android application", Next, then choose "Use existing keystore" or "Create new keystore", finish the wizard. ProGuard runs only when you build your application in release mode.
There is no way to prevent the decompilation of classes and resources. Obfuscation, such as proguard, are tools to make reverse engineering of java harder through name munging, string munging, and flow control changing. Though as stated before, everything can always be reverse engineered. Obfuscation is used to make the barrier to entry higher, and to deter people from wanting to reverse engineer your code due to level of effort.
For the moment I am developing small Android projects to practice with the Android prorgramming. However, once on the market, I would like to obfuscate / optimise the APK thanks to ProGuard. But this tool renames classes to obfuscate the code, so:
Is it safe to use tools like Android Query to write the code?
If it is not safe, what are some framework examples that can be used safely with Pro Guard?
What could be a solution to the problem? Or should I write everything using the good old Android style and forget about a "write less, do more" approach?
How do I identify the tools that are ProGuard-safe from the ones that are not?
I assume you want to use third party libraries (jar files). You could use a 3 step approach:
If the third party jar explicitly supports Android, it will have a proguard configuration. Usually this is a snippet that you merge into your proguard-project.txt.
If there is no such explicit support, you may still try to use the jar, obfuscate and test your app. If errors occur, gradually exclude classes from obfuscation until it works. A common problem is that libraries use reflection to instantiate classes and call methods which breaks after obfuscation.
Exclude the whole library from obfuscation. This will work in any case and proguard will not touch the library at all. (The Android toolchain will still repackage the contents of the jar into your apk which might cause problems.) This will also produce the least obfuscated result and should really be your last resort.
In any case, obfuscation is not a switch that you simply toggle. You'll need to get familiar with proguard config files which involves a learning curve.
I have an Android project that I recently published to the market after running it through obfuscation with ProGuard.
The project exported without any complications, but how do I know it's been obfuscated? Is there anything I could do to verify that obfuscation was successful?
Look for dump.txt, mapping.txt, seeds.txt and usage.txt. They will probably be in a proguard folder at your project directory. These are created when ProGuard is run on your code.
These are filled with information about the obfuscation, especially useful is mapping.txt which shows what ProGuard turned your various member names in to.
Try to reverse engineer your own application. See what you can read in the code.
Use the following questions:
decompiling DEX into Java sourcecode
http://www.taranfx.com/decompile-reverse-engineer-android-apk
DISCALIMER: I am not the owner of decompileandroid.com and I am not paid to promote it. I am a develper, who is satisfied with this service.
There is actually an easier way than acquiring several different tools and passing the output of one of them to the other (this of course gives you a better control of what's going on). You can use the service
decompileandroid.com
Basically you upload and .apk file and it does all of these steps for you.
Then you can download a .zip file, which contains the decompiled sources.
You can first upload your .apk built in debug mode, then upload an .apk built in release mode. Just make sure that the flag minifyEnabled is set to true in your build.gradle file for the release build.
The difference was pretty obvious in my case - most of my classes were named a,b,c, etc in the minified build.