Apktool icon indicating copy to clipboard operation
Apktool copied to clipboard

[BUG] ArrayIndexOutOfBoundsException exception for APK without resources produced with AGP7

Open inez opened this issue 3 years ago • 9 comments
trafficstars

Information

  1. Apktool Version (apktool -version) - 2.6.0
  2. Operating System (Mac, Linux, Windows) - Mac
  3. 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

  1. 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

inez avatar Nov 24 '21 17:11 inez

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.

inez avatar Nov 24 '21 18:11 inez

Brain is blanking - what is AGP? GooglePlay something?

iBotPeaches avatar Nov 24 '21 21:11 iBotPeaches

Android Gradle Plugin

inez avatar Nov 24 '21 21:11 inez

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

iBotPeaches avatar Nov 27 '21 12:11 iBotPeaches

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

gramound avatar Dec 14 '21 20:12 gramound

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.

iBotPeaches avatar Jan 17 '22 13:01 iBotPeaches

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

gramound avatar Jan 20 '22 00:01 gramound

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 avatar Jul 07 '22 17:07 gramound

@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.

iBotPeaches avatar Jul 10 '22 13:07 iBotPeaches

@inez - Does adding --no-res fix your issue? (It works for my test apks).

gramound avatar Oct 26 '22 05:10 gramound

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;
}

gramound avatar Dec 09 '22 18:12 gramound

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?)

gramound avatar Dec 15 '22 19:12 gramound

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.

iBotPeaches avatar Jul 29 '23 10:07 iBotPeaches

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.

gramound avatar Jul 31 '23 18:07 gramound