Apktool
Apktool copied to clipboard
[BUG] ArrayIndexOutOfBoundsException exception for APK without resources produced with AGP7
Information
- Apktool Version (
apktool -version) - 2.6.0 - Operating System (Mac, Linux, Windows) - Mac
- APK From? (Playstore, ROM, Other) - Other
Stacktrace/Logcat
~/Downloads ./apktool -f d demo-app-debug-androidTest.apk
I: Using Apktool 2.6.0 on demo-app-debug-androidTest.apk
I: Loading resource table...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at brut.androlib.res.AndrolibResources.selectPkgWithMostResSpecs(AndrolibResources.java:103)
at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:76)
at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:56)
at brut.androlib.Androlib.getResTable(Androlib.java:69)
at brut.androlib.ApkDecoder.getResTable(ApkDecoder.java:247)
at brut.androlib.ApkDecoder.decode(ApkDecoder.java:109)
at brut.apktool.Main.cmdDecode(Main.java:175)
at brut.apktool.Main.main(Main.java:78)
Steps to Reproduce
apktool -f d demo-app-debug-androidTest.apk
APK produced with AGP < 7:
~/Downloads unzip -l demo-app-debug-androidTest.apk
Archive: demo-app-debug-androidTest.apk
Length Date Time Name
--------- ---------- ----- ----
4145064 01-01-1981 01:01 classes.dex
25220 01-01-1981 01:01 classes2.dex
11376 01-01-1981 01:01 LICENSE-junit.txt
34 01-01-1981 01:01 META-INF/services/kotlin.test.AsserterContributor
964 01-01-1981 01:01 junit/runner/logo.gif
883 01-01-1981 01:01 junit/runner/smalllogo.gif
3328 01-01-1981 01:01 AndroidManifest.xml
384 01-01-1981 01:01 resources.arsc
901 01-01-1981 01:01 META-INF/CERT.SF
1400 01-01-1981 01:01 META-INF/CERT.RSA
827 01-01-1981 01:01 META-INF/MANIFEST.MF
--------- -------
4190381 11 files
APK produced with AGP 7
~/Downloads unzip -l demo-app-debug-androidTest.apk
Archive: demo-app-debug-androidTest.apk
Length Date Time Name
--------- ---------- ----- ----
4145044 01-01-1981 01:01 classes.dex
24964 01-01-1981 01:01 classes2.dex
11376 01-01-1981 01:01 LICENSE-junit.txt
34 01-01-1981 01:01 META-INF/services/kotlin.test.AsserterContributor
964 01-01-1981 01:01 junit/runner/logo.gif
883 01-01-1981 01:01 junit/runner/smalllogo.gif
3328 01-01-1981 01:01 AndroidManifest.xml
40 01-01-1981 01:01 resources.arsc
901 01-01-1981 01:01 META-INF/CERT.SF
1400 01-01-1981 01:01 META-INF/CERT.RSA
827 01-01-1981 01:01 META-INF/MANIFEST.MF
--------- -------
4189761 11 files
Extra clarification - in case of AGP < 7 resources.arsc after decoding contains only:
<?xml version="1.0" encoding="utf-8"?>
<resources />
so essentially it is empty.
Brain is blanking - what is AGP? GooglePlay something?
Android Gradle Plugin
To save me time, can you share those two applications or even push the test source via PR to this repo under 2701? https://github.com/iBotPeaches/TestApks
I see the same exception when I use Apktool on any recent "Android Instrumented Test" APK. I assume inez's APK is also a instrumented test APK based on the "-androidTest" in the file name.
For example, you can use an APK from the latest Android CTS release, like android-cts/testcases/AlarmTestApp.apk in https://dl.google.com/dl/android/cts/android-cts-12_r2-linux_x86-arm.zip (source at https://android.googlesource.com/platform/cts/+/refs/tags/android-cts-12.0_r2/tests/AlarmManager/app/)
Alternatively, you can create a new test app in Android Studio, using the default template for Phone App with Empty Activity, then open the auto-generated "ExampleInstrumentedTest" and click on the "Run test" triangle in the margin next to the class name. That will generate the APK in app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
Just leaving a note that I attempted to build my own application for replication, kept getting manifest merge errors with a brand new empty application and gave up. I will return back to this ticket in time.
Can you give this a try? https://github.com/gramound/TestApks/commit/6f1f747ce9cbffd89094d147fd44c0954bb5a09b
./gradlew assembleDebugAndroidTest
apktool d ./app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
Until we figure this out, could we add a "case 0: pkg = null; break;" to loadMainPkg, such that we'd jump to the more meaningful exception "arsc files with zero packages or no arsc file found." instead of crashing inside selectPkgWithMostResSpecs?
@gramound - Pulled in your test app - thanks as well as fixing source to crash at right location as you mentioned. Have not peeked yet further at this time.
@inez - Does adding --no-res fix your issue? (It works for my test apks).
On second thought --no-res is not good enough for me, because it leaves the AndroidManifest.xml as binary XML.
The issue with this empty resources.arsc is that apktool can't find the main package name. Is there an alternate way of finding it? For example, I was able to workaround by injecting the main package name in readTableHeader()
if (packageCount == 0) {
ResPackage[] packages = new ResPackage[1];
packages[0] = new ResPackage(mResTable, 2, "com.example.my.package.name");
return packages;
}
Actually, prehaps injecting a default bogus package name could be good enough in that situation?
I had accidentally left the code snippet above in my build and was having no problem decompiling a whole bunch of apks that had nothing to do with the injected package name. Everything went fine. The only impact was the package="com.example.my.package.name" appearing in the AndroidManifest.xml, but it doesn't affect anything else. (better than nothing?)
I'll admit this ticket really confused me at first, but after another look. We are building the test sample which must be some shell of the application to trigger tests.
So have a patch going up that properly survives decoding with an empty resource table. You'll basically get nothing because the resource table is basically nothing.
➜ 2701 xxd resources.arsc
00000000: 0200 0c00 2800 0000 0000 0000 0100 1c00 ....(...........
00000010: 1c00 0000 0000 0000 0000 0000 0001 0000 ................
00000020: 1c00 0000 0000 0000 ........
➜ 2701
➜ 2701 apktool d app-debug-androidTest.apk -f
I: Using Apktool 2.8.2-22eb80-SNAPSHOT on app-debug-androidTest.apk
I: Loading resource table...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/ibotpeaches/.local/share/apktool/framework/1.apk
I: Regular manifest package...
I: Baksmaling classes.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes3.dex...
I: Baksmaling classes4.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
➜ 2701
I extracted the sample apk from the test apk pr, updated gradle here and loaded into test suite.
Will close on merge of: https://github.com/iBotPeaches/Apktool/pull/3230
Sorry for delay.
Thanks! I just want to clarify we don't get nothing. We actually get the decompiled test source code (e.g. smali_classes3/com/ibotpeaches/issue2701/ExampleInstrumentedTest.smali) This is extremely useful with closed source test suites.