I want to check which classes and methods were removed.
Any way to achieve this?
I know mapping.txt shows which symbols is obfuscated to what.
But what is removed is not listed there as I know.
Proguard web site does not describe about this.
The option -printusage writes out the unused classes, fields, and methods.
Android Gradle builds by default write it to build/outputs/mapping/release/usage.txt.
Add the following rules in proguard-rules.pro file in your Gradel Scripts directory
Generate a report of removed (or kept) code
add -printusage usage.txt
To check report of the entry points that R8 determines from your project’s keep rules
add -printseeds seeds.txt
after this, build signed apk. Then at the root of your projects these files will be generated.
usage.txt is your choice to find what were removed - list of what Proguard does not keep
[Read more here]
Related
Actually, I'm looking for the solution to obfuscate a whole apk file using proguard. The most common approach is to unzip the apk first. Then convert the decompressed classes.dex to the jar format. Next run command proguard #proguard.cfg to obfuscate the jar file. Finally after obfuscating compress the content back to form the whole apk.
Following is the content of proguard.cfg,
-injars in.jar
-outjars out.jar
-verbose
However, there are always errors of unresolved references when running proguard #proguard.cfg. I know it is caused by necessary libs missing. However, it is really trivial to config the libs for each one when having more than 1000 apks. So is there any workaround to obfuscate apks in batch manner via proguard? In other words, force proguard to ignore classes from outer libs and merely obfuscate the classes in the given jar file.
Finally I got the solution. Just add one option which will suppress all the unresolved reference warnings. That is -dontwarn which is used to control the warnings. If it is set to -dontwarn **, the obfuscation process will ignore all the warnings. For other useful options, please see https://github.com/facebookarchive/proguard/blob/master/examples/android.pro
I have a project that depends on some maven lib, after proguard I got the files under package com.xxx kept, but I didn't add the rule in my project proguard files, I must be imported from maven lib. I know there will be a merged proguard file during progurad processure. My question is there a way to hook the processure and prints the separated proguard rules, or how to find which lib imports the rule.
Thanks in advance.
Modify your proguard-project.txt to include
-printconfiguration "build/outputs/mapping/configuration.txt"
Trigger proguard run with ./gradlew assembleRelease and inspect the file. It doesn't always tell which aar or jar has contributed it though. Maybe create feature request for AGP to make behaviour consistent with aapt which prints where every line is coming from.
I have an issue which I'm pretty sure is related to multidex. Basically one of the libraries I use has a .properties resource bundle in a jar. As my application started growing I started having issues with it. I've made a couple of posts about it in the past but never had any solutions (post 1, post 2). Post 2 actually has a lot more details about the issue.
Basically this resource is missing unless I force some of the code on that Jar to run on the Application onCreate method. At least that was the issue until yesterday.
Yesterday I update a jar that has nothing to do with this but is now larger than it used to be (which I'm assuming means it has more methods), and now the code fails again on this same issue java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale en_US but now it fails for everyone, not just some users.
I took apart the apks using apktool for one that works and one that doesn't (basically downgrading those unrelated jars) and there is an unknown folder in both apks but the one that works has those LocalStrings.properties in that folder and the one that doesn't work doesn't have them in that folder. I have unzipped those unrelated jars just to make sure and they don't have that javax.servlet package in there and they are jars so they don't have anything else that might affect the gradle build.
Basically my theory right now is that those jars are just large enough to push the javax.servlet stuff out of the first dex file, but that isn't entirely right because the properties files don't even go in the dex file. If I just unzip the apk, I can see the javax package on the root folder and the resource files inside the right place but not LocalStrings.properties whereas if I do that for an apk that works, I can see LocalStrings.properties in there.
Right now I've been testing multiDexKeepProguard and I got all javax.servlet to go in the main dex file but I still can't get LocalStrings.properties to show up in the apk, even with:
-keepclassmembers class **$Properties
I've also tried a few other crazy things like putting the LocalStrings.properties files inside my main app package using the javax.servlet package and it didn't help either.
So what else can I try? Is this a bug or am I doing something wrong?
Thanks.
Edit: I would like to report that I've once again gotten past this issue by removing a dependency (an ad network) that I'm no longer using. I realized I still had that dependency when I used dex2smali to look at the first dex file and saw it was there. So it definitely appears to be an issue with the size of the jars it puts on the first dex file.
Edit: I have this on my proguard settings:
-keep class javax.** {*;}
-keep interface javax.** {*;}
-keepclassmembers class javax.** {*;}
-keepclassmembers class **$Properties
Not sure if this was the right way to do it, but apparently proguard was mistakenly deleting the *.properties files for me.
What fixed it was doing a build with
minifyEnabled false
and then going back to
minifyEnabled true
After that, the *.properties files were all available in the final build again.
It looks like your package property file is stripped by ProGuard. I am not sure whether you have tried below configurations
-keep class javax.servlet.**
or
-keep class javax.servlet.** { *; }
or
-optimizations !javax.servlet
-dontoptimize
Also, more additional references:
shrink-code: https://developer.android.com/studio/build/shrink-code
Processing resource files: https://docs.huihoo.com/proguard/manual/examples.html
-keeppackagenames https://stackoverflow.com/a/5866755/8034839
How to tell ProGuard to keep everything in a particular package?
I have obfuscated my apk, but the file size has only been reduced from 12MB to 10.5MB.
The reason it is only a relatively small reduction may be because my app uses a couple of large libraries, but is there any way I can check the level of obfuscation that has been performed?
Just in case, this is my proguard-project.txt file...
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-dontwarn twitter4j.**
...and the libraries I'm using are android-support-v4.jar, acra-4.5.0.jar and twitter4j-core-4.0.2.jar.
Here is probably a more visual way to check.
In the newer release of Android Studio, it comes with the APK Analyser that let user explore what is in the APK file and it is handy to check if your class has been obfuscated.
Below image shows that both package and method name have been obfuscated
In your project directory you will find a Proguard folder, in which you will see four text files:
dump.txt
Describes the internal structure of all the class files in the .apk file
mapping.txt
Lists the mapping between the original and obfuscated class, method, and field names. This file is important when you receive a bug report from
a release build, because it translates the obfuscated stack trace back to the
original class, method, and member names. See Decoding Obfuscated Stack Traces
for more information.
seeds.txt
Lists the classes and members that are not obfuscated
usage.txt
Lists the code that was stripped from the .apk
Source: Proguard
Hope this helps!
Proguard
Proguard workflow:
seeds.txt - list of what Proguard keeps. These are entry points and they nodes. For example for bare java it is a main function and others dependencies
usage.txt - list of what Proguard does not keep
mapping.txt - info about old and new naming in old_name -> new_name format. It can be used for decoding stacktrace by retrace or proguardui
dump.txt - describe everything that Proguard put into the result archive
You can find output
<module_name>/build/outputs/mapping/<buildType>/
You can use Analyze APK tool. Where you can look thought .class files, add a Proguard mapping file, show removed nodes, show deobfuscated names
[ProGuard vs R8]
any way I can check the level of obfuscation that has been performed?
You might be able to use the flag -optimizationpasses N.
Specifies the number of optimization passes to be performed. By default, a single pass is performed. Multiple passes may result in further improvements. If no improvements are found after an optimization pass, the optimization is ended. Only applicable when optimizing.
ProGuard only shrinks/optimizes the parts you did not create -keep options for. When using broad -keep rules (ending in .** { *; }), the shrinking/optimization results quickly decrease.
I can see from the snippet you did not create such broad -keep options yourself but they may be part of the ProGuard consumer rules which are part of certain dependencies. You can print all these -keep options by adding the follwing in your ProGuard configuration file:
-printconfiguration fullconfig.txt. This will create the file fullconfig.txt in which all -keep options, including the ones of the dependencies, are listed.
If one of your dependencies contains too broad -keep options you could choose to ignore these by creating a consumer rule filter. This will require you to create the -keep options for the dependency yourself.
Recently there was a tool released to inspect what parts of a jar/apk are being kept thus not shrunken/optimized. You need to provide the -keep options and upload the jar/apk, you can then see in a visual way what parts of your project are not processed with ProGuard. This tool is called the ProGuard Playground. I would recommend copy/pasting the content of the fullconfig.txt file, that way you can easily see what parts are left untouched by ProGuard.
I plan on using ProGuard to obfuscate the code of my Android app. I have been researching about it. Most of the articles and videos on YouTube seem to be out dated. From all what I have gathered, here is what need to be done:
In the project.properties class I will have to uncomment the line:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
I am using Crashlytics and it says that to have informative stack traces, I must add a line to ProGuard configuration:
-keepattributes SourceFile,LineNumberTable
I am guessing that the above line is appended to proguard-project.txt?
And then that's it. Please correct me where I am wrong.
Correct. In your project.properties you need to define the
path/filename for your Proguard configuration file, e.g.
proguard.config=proguard-project.txt
(in this case proguard-project.txt sits in the project's root folder)
Also correct. As per the Proguard documentation:
-keepattributes [attribute_filter]
Specifies any optional attributes to be preserved.
...
You should also keep the SourceFile and LineNumberTable
attributes for producing useful obfuscated stack traces. Finally, you
may want to keep annotations if your code depends on them. Only
applicable when obfuscating.