在Android开发中,Xposed框架允许开发者通过Hook机制修改或增强现有应用的功能。然而,当应用使用AndroidManifestApplication_appComponentFactory属性时,可能会遇到一些挑战,特别是在模块加载的早期阶段。本文将探讨如何创建一个Xposed模块来Hook使用CoreComponentFactory的应用,并分析在应用启动过程中handleLoadPackage()方法未被调用的原因以及可能的解决方案。

复现步骤

  1. 创建一个Xposed模块,用于Hook那些使用AndroidManifestApplication_appComponentFactory属性的应用,例如androidx.core.app.CoreComponentFactory
  2. 启动目标应用。

预期行为

预期在应用启动时,handleLoadPackage()方法会被调用,这样就可以进行方法Hook。

实际行为

实际情况下,handleLoadPackage()方法在appComponentFactory类被加载之前没有被调用,因此无法Hook相关方法。这是否意味着在这么早的阶段就进行方法Hook是不被支持的?

相关链接

Xposed模块列表

Custom xposed module `dev.agnosticapollo.foo` for `com.foo` app.

Root方案

使用Magisk 29

系统模块列表

Zygisk-LSPosed

LSPosed版本

v1.10.2 (7199) 0e457e3247ed01c818848d54d2dc556f963b46af

Android版本

未提供

版本要求

  • 使用GitHub Actions提供的最新调试版本。

日志

无Xposed模块时的堆栈跟踪

at androidx.core.app.CoreComponentFactory.<clinit>
at java.lang.Class.newInstance(Native Method)
at android.app.LoadedApk.createAppFactory(LoadedApk.java:260)
at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:902)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:982)
at android.app.ContextImpl.createAppContext(ContextImpl.java:2663)
at android.app.ContextImpl.createAppContext(ContextImpl.java:2655)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6602)
at android.app.ActivityThread.access$1300(ActivityThread.java:237)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7664)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

有Xposed模块时的堆栈跟踪

at androidx.core.app.CoreComponentFactory.<clinit>
at java.lang.Class.newInstance(Native Method)
at android.app.LoadedApk.createAppFactory(LoadedApk.java:260)
at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:902)
at java.lang.reflect.Method.invoke(Native Method)
at q.ChkgI.s.cAxrIL.ZL.p.aVdg.dG.HookBridge.invokeOriginalMethod(Native Method)
at org.lsposed.lspd.impl.LSPosedBridge$NativeHooker.callback(r8-map-id-262c2e0ff89d3cc5bb25cad9c304996a61abc774558320706d02f16a4c7c9177:190)
at LSPHooker_.createOrUpdateClassLoaderLocked(Unknown Source:11)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:982)
at android.app.LoadedApk.getResources(LoadedApk.java:1214)
at android.app.ContextImpl.createAppContext(ContextImpl.java:2663)
at android.app.ContextImpl.createAppContext(ContextImpl.java:2655)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6602)
at android.app.ActivityThread.access$1300(ActivityThread.java:237)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7664)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Logcat日志

LSPosed                 I Loading xposed for com.foo/xxxxx
LSPosed-Bridge          I Loading legacy module dev.agnosticapollo.foo from ...
com.foo                 W  Unsupported class loader
com.foo                 W  Could not establish class loader context
LSPosed-Bridge I        Loading class dev.agnosticapollo.foo.xposed.XposedModule
dev.agnosticapollo.foo  I  initZygote
LSPosed                 E  Compressed data is corrupt
<CoreComponentFactory is called here>

针对上述问题,开发者可能需要考虑在应用加载更晚的阶段进行Hook,或者检查是否有其他方法可以在应用启动早期进行干预。同时,确保Xposed模块和LSPosed的版本是最新的,以避免由于版本兼容性引起的问题。如果问题仍然存在,可能需要进一步检查应用的类加载机制和Hook的时机。