iBotPeaches / Apktool

A tool for reverse engineering Android apk files

Home Page:https://apktool.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

huhuang03 opened this issue · comments

commented

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

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.

commented

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)

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.

commented

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)

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.

commented

🆗, already send by twitter.

Obtained thanks.

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.

commented

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

And I tried something like this: huhuang03@cdf6751
image

as a temporary workaround.

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

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.