The option -keep allows to exclude from obfuscation, but it still obfuscate the methods parameter names, which can be bad for framework like Spring web.
-keep class com.example.web.** { *; }
Is there a way to preserve the arguments names for certain packages only?
Not possible:
https://sourceforge.net/p/proguard/discussion/182455/thread/59cb6762/
~~~~~~~~~~~~~~~~
From what I've tried the -keepparameternames seems to affect only the -keep-ed methods.
So the answer to your question: it's possible to limit the list of packages that fall under its action marking with -keep (or its derivatives) only certain packages.
Related
I use Kotlin and I have many internal classes.
I want to obfuscate and shrink everything apart from all public classes.
Proguard rules:
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-optimizationpasses 5
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
-keep public class * {
public <methods>;
public <fields>;
}
Unfortunately the -keep public class * behaves defensively and keeps all names, also for the internal classes.
Your rules are way too broad.
Single "-keep" with nested rules is more broad, compared to combination of "-keepmembers" and "-keepclasseswithmembers" rules
Full "-keep" rule means "do not change bytecode of that method, ever"
Classes, referenced by kept classes and methods, can not be removed, renamed or repackaged
This line in your rules keeps all your classes and interfaces:
-keep public class * {
I mean ALL of them. Whether they have public members or not.
Use -keepclasseswithmembers instead!
Because of these lines
{
public <methods>;
public <fields>;
}
all your public methods will be left untouched, which means that repackaging and renaming methods, referenced from your public methods can not be carried out!
If you want at least some repackaging to be done, make sure to allow optimization (because repackaging is performed as part of optimization step):
-keepmembers,allowoptimization public class * {
public <methods>;
public <fields>;
}
In addition to repackaging, this will also allow for some inlining (which in turn assists in removing classes, that supply inlined methods).
Also with Android apps you are much better off repackaging into your primary package (the application package, or package with biggest number of your immovable classes in it) instead of empty package (''). This is because some "exported" classes (Activities, Views, Services, other stuff, referenced from xml files) can not be moved outside of their package by Proguard, — aapt dynamically generates special rules to prevent that. The part of optimization process, that changes access modes from public to protected/private, becomes more efficient the more classes can be placed together in single package.
I want to obfuscate and shrink everything apart from all public classes.
Bad idea. You really should try to obfuscate as much as possible, especially public classes. If you restrict obfuscation, repackaging is also restricted! It would rename them!!
Aim for the most specific rules possible.
If you want to prevent shrinking:
-keep,allowoptimization,allowobfuscation public class com.example.Example
If you want to prevent renaming, but allow stripping unused classes:
-keep,allowoptimization,allowshrinking public class com.example.*
In general, avoid wildcard rules (bare *) and -keep rules: prefer rules for specific classes and -keepmembers/-keepclasseswithmembers
The correct approaches for obfuscating applications and libraries are completely different, but they have something in common — you should not care about public methods/classes; just obfuscate/shrink/repackage as much as possible until any more would break it.
For applications you should just obfuscate/repackage as much as possible. If you don't know, which packages are safe to obfuscate, start from opting known safe packages into obfuscation.
For libraries — do not apply Proguard to library itself (unless you are trying to achieve security by obscurity). Use the feature of aar format — consumer proguard files — that allows to supply rule "segments", which should be followed during final app obfuscation.
Will DexGuard help me to obfuscate my broadcastReceiver ? I have important algorithm in one of my broadcast Receivers and i need a way to obfuscate it, but DexGuard needs purchase a license ? Proguards free, any suggestions ? and i can't find a link to download redex by facebook so i assume its still in development. So my question is which one of them will obfuscate my broadcastReceiver.
my proguard file has content like this:
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
**-keep public class * extends android.content.BroadcastReceiver**
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
notice it says to keep broadcastReceiver, how can i hide my data ? I'd have to try and move all my logic to another class but broadcastreceiver gets garbage collected aggressively. So not a option.
You are right the default ProGuard and DexGuard config excludes classes that extend BroadcastReceiver so just move to another class. It would be better OO design to have your logic in separate class - makes it more testable for one. Certainly DexGuard will offer stronger protection than ProGuard given it has specific protection functionality Class encryption and API hiding sound as if they would be useful. Note there are other commercial obfuscators for Android.
For increased security one option would be to store/run the algorithm in native code given it's more difficult to reverse engineer.
But actually as you say important algorithm I wonder if it should be in the app at all. Storing and running the algorithm in a controlled server environment and having a secure API would be better IMO - of course there's no 100% security as your server could get hacked but this would likely be better than having a copy of the algorithm in every .apk downloaded.
What would be a smart ProGuard configuration to obfuscate just the private methods and constants of one particular class com.acme.Algorithm?
I would like to obfuscate just that, because it contains an algorithm that should not be plain obvious when accidentally opening the .jar.
I'm a ProGuard newbie. AFAIU, you have to use "keep", but the positive logic of "do obfuscate" is not available, right? So how to exlude my class from a "keep everything" config? Note: I don't want to obfuscate other classes for the moment, because I want to allow the customer to see meaningful stacktraces.
Obfuscating a single class won't have much effect: it may change the class name and a few field names and methods names, and it may optimize some code. Obfuscation tends to be less effective for hiding small pieces of information. The more application code you obfuscate, the more difficult it becomes to understand.
That being said, you can specify:
-keep class !com.acme.Algorithm { *; }
It keeps all classes/fields/methods outside of com.acme.Algorithm.
I'm using progurad to get rid of some logging:
-assumenosideeffects class android.util.Log {
public static int d(...);
public static int v(...);
}
I don't want anything else to happen to any classes. In particular I don't want any obfuscation, since this is a library. The clients of the library will apply obfuscation themselfs.
Is there a way to tell proguard to do "nothing" except the -assumenosideeffects rule please?
This option is applied in the optimization step, so you could disable shrinking and obfuscation. You still need to provide -keep options, e.g. ProGuard manual > Examples > A typical library.
I have a library that is about to be obfuscated using ProGuard. "Library mode" is almost applicable for my use case, i.e. it is almost fine to keep all public and protected classes and class members.
However due to Java's visibility requirements some members cannot be made package private or private and thus they are public classes although they should not be in the library. I would like to have them obfuscated to make it more clearly that these classes do not belong to the public api, as well as to get better obfuscation and smaller library jars.
Is there a way to exclude some items from a proguard "keep" rule without specifying each of these items by name (using the '!').
Ideally I would like to annotate these classes and members with a tagging annotation, but as far as I understand Proguard can only be told to keep items with certain annotations.
You can only keep items indeed. If you want to exclude certain class members, you have to do so by listing or annotating the class members that you do want to keep. When specifying a class name, you can provide a list, optionally with "!" to exclude names. When specifying a class member name and type, that is not possible. Still, in both cases, you can use wildcards. If you pick special names for your internal classes, this might work:
-keep public class * {
public protected *** !myInternalField*;
public protected *** !myInternalMethod*(...);
}