Here are few lines from proguard-rules.pro
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes InnerClasses,EnclosingMethod
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-keep public class * extends java.lang.Exception
-dontwarn org.apache.http.**
Logcat output (error line number is listed as 1133, while my source file is 100 lines longer)
09-04 16:11:46.698 3827-5280/com.XX.main E/AndroidRuntime: FATAL EXCEPTION: IntentService[ActivityRecognizedTracker]
Process: com.XX.main, PID: 3827
java.lang.NullPointerException: Attempt to read from field 'double com.XX.trips.Trip.a' on a null object reference
at com.XX.ActivityRecognizedTracker.onHandleIntent(SourceFile:1133)
I am preserving the line numbers and source file attributes, but stack trace is still obfuscated. What am I doing wrong?
AFAIK it's not possible to obfuscate the code and have original stacktraces. So if you want to see original method and class names in the stacktrace, you have to add -dontobfuscate rule.
But you don't really need the original stacktrace.
You are using -keepattributes SourceFile,LineNumberTable and that enables you to unambiguously retrace the stacktrace. Just don't forget to keep the generated mapping.txt file.
Moreover if you remove -renamesourcefileattribute SourceFile you'll see the original file names in the parentheses. The line number is already there, so you should be able to figure out without retracing where the exception actually happened.
Related
I have implemented dexguard in my application. Application is working when no obfuscation is done but crashes as dexguard obfuscation is done.
it gives the error.
Caused by: android.view.InflateException: Binary XML file line #0 in com.avanza.ambitwizhmb:layout/2131558492: Error inflating class fragment
Caused by: com.huawei.hms.maps.model.RuntimeRemoteException: AppId is null. Please check whether the agconnect-services.json file is added to your app project.
the dexguard rules for huawei is:
-keep class com.huawei.agconnect.**{*;}
-dontwarn com.huawei.agconnect.**
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
-keep interface com.huawei.hms.analytics.type.HAEventType{*;}
-keep interface com.huawei.hms.analytics.type.HAParamType{*;}
If Dexguard obfuscation is used during app packaging, you need to configure the following:
-ignorewarnings
-keep class com.huawei.agconnect.** {*;}
-keepresourcexmlelements **
-keepresources /
My Android release build uses the following proguard-rules.pro
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-keepnames class com.mypackage.** { *; }
-keepclassmembers class com.mypackage.** { *; }
...
I'm uploading mapping.txt along with the build when performing the Google Play console pre-launch testing. Any crashes during testing have the correct function / class information for my package, but the line numbers are completely incorrect:
Caused by: java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.get(ArrayList.java:437)
at com.mypackage.MyClass1.getHistory(MyClass1.java:1) <-- this is incorrect
at com.mypackage.MyClass2.onCreate(MyClass2.java:9) <-- this is incorrect
at androidx.fragment.app.Fragment.performCreate(Fragment.java:6)
at b.m.b.g0.d(FragmentStateManager.java:5)
at b.m.b.g0.j(FragmentStateManager.java:33)
...
Any help much appreciated.
*** Update ***
I've tried running with the stand-alone R8 tool as per suggestion by #sgjesse in this and the deobfuscated line numbers are correct, so I'm assuming it's a funny with Google Play Console.
I am using ProGuard in my application and problem is when users report some problem to my console and I can't decode it precisely because of "Unknown source".
Here is example of stacktrace:
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.my.package.j.a(Unknown Source)
at com.a.a.c.c.j(Unknown Source)
at com.a.a.c.c.b(Unknown Source)
at com.a.a.c.e.run(Unknown Source)
at java.lang.Thread.run(Thread.java:856)
Then I am using this code to decode it:
./retrace.sh -verbose mapping.txt stacktrace.txt > out.txt
And here is output:
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.my.package.MyFragment$10.void output(int,java.lang.String)(Unknown Source)
at com.stericson.RootTools.execution.Shell.void readOutput()(Unknown Source)
at com.stericson.RootTools.execution.Shell.void closeCustomShell()(Unknown Source)
com.stericson.RootTools.execution.Shell startShell(int)
void access$200(com.stericson.RootTools.execution.Shell)
at com.stericson.RootTools.execution.Shell$2.void run()(Unknown Source)
at java.lang.Thread.run(Thread.java:856)
It only shows name of Fragment when error occurred, but I also need exact line and method.
Your question has actually two parts.
1) Why are you missing the line information?
You are removing the line information during obfuscation. You need the following rules in your proguard.cfg
-renamesourcefileattribute MyApplication
-keepattributes SourceFile,LineNumberTable
Find details for retracing line numbers here: http://proguard.sourceforge.net/manual/retrace/examples.html#with
2) Why is it missing some method/class name, in your example
com.my.package.MyFragment$10.void
This is because $10 is most likely an anonymous class declaration which will be treated differently during compiling and subsequent obfuscation. First easy solution is of course to get rid of the anonymous declaration and declare it somewhere. Another solution would be to add the following line again to your proguard.cfg
-keepattributes EnclosingMethod
This of course will again not remove some information and will reduce your obfuscation.
The problem:
I'm using android mobile services, which relies on androidhttpclient.
Referencing org.apache.http.legacy resolves all the problems and the app runs just fine. However, with proguard on, I keep running into issues.
The problem plays out in two scenarios. If I keep the export checkbox checked (in jave build path), I get a 'Stub!' exception as expected (see discussion below)(see screenshot for which checkbox I'm talking about)
The runtime crash of type: "Stub!":
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.stuffd/com.stuffd.MainActivity}: java.lang.RuntimeException: Stub!
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2345)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2405)
at android.app.ActivityThread.access$800(ActivityThread.java:149)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1324)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5317)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
Caused by: java.lang.RuntimeException: Stub!
at org.apache.http.message.AbstractHttpMessage.(AbstractHttpMessage.java:7)
at org.apache.http.client.methods.HttpRequestBase.(HttpRequestBase.java:7)
at org.apache.http.client.methods.HttpGet.(HttpGet.java:8)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.executeGetRecords(MobileServiceJsonTable.java:952)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.executeUrlQuery(MobileServiceJsonTable.java:183)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.execute(MobileServiceJsonTable.java:160)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceTable.execute(MobileServiceTable.java:158)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceTable.execute(MobileServiceTable.java:249)
at com.microsoft.windowsazure.mobileservices.table.query.ExecutableQuery.execute(ExecutableQuery.java:101)
If however, I keep the checkbox unchecked (as suggested - see discussion below), I get and AbstractMethodError exception.
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:811)
Caused by: java.lang.AbstractMethodError: abstract method "java.lang.String org.apache.http.client.methods.HttpRequestBase.getMethod()"
at android.net.http.AndroidHttpClient.getMethod(AndroidHttpClient.java:283)
at android.net.http.AndroidHttpClient.execute(AndroidHttpClient.java:301)
proguard config used:
-dontwarn org.apache.http.**
-dontwarn android.net.http.**
-dontwarn com.microsoft.windowsazure.mobileservices.**
Has anyone else run into this and has figured it out?
Here's what I am using, allowing the OS to properly replace the stubbed methods at runtime.
-keep class org.apache.http.** { *; }
-keep class org.apache.commons.codec.** { *; }
-keep class org.apache.commons.logging.** { *; }
-keep class android.net.compatibility.** { *; }
-keep class android.net.http.** { *; }
-dontwarn org.apache.http.**
-dontwarn android.webkit.**
It's all the stubbed packages provided by org.apache.http.legacy.jar.
You're right not exporting the legacy apache lib. However it has to be located outside the libs folder and added to the Build Path (when using Eclipse). Otherwise it gets exported anyway with your Android Private Libraries.
I'm using GMS, Volley and AndroidHttpClient in my own communication classes.
Here's what I had to add to the proguard settings:
-dontwarn org.apache.http.**
-dontwarn com.google.android.gms.**
-dontwarn com.android.volley.toolbox.**
-dontwarn com.myapp.communication.**
-keep class com.google.android.gms.** { *; }
I'm trying to deobfucate a stack trace from my Android app. I used proguard when building the app and running retrace seem to work, more or less.
What isn't working is decoding the line numbers. No line numbers are shown on the output and it lists several choices for each "at".
Here is my proguard-project.txt file:
-keepattributes LineNumberTable
-assumenosideeffects class android.util.Log {
public static int v(...);
public static int d(...);
}
This is my stack trace:
uncaught exception
java.lang.NullPointerException
at com.myapp.myapp.dbaccess.ag.a(Unknown Source)
at com.myuapp.myapp.dbaccess.x.a(Unknown Source)
at com.myapp.myapp.dbaccess.x.a(Unknown Source)
at com.myapp.myapp.main.ab.run(Unknown Source)
And here is the output:
uncaught exception
java.lang.NullPointerException
at com.myapp.myapp.dbaccess.ZNodeCache.com.myapp.myapp.dbaccess.ZNode getNodeFromCache(long)(Unknown Source)
com.myapp.myapp.dbaccess.ZRoot getRootFromCache()
com.myapp.myapp.dbaccess.ZNode getNodeFromDb(long,boolean)
com.myapp.myapp.dbaccess.ZNode$Array getChildrenForExport(com.myapp.myapp.dbaccess.ZNode)
... many more ...
at com.myapp.myapp.dbaccess.XmlImport.com.myapp.myapp.dbaccess.XmlImport$Results importFile(java.lang.String)(Unknown Source)
void _doImport(java.io.InputStream,com.myapp.myapp.dbaccess.XmlImport$Results)
void importFile(java.io.InputStream)
void importNode(org.xmlpull.v1.XmlPullParser,com.myapp.myapp.dbaccess.ZNode)
... many more ...
at com.myapp.myapp.dbaccess.XmlImport.com.myapp.myapp.dbaccess.XmlImport$Results importFile(java.lang.String)(Unknown Source)
void _doImport(java.io.InputStream,com.myapp.myapp.dbaccess.XmlImport$Results)
void importFile(java.io.InputStream)
void importNode(org.xmlpull.v1.XmlPullParser,com.myapp.myapp.dbaccess.ZNode)
... many more ...
at com.myapp.myapp.main.MainActivity$3.void run()(Unknown Source)
I must be missing another configuration parameter; any ideas?
Turns out the answer is in the Android documentation (believe it or not). I guess I missed it the first time around. You need to specify the source file, like this:
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
The renamsesourcefileattribute will cause all source files to have the name SourceFile (or whatever you put). "retrace" doesn't care what the source file name is, but if you leave it out, it decides to ignore the line numbers.
This goes in proguard-project.txt which, if you're using Android Studio, you'll find in "your project".app.