Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
inez opened this issue Nov 24, 2021 · 14 comments · Fixed by #3230
Closed
Milestone

Comments

@inez
Copy link

inez commented Nov 24, 2021

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
Copy link
Author

inez commented Nov 24, 2021

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.

@iBotPeaches
Copy link
Owner

Brain is blanking - what is AGP? GooglePlay something?

@inez
Copy link
Author

inez commented Nov 24, 2021

Android Gradle Plugin

@iBotPeaches
Copy link
Owner

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

Repository owner deleted a comment from Rone-s9 Dec 4, 2021
@gramound
Copy link
Contributor

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

@iBotPeaches
Copy link
Owner

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.

@gramound
Copy link
Contributor

Can you give this a try? gramound/TestApks@6f1f747
./gradlew assembleDebugAndroidTest
apktool d ./app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk

@gramound
Copy link
Contributor

gramound commented Jul 7, 2022

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?

@iBotPeaches
Copy link
Owner

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

@gramound
Copy link
Contributor

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

@gramound
Copy link
Contributor

gramound commented Dec 9, 2022

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
Copy link
Contributor

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

@iBotPeaches
Copy link
Owner

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: #3230

Sorry for delay.

iBotPeaches added a commit that referenced this issue Jul 29, 2023
@iBotPeaches iBotPeaches added this to the v2.8.2 milestone Jul 30, 2023
@gramound
Copy link
Contributor

gramound commented Jul 31, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants