为什么打完smali补丁后APK无法安装?

Why APK could not be installed after Smali patching?

这是 TestClassMainActivity

为了始终显示 Toast,我更改了 TestClass constructor 使用 smali 补丁 到以下:

但是编译签名后,新打补丁的apk无法安装

问题出在哪里??

补丁代码如下:

iput-boolean p1, p0, Lcom/example/test1/TestClass;->testB:Z

if-nez p1, :cond_0

const/4 p1, 0x1

iput-boolean p1, p0, Lcom/example/test1/TestClass;->testB:Z

:cond_0

这是安装时的LOGCAT:

1772  1772 D AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<

1772  1772 D AndroidRuntime: CheckJNI is OFF

1772  1772 D ICU     : No timezone override file found: /data/misc/zoneinfo/current/icu/icu_tzdata.dat

1772  1772 E memtrack: Couldn't load memtrack module (No such file or directory)

1772  1772 E android.os.Debug: failed to load memtrack module: -2

1772  1772 I Radio-JNI: register_android_hardware_Radio DONE

1772  1772 D AndroidRuntime: Calling main entry com.android.commands.pm.Pm

1594  1606 D DefContainer: Copying /data/local/tmp/app-release_SIGNED_UNALIGNED.apk to base.apk

 637   662 D NativeLibraryHelper: Library 'libtoolChecker.so' is not page-aligned - will not be able to open it directly from apk.

 637   662 W NativeHelper: Failure copying native libraries [errorCode=-2]

 637   662 I art     : Starting a blocking GC Explicit

 637   662 I art     : Explicit concurrent mark sweep GC freed 34438(1881KB) AllocSpace objects, 2(40KB) LOS objects, 33% free, 6MB/9MB, paused 267us total 14.270ms

1772  1772 I art     : System.exit called, status: 1

1772  1772 I AndroidRuntime: VM exiting with result code 1.

简答

使用处理 v2 签名的 zipalign and (if not already) sign using apksigner 对齐 APK 文件,这是一项附加要求。

长答案

您的 logcat 中有两次提到对齐,这强烈表明您的 APK 文件未对齐。由于Android 11,有一个requirement APK文件包含一个未压缩的resources.asrc文件,它在文件中对齐到4个字节。

通过 ADB 复制问题,我使用了以下内容:

# 1) Install the original APK file
adb install original.apk

# 2) Decode the original APK file, decompiling into Smali
apktool decode --output original original.apk

# 3) Apply the logic patch
patch -p1 < switch.patch

# 4) Rebuild an APK file with the patch
apktool build --output rebuilt.apk original

# 5) Sign the rebuilt APK file
jarsigner -keystore keystore -storepass password rebuilt.apk key0

# 6) Attempt installation of the rebuilt APK file
adb install -r rebuilt.apk

这会导致以下错误:

adb: failed to install rebuilt.apk: Failure [-124: Failed parse during installPackageLI: Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed and aligned on a 4-byte boundary]

我的第一个想法是在使用 jarsigner 对 APK 进行签名后简单地使用 zipalign,如下所示:

# 1) Install the original APK file
adb install original.apk

# 2) Decode the original APK file, decompiling into Smali
apktool decode --output original original.apk

# 3) Apply the logic patch
patch -p1 < switch.patch

# 4) Rebuild an APK file with the patch
apktool build --output rebuilt.apk original

# 5) Sign the rebuilt APK file
jarsigner -keystore keystore -storepass password rebuilt.apk key0

# 6) Create an aligned APK file
zipalign 4 rebuilt.apk rebuilt-aligned.apk

# 7) Attempt installation of the rebuilt APK file
adb install -r rebuilt-aligned.apk

但是,这导致了以下错误:

adb: failed to install rebuilt-aligned.apk: Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Scanning Failed.: No signature found in package of version 2 or newer for package au.com.msbit.a68855123]

这表明还有一个 requirement 和 Android 11; APK 文件使用 v2 签名方案进行签名,这需要 apksigner。将两者放在一起,就像下面的作品:

# 1) Install the original APK file
adb install original.apk

# 2) Decode the original APK file, decompiling into Smali
apktool decode --output original original.apk

# 3) Apply the logic patch
patch -p1 < switch.patch

# 4) Rebuild an APK file with the patch
apktool build --output rebuilt.apk original

# 5) Create an aligned APK file
zipalign 4 rebuilt.apk rebuilt-aligned.apk

# 6) Sign the rebuilt APK file
apksigner sign --ks keystore --ks-pass pass:password rebuilt-aligned.apk

# 7) Attempt installation of the rebuilt APK file
adb install -r rebuilt-aligned.apk

apksigner 的文档中所述,在对 APK 文件进行任何修改后,它必须是 运行,因此,与使用 jarsigner 时的顺序相反, zipalign 必须在 运行 之前 apksigner.