Closed harshitshah4 closed 1 year ago
@yujincheng08 thanks for the quick review, @vvb2060 @Dr-TSNG can we please get your review too.
@yujincheng08 can we get this PR merged ?
@yujincheng08 / @vvb2060 why did we revert this ?
modules should not load lspatch's so.
@yujincheng08 Module was not loading lspatch.so
file, LSPatch was loading it internally. Since we have added System.load
method in static
block in LSPAppComponentFactory.stub
method, sometimes apps gets restarted on its own, and the static block in App Component Factory gets loaded again in to memory due to which System.load
method gets called again. Hence only some apps were crashing.
@yujincheng08 @vvb2060 I feel this is a valid bug in LSPatch, and should be merged in master to fix this.
so will ur fix works? if app is reloaded, and thus the lspatch classloader is reloaded, will the reloaded lspatch and app work?
Yes.
how? since lspatch.so is not loaded successfully?
lspatch.so has loaded already, and we are trying to reload it hence it is failing.
I think AppComponentFactory will only be loaded once. Can you show me the code that AppComponentFactory will be loaded the second time by different classloader? Since you don't show the full backtrace, I cannot reference the code.
@yujincheng08 sharing the complete stacktrace:
06-01 13:09:24.926 W/istmobile.debu(31172): ClassLoaderContext classpath size mismatch. expected=0, found=42 (PCL[]{PCL[/system/framework/org.apache.http.legacy.jar*1038351580]} | PCL[/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk*963391286:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes2.dex*3523290992:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes3.dex*1437002724:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes4.dex*3949827186:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes5.dex*104114143:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes6.dex*1198623303:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes7.dex*30799929:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.
06-01 13:09:24.954 E/System (31172): Unable to open zip file: /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk
06-01 13:09:24.954 E/System (31172): java.io.FileNotFoundException: /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk (No such file or directory)
06-01 13:09:24.954 E/System (31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:164)
06-01 13:09:24.955 I/LSPatch-MetaLoader(31172): Bootstrap loader from embedment
06-01 13:09:24.968 W/istmobile.debu(31172): Shared library "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/assets/lspatch/so/arm64-v8a/liblspatch.so" already opened by ClassLoader 0x1c7(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]]); can't open in ClassLoader 0x7ff8d8befc(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk", zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/user/0/org.houstonmethodist.methodistmo
06-01 13:09:24.969 I/LSPosed-Bridge(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:514)
06-01 13:09:24.969 I/LSPosed-Bridge(31172): Caused by: java.lang.UnsatisfiedLinkError: Shared library "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/assets/lspatch/so/arm64-v8a/liblspatch.so" already opened by ClassLoader 0x1c7(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]]); can't open in ClassLoader 0x7ff8d8befc(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk", zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]])
06-01 13:09:24.969 I/LSPosed-Bridge(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:464)
06-01 13:09:24.969 E/AndroidRuntime(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:514)
06-01 13:09:24.969 E/AndroidRuntime(31172): Caused by: java.lang.UnsatisfiedLinkError: Shared library "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/assets/lspatch/so/arm64-v8a/liblspatch.so" already opened by ClassLoader 0x1c7(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]]); can't open in ClassLoader 0x7ff8d8befc(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk", zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]])
06-01 13:09:24.969 E/AndroidRuntime(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:464)
hmm, still dont know where LSPAppComponentFactoryStub is loaded.
You can check these log lines:
06-01 13:08:47.000 I/LSPatch-MetaLoader(31172): Bootstrap loader from embedment
06-01 13:08:47.104 I/LSPatch (31172): Use manager: false
06-01 13:08:47.104 I/LSPatch (31172): Signature bypass level: 0
06-01 13:08:47.107 I/LSPatch (31172): Extract original apk
06-01 13:08:47.511 I/LSPatch (31172): hooked app initialized: android.app.LoadedApk@8c9a549
06-01 13:08:47.519 W/LSPatch (31172): Original AppComponentFactory not found: androidx.core.app.CoreComponentFactory
06-01 13:08:47.519 D/LSPatch (31172): Initialize service client
06-01 13:08:47.523 I/LSPatch (31172): Extract module apk: com.varuns2002.disable_flag_secure
06-01 13:08:47.533 D/LSPatch (31172): Processing /data/misc/profiles/cur/0/com.sample.app.debug/primary.prof
06-01 13:08:47.540 D/LSPatch (31172): Skip profile /data/misc/profiles/cur/0/com.sample.app.debug/primary.prof
06-01 13:08:47.551 I/LSPatch (31172): Bootstrap Xposed
06-01 13:08:47.560 I/LSPosed-Bridge(31172): Loading module com.varuns2002.disable_flag_secure from /data/user/0/com.sample.app.debug/cache/lspatch/com.varuns2002.disable_flag_secure/3335930313.apk
06-01 13:08:47.571 I/LSPatch (31172): Load modules
06-01 13:08:50.620 I/LSPatch (31172): Modules initialized
06-01 13:08:50.621 I/LSPatch (31172): LSPatch bootstrap completed
06-01 13:09:24.926 W/istmobile.debu(31172): ClassLoaderContext classpath size mismatch. expected=0, found=42 (PCL[]{PCL[/system/framework/org.apache.http.legacy.jar*1038351580]} | PCL[/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk*963391286:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes2.dex*3523290992:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes3.dex*1437002724:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes4.dex*3949827186:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes5.dex*104114143:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes6.dex*1198623303:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!classes7.dex*30799929:/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.
06-01 13:09:24.954 E/System (31172): Unable to open zip file: /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk
06-01 13:09:24.954 E/System (31172): java.io.FileNotFoundException: /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk (No such file or directory)
06-01 13:09:24.954 E/System (31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:164)
06-01 13:09:24.955 I/LSPatch-MetaLoader(31172): Bootstrap loader from embedment
06-01 13:09:24.968 W/istmobile.debu(31172): Shared library "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/assets/lspatch/so/arm64-v8a/liblspatch.so" already opened by ClassLoader 0x1c7(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]]); can't open in ClassLoader 0x7ff8d8befc(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk", zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/user/0/org.houstonmethodist.methodistmo
06-01 13:09:24.969 I/LSPosed-Bridge(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:514)
06-01 13:09:24.969 I/LSPosed-Bridge(31172): Caused by: java.lang.UnsatisfiedLinkError: Shared library "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/assets/lspatch/so/arm64-v8a/liblspatch.so" already opened by ClassLoader 0x1c7(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]]); can't open in ClassLoader 0x7ff8d8befc(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk", zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]])
06-01 13:09:24.969 I/LSPosed-Bridge(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:464)
06-01 13:09:24.969 E/AndroidRuntime(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:514)
06-01 13:09:24.969 E/AndroidRuntime(31172): Caused by: java.lang.UnsatisfiedLinkError: Shared library "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/assets/lspatch/so/arm64-v8a/liblspatch.so" already opened by ClassLoader 0x1c7(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]]); can't open in ClassLoader 0x7ff8d8befc(dalvik.system.PathClassLoader[DexPathList[[zip file "/data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk", zip file "/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/base.apk"],nativeLibraryDirectories=[/data/app/com.sample.app.debug-QEePRTHZDLE9exp1cVuEfA==/lib/arm64, /data/user/0/com.sample.app.debug/cache/lspatch/origin/4198609975.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]])
06-01 13:09:24.969 E/AndroidRuntime(31172): at org.lsposed.lspatch.metaloader.LSPAppComponentFactoryStub.<clinit>(Unknown Source:464)
If you see at the log line: Bootstrap loader from embedment
in above logs, this log line is added in code at this point: https://github.com/LSPosed/LSPatch/blob/e79bf0e004b17171607ab04dcd42f05493d59d9f/meta-loader/src/main/java/org/lsposed/lspatch/metaloader/LSPAppComponentFactoryStub.java#L85, which means LSPAppComponentFactoryStub is loaded, and hence causing the crash.
I mean, who loaded the LSPAppComponentFactoryStub?
This whole code is inside static block in LSPAppComponentFactoryStub
As in Android/ Java every static block gets loaded automatically as soon as the class is referenced, which generally happens when app is started / re-started
I know. So where the new classloader is created and who loads LSPAppComponentFactoryStub
to trigger the clinit?
There could be multiple reasons for clinit to getting calling multiple times, it is not guaranteed to be called only once. It could happen in case of class reloading: In some cases, such as during hot swapping or dynamic code reloading, the class may be reloaded, leading to the execution of the static block again.
it is not guaranteed to be called only once
no. pls learn java better.
the reason is that someone has created a new classloader of the base apk (not the original one) and loaded LSPAppComponentFactoryStub
again. we need to find out where and who did this.
@yujincheng08 even if what you are saying is true, someone can write a code in an "app" to do that. And if the app works without patching, we should try to make it work with patching too.
so the app writes some anti-lspatch codes, right? intentedly query the pm for the base apk, load it and load LSPAppComponentFactoryStub
right?
The app that I am testing has not written anti-lspatch code. They might query pm of base.apk as a "valid" workflow in their app.
Even if someone is loading all the class files in base apks using pm, its a valid use case in app, it shouldn't mean that they have written anti-lspatch mechanisms.
@yujincheng08 We are also seeing this log line:
ClassLoaderContext classpath size mismatch. expected=0, found=42 (PCL[]{PCL[/system/framework/org.apache.http.legacy.jar*1038351580]} | PCL[/data/user/0/com.example.app/cache/lspatch/origin/4198609975.apk*963391286:/data/user/0/org.houstonmethodist.methodistmobile.debug/cache/lspatch/origin/4198609975.apk!classes2.dex*3523290992:/data/user/0/org.houstonmethodist.methodistmobile.debug/cache/lspatch/origin/4198609975.apk!classes3.dex*1437002724:/data/user/0/org.houstonmethodist.methodistmobile.debug/cache/lspatch/origin/4198609975.apk!classes4.dex*3949827186:/data/user/0/org.houstonmethodist.methodistmobile.debug/cache/lspatch/origin/4198609975.apk!classes5.dex*104114143:/data/user/0/org.houstonmethodist.methodistmobile.debug/cache/lspatch/origin/4198609975.apk!classes6.dex*1198623303:/data/user/0/org.houstonmethodist.methodistmobile.debug/cache/lspatch/origin/4198609975.apk!classes7.dex*30799929:/data/user/0/
Running dexopt (dexoptNeeded=1) on: /data/app/com.example.app-QEePRTHZDLE9exp1cVuEfA==/base.apk
Not sure if it can help you debug.
Found this reference: https://source.android.com/docs/core/runtime/art-class-loader-context#boot-time-clc-mismatch
Also the app is crashing on Android v10, and working on other versions
someone can write a code in an "app" to do that.
@yujincheng08 @harshitshah4 Is this not a valid usecase for android apps?
Yes @ayush5harma this is a valid use case in an Android app, and hence its a valid bug in LSPatch. @yujincheng08
AppComponentFactory
for a process, which should be loaded by the system framework. LSPatch replaces it with LSPAppComponentFactoryStub
and loads lspatch.so
.LSPAppComponentFactoryStub
does).HelloWorld
, what would happen? There's no such class in LSPatch's classloader.I think this behavior is expected if the l2 signature bypass is off. Because we cannot forward class loading to the correct classloader perfectly. Imagine if an app loads its base.apk again, and loads some class with strange names that do not exist in LSPatch's classloader and crashes, how can we avoid this?
@yujincheng08 thanks for the detailed explanation. Since you mentioned that app is trying to load class files in base.apk, due to which LSPAppComponentFactory is getting loaded. Is there a way to redirect the PackageManager to point to the original apk, and not LSPatch apk
it should be able to bypass by enabling the level 2 signature bypass
@yujincheng08 The app crashes with same reason even after level 2 signature bypass
We have seen apps to be crashing due to multiple System.load calls. As seen from the log lines:
Looks like we are trying to load liblspatch.so file even when it was loaded earlier by the ClassLoader, due to which it is causing the error.
This is similar to this issue: https://stackoverflow.com/questions/54155086/preventing-duplicate-system-loadlibrary-calls-when-dynamically-loading-reloading
Have added try ... catch block around
System.load
method to handle exceptions / error raised from it, and have added log line to debug the issue in cases of actual errors.