iBotPeaches / Apktool

A tool for reverse engineering Android apk files
https://apktool.org/
Apache License 2.0
19.79k stars 3.56k forks source link

[BUG] apktool d xx.apk generate minSdkVersion and targetSdkVersion as empty '', but aapt not #3592

Open huhuang03 opened 4 months ago

huhuang03 commented 4 months ago

Information

  1. Apktool Version (apktool -version) - 2.9.3
  2. Operating System (Mac, Linux, Windows) - Windows
  3. APK From? (Playstore, ROM, Other) - Other
  4. Java Version (java --version) - 17.0.4

Stacktrace/Logcat

I: Using Apktool 2.9.3
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
        at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.base/java.lang.Integer.parseInt(Integer.java:662)
        at java.base/java.lang.Integer.parseInt(Integer.java:770)
        at brut.androlib.apk.ApkInfo.mapSdkShorthandToVersion(ApkInfo.java:199)
        at brut.androlib.apk.ApkInfo.getMinSdkVersionFromAndroidCodename(ApkInfo.java:163)
        at brut.androlib.ApkBuilder.build(ApkBuilder.java:86)
        at brut.apktool.Main.cmdBuild(Main.java:296)
        at brut.apktool.Main.main(Main.java:95)

Steps to Reproduce

  1. apktool apktool d xxx.apk, generate apktool.yml like this:
    
    sdkInfo:
    minSdkVersion: 
    targetSdkVersion: 

versionInfo: versionCode: versionName: 1.0.68


But us `aapt dump badging xxx.apk |grep Version` can see the versions

versionCode='68' versionName='1.0.68' platformBuildVersionName='6.0-2438415' platformBuildVersionCode='23' compileSdkVersion='23' compileSdkVersionCodename='6.0-2438415' install-location:'auto' sdkVersion:'19' targetSdkVersion:'26'



### Frameworks
If this APK is from an OEM ROM (Samsung, HTC, LG). Please attach framework files
(`.apks` that live in `/system/framework` or `/system/priv-app`)
No
### APK
If this APK can be freely shared, please upload/attach a link to it.
No
### Questions to ask before submission
1. Have you tried `apktool d`, `apktool b` without changing anything? Yes, still eror
2. If you are trying to install a modified apk, did you resign it? build failed, so not able to install
3. Are you using the latest apktool version? Yes
iBotPeaches commented 4 months ago

May you run aapt d xmltree file.apk AndroidManifest.xml? Only need the first 20 or so lines where it dumps out the version information.

huhuang03 commented 4 months ago

It look like it has value but is "" as string type, strange...

build-tools\29.0.2\aapt.exe d xmltree .\apk_file.apk AndroidManifest.xml
N: android=http://schemas.android.com/apk/res/android
  E: manifest (line=2)
    A: android:versionCode(0x0101021b)=(type 0x10)0x44 (Raw: "")
    A: android:versionName(0x0101021c)="1.0.68" (Raw: "1.0.68")
    A: android:installLocation(0x010102b7)=(type 0x10)0x0 (Raw: "")
    A: android:compileSdkVersion(0x01010572)=(type 0x10)0x17 (Raw: "")
    A: android:compileSdkVersionCodename(0x01010573)="6.0-2438415" (Raw: "6.0-2438415")
    A: package="xxx" (Raw: "xxx")
    A: platformBuildVersionCode=(type 0x10)0x17 (Raw: "23")
    A: platformBuildVersionName="6.0-2438415" (Raw: "6.0-2438415")
    E: uses-sdk (line=0)
      A: android:minSdkVersion(0x0101020c)=(type 0x10)0x13 (Raw: "")
      A: android:targetSdkVersion(0x01010270)=(type 0x10)0x1a (Raw: "")
    E: uses-feature (line=3)
      A: android:glEsVersion(0x01010281)=(type 0x11)0x20000 (Raw: "")
    E: supports-screens (line=4)
      A: android:anyDensity(0x0101026c)=(type 0x12)0xffffffff (Raw: "")
      A: android:smallScreens(0x01010284)=(type 0x12)0xffffffff (Raw: "")
      A: android:normalScreens(0x01010285)=(type 0x12)0xffffffff (Raw: "")
      A: android:largeScreens(0x01010286)=(type 0x12)0xffffffff (Raw: "")
      A: android:xlargeScreens(0x010102bf)=(type 0x12)0xffffffff (Raw: "")
    E: uses-permission (line=5)
iBotPeaches commented 4 months ago

Interesting. So I guess if its broken to the point that aapt cannot understand it, then its either actually empty or aapt can't handle it.

You can repeat that test with aapt2, I think its the same parameters. You just might need to do aapt2 d xmltree apk_file.apk --file AndroidManifest.xml to exclude that possibility.

huhuang03 commented 4 months ago

The raw apk can install and run normally. Looks like the the minSdkVersion has 19 in valueData, but the valueRaw is empty. image

It's not a normal situation.

And the aapt2 output:

build-tools\29.0.2\aapt2.exe d xmltree apk_douluodaluwuhunjuexing.apk --file AndroidManifest.xml
N: android=http://schemas.android.com/apk/res/android (line=0)
  E: manifest (line=2)
    A: http://schemas.android.com/apk/res/android:versionCode(0x0101021b)=68
    A: http://schemas.android.com/apk/res/android:versionName(0x0101021c)="1.0.68" (Raw: "1.0.68")
    A: http://schemas.android.com/apk/res/android:installLocation(0x010102b7)=0
    A: http://schemas.android.com/apk/res/android:compileSdkVersion(0x01010572)=23
    A: http://schemas.android.com/apk/res/android:compileSdkVersionCodename(0x01010573)="6.0-2438415" (Raw: "6.0-2438415")
    A: package="xxx" (Raw: "xxx")
    A: platformBuildVersionCode=23 (Raw: "23")
    A: platformBuildVersionName="6.0-2438415" (Raw: "6.0-2438415")
      E: uses-sdk (line=0)
        A: http://schemas.android.com/apk/res/android:minSdkVersion(0x0101020c)=19
        A: http://schemas.android.com/apk/res/android:targetSdkVersion(0x01010270)=26
      E: uses-feature (line=3)
        A: http://schemas.android.com/apk/res/android:glEsVersion(0x01010281)=0x00020000
      E: supports-screens (line=4)
        A: http://schemas.android.com/apk/res/android:anyDensity(0x0101026c)=true
        A: http://schemas.android.com/apk/res/android:smallScreens(0x01010284)=true
        A: http://schemas.android.com/apk/res/android:normalScreens(0x01010285)=true
        A: http://schemas.android.com/apk/res/android:largeScreens(0x01010286)=true
        A: http://schemas.android.com/apk/res/android:xlargeScreens(0x010102bf)=true
      E: uses-permission (line=5)
iBotPeaches commented 4 months ago

Well thats an interesting find. I don't actually know what AOSP reads by default, but that chunk you are looking at is the ResXMLTree_attribute one. We shift all elements of that into that mAttributes you are reviewing by those attribute indexes.

So

struct ResXMLTree_attribute
{
    // Namespace of this attribute.
    struct ResStringPool_ref ns;

    // Name of this attribute.
    struct ResStringPool_ref name;

    // The original raw string value of this attribute.
    struct ResStringPool_ref rawValue;

    // Processesd typed value of this attribute.
    struct Res_value typedValue;
};

If raw value is empty - it must mean AOSP only reads the typed value (data). I'll have to revisit that logic there, but it would really help to share the application so I can debug it directly. You can work with me in private and I won't share it anywhere if thats something you are open to.

huhuang03 commented 4 months ago

🆗, already send by twitter.

iBotPeaches commented 4 months ago

Obtained thanks.

iBotPeaches commented 3 months ago

Yeah this doesn't make any sense. I confirmed versionCode cannot be read as we do and if we read the raw typed value we get an unrelated property.

android.permission.RESTART_PACKAGES

The next item is also misspelled.

android.permission.BROADCfAST_STICKY

I don't know what is occurring here yet, but it almost seems like some resources are densely packed and others are not.

huhuang03 commented 3 months ago

Thank you for your time. Maybe it's not a normal apk.

And I tried something like this: https://github.com/huhuang03/Apktool/commit/cdf67517ab50c92b431179fcef8041671dae6322 image

as a temporary workaround.

I'm not familar to aapt. This issue can be close if it's not a normal situation.

iBotPeaches commented 3 months ago

I believe its a new form of obfuscation Apktool needs to support. Apktool has a flaw presently that it reads AXML by knowing the amount attributes and taking the assumed size of each attribute and spreading into an array set.

Then based on the shift/index we know how to read them. What I believe is happening here is smaller packed attributes are included. This causes everything to shift from what we expect and leads to some attributes disassembly improperly.

https://github.com/iBotPeaches/Apktool/blob/master/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java#L785-L789

Been traveling so haven't had as much time to dig into this.