SIGSEGV in artQuickGenericJniTrampoline while hooking java methods
Hooking a java method in system_server on a Samsung Android 13 S23 plus and A33 with the last updates causes a SIGSEGV/SEGV_MAPERR crash. On a S21 5G I cannot reproduce it.
My hypothesis is a change in libart.so but looking at the source code and diffing the binaries I couldn't find a reason.
p.s. not all methods seems to trigger the crash
sha1sum: 7c9ef90838717ac4d792139f8b1f7ca9692d018e /apex/com.android.art@341711000/lib64/libart.so
frida-gadget 16.2.5
crashlog
06-05 11:55:59.313 2457 2457 I frida : Debug1
06-05 11:55:59.318 2457 2457 I frida : ComputerEngine: <class: com.android.server.pm.ComputerEngine>
...
...
...
06-05 11:56:07.354 2457 3623 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1b96c0 in tid 3623 (binder:2457_4), pid 2457 (system_server)
...
...
...
06-05 11:56:08.544 18081 18081 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-05 11:56:08.544 18081 18081 F DEBUG : Build fingerprint: 'samsung/dm2qxeea/dm2q:13/TP1A.220624.014/S916BXXS3AWIF:user/release-keys'
06-05 11:56:08.544 18081 18081 F DEBUG : Revision: '13'
06-05 11:56:08.544 18081 18081 F DEBUG : ABI: 'arm64'
06-05 11:56:08.544 18081 18081 F DEBUG : Processor: '5'
06-05 11:56:08.544 18081 18081 F DEBUG : Timestamp: 2024-06-05 11:56:07.512826284+0200
06-05 11:56:08.544 18081 18081 F DEBUG : Process uptime: 1136s
06-05 11:56:08.544 18081 18081 F DEBUG : Cmdline: system_server
06-05 11:56:08.544 18081 18081 F DEBUG : pid: 2457, tid: 3623, name: binder:2457_4 >>> system_server <<<
06-05 11:56:08.544 18081 18081 F DEBUG : uid: 1000
06-05 11:56:08.544 18081 18081 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
06-05 11:56:08.544 18081 18081 F DEBUG : pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY)
06-05 11:56:08.544 18081 18081 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x00000000001b96c0
06-05 11:56:08.544 18081 18081 F DEBUG : x0 00000000001b96b0 x1 000000791c8f3fd0 x2 000000791c8f2bd0 x3 0000000000000000
06-05 11:56:08.544 18081 18081 F DEBUG : x4 00000000000003e8 x5 0000000000000000 x6 0000000000000000 x7 0000000014031000
06-05 11:56:08.544 18081 18081 F DEBUG : x8 0000000012f2d7c0 x9 0000000000000000 x10 000000000bcb3946 x11 0000000000000005
06-05 11:56:08.544 18081 18081 F DEBUG : x12 000000791c8f3f28 x13 0000007b01c16000 x14 000000791c8f5000 x15 0000007a001baa70
06-05 11:56:08.544 18081 18081 F DEBUG : x16 0000000000001400 x17 00000077ffe41ac4 x18 000000791b904000 x19 0000007a649898d0
06-05 11:56:08.544 18081 18081 F DEBUG : x20 000000791c8f3fd0 x21 b4000079974bb400 x22 000000791c8f2bd0 x23 00000000400c0000
06-05 11:56:08.544 18081 18081 F DEBUG : x24 0000000000000000 x25 00000000000003e8 x26 0000000014031000 x27 000000791c8f5000
06-05 11:56:08.544 18081 18081 F DEBUG : x28 000000791c8f3fd0 x29 000000791c8f2b70
06-05 11:56:08.544 18081 18081 F DEBUG : lr 0000007b01351e00 sp 000000791c8f2a70 pc 0000007b012cbbd4 pst 0000000060001000
06-05 11:56:08.544 18081 18081 F DEBUG : backtrace:
06-05 11:56:08.544 18081 18081 F DEBUG : #00 pc 00000000002cbbd4 /apex/com.android.art/lib64/libart.so (artQuickGenericJniTrampoline+88) (BuildId: ddcc440d4609d2099db9d20895487a78)
06-05 11:56:08.544 18081 18081 F DEBUG : #01 pc 0000000000351dfc /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+92) (BuildId: ddcc440d4609d2099db9d20895487a78)
06-05 11:56:08.544 18081 18081 F DEBUG : #02 pc 0000000003beba88 /data/misc/apexdata/com.android.art/dalvik-cache/arm64/system@[email protected]@classes.odex (com.android.server.pm.ComputerEngine.getInstalledPackages+376)
06-05 11:56:08.544 18081 18081 F DEBUG : #03 pc 0000000002f67c4c /data/misc/apexdata/com.android.art/dalvik-cache/arm64/system@[email protected]@classes.odex (com.android.server.pm.IPackageManagerBase.getInstalledPackages+92)
06-05 11:56:08.544 18081 18081 F DEBUG : #04 pc 0000000002fbd614 /data/misc/apexdata/com.android.art/dalvik-cache/arm64/system@[email protected]@classes.odex (com.android.server.pm.ModuleInfoProvider.getInstalledModules+548)
06-05 11:56:08.544 18081 18081 F DEBUG : #05 pc 00000000023d8978 /data/misc/apexdata/com.android.art/dalvik-cache/arm64/system@[email protected]@classes.odex ([DEDUPED]+40)
06-05 11:56:08.544 18081 18081 F DEBUG : #06 pc 00000000008b754c /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.content.pm.IPackageManager$Stub.onTransact+8700)
06-05 11:56:08.544 18081 18081 F DEBUG : #07 pc 00000000039499a8 /data/misc/apexdata/com.android.art/dalvik-cache/arm64/system@[email protected]@classes.odex (com.android.server.pm.PackageManagerService$IPackageManagerImpl.onTransact+72)
06-05 11:56:08.544 18081 18081 F DEBUG : #08 pc 0000000000a93428 /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.Binder.execTransactInternal+696)
06-05 11:56:08.544 18081 18081 F DEBUG : #09 pc 0000000000a930c0 /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.Binder.execTransact+272)
06-05 11:56:08.544 18081 18081 F DEBUG : #10 pc 000000000033b3a4 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: ddcc440d4609d2099db9d20895487a78)
06-05 11:56:08.544 18081 18081 F DEBUG : #11 pc 0000000000339404 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+772) (BuildId: ddcc440d4609d2099db9d20895487a78)
06-05 11:56:08.544 18081 18081 F DEBUG : #12 pc 000000000055bca8 /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallBooleanMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+192) (BuildId: ddcc440d4609d2099db9d20895487a78)
06-05 11:56:08.544 18081 18081 F DEBUG : #13 pc 00000000000c5714 /system/lib64/libandroid_runtime.so (_JNIEnv::CallBooleanMethod(_jobject*, _jmethodID*, ...)+124) (BuildId: 5a5ea2fc60784763fe10b9d6fa7c490b)
06-05 11:56:08.544 18081 18081 F DEBUG : #14 pc 000000000017c2c0 /system/lib64/libandroid_runtime.so (JavaBBinder::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+160) (BuildId: 5a5ea2fc60784763fe10b9d6fa7c490b)
06-05 11:56:08.544 18081 18081 F DEBUG : #15 pc 0000000000051a1c /system/lib64/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+240) (BuildId: 0234f9002fd61e3de30c847bdd330237)
06-05 11:56:08.544 18081 18081 F DEBUG : #16 pc 000000000005caf8 /system/lib64/libbinder.so (android::IPCThreadState::executeCommand(int)+1040) (BuildId: 0234f9002fd61e3de30c847bdd330237)
06-05 11:56:08.544 18081 18081 F DEBUG : #17 pc 000000000005c61c /system/lib64/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+164) (BuildId: 0234f9002fd61e3de30c847bdd330237)
06-05 11:56:08.544 18081 18081 F DEBUG : #18 pc 000000000005cef0 /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+72) (BuildId: 0234f9002fd61e3de30c847bdd330237)
06-05 11:56:08.544 18081 18081 F DEBUG : #19 pc 000000000008d164 /system/lib64/libbinder.so (android::PoolThread::threadLoop()+448) (BuildId: 0234f9002fd61e3de30c847bdd330237)
06-05 11:56:08.544 18081 18081 F DEBUG : #20 pc 0000000000013418 /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+424) (BuildId: 97f353c1a350efeb766e1e852854da85)
06-05 11:56:08.544 18081 18081 F DEBUG : #21 pc 00000000000ce7e8 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+144) (BuildId: 5a5ea2fc60784763fe10b9d6fa7c490b)
06-05 11:56:08.544 18081 18081 F DEBUG : #22 pc 00000000000f5298 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 1bcad8bca80d38bceb9089f70d394e33)
06-05 11:56:08.544 18081 18081 F DEBUG : #23 pc 000000000008ebdc /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68) (BuildId: 1bcad8bca80d38bceb9089f70d394e33)
reproducer script:
if (Java.available) {
Java.perform(function () {
Java.use("android.util.Log").i("frida", "Debug1");
var ComputerEngine = Java.use("com.android.server.pm.ComputerEngine");
Java.use("android.util.Log").i("frida", "ComputerEngine: " + ComputerEngine);
ComputerEngine["getInstalledPackagesBody"].implementation = function (flags, userId, callingUid) {
Java.use("android.util.Log").i("frida", "I'm here");
return this["getInstalledPackagesBody"](flags, userId, callingUid);
};
});
}
to trigger the crash you can open the Settings app and navigate in the app list.
the crash happens when the jvm tries to access the hooked method
public final ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId) {
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
return ParceledListSlice.emptyList();
}
if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForPackage(flags, userId);
enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
false /* checkShell */, "get installed packages");
return getInstalledPackagesBody(flags, userId, callingUid);<----crash
}
protected ParceledListSlice<PackageInfo> getInstalledPackagesBody(long flags, int userId,
int callingUid) {
artQuickGenericJniTrampoline:
It looks like is is a problem related to the garbage collector, with frida disabling GarbageCollector::Run() prevents the crashes
Adding that two of my devices (Android 12 and Android 14) have the same issue, both of them have /apex/com.android.art@341711000 and did not have issues before.
In my case,
- Use Magisk + Zygisk + Shamiko (~ Android13: Worked, Android 14: Need to test)
- Use KernelSU (GKI Only, Android 12 or 12.1(12L) Only) : KernelSU + Android 13+ (App Crashed) : Non-GKI: Unpredictable
- APatch: I didn't use it, so i don't know.
Currently the only working workaround is hooking the onLeave of the RunPhases of the art GC and refresh all the hooks. I've tried to do some debugging and commit diffing in libart but I couldn't find anything edit: this solution crashes the process after a while
I have tried to test frida-java-bridge but on a Pixel 6 (14.0.0 (AP2A.240605.024, Jun 2024) ) with the latest Google Play system update( open settings->search "Play system"->Google Play system update->check for update)
with the latest frida-server and frida-tools(both 16.4.2) on my mac this repo cloned exported the correct env variables
$ make check
[*] Running the test suite with optimizations disabled (interpreter mode).
/Users/foo/Downloads/Xcode.app/Contents/Developer/usr/bin/make -C test deploy
d8 \
--output build/tests.zip \
--classpath /Users/foo/Library/Android/sdk/platforms/android-33/android.jar \
--min-api 33 \
build/tests.jar
cd build && unzip tests.zip classes.dex
Archive: tests.zip
inflating: classes.dex
mv build/classes.dex build/tests.dex
adb shell "rm -rf /data/local/tmp/frida-java-bridge-tests && mkdir -p /data/local/tmp/frida-java-bridge-tests"
adb push build/arm64-v8a/runner build/tests.dex build/frida-java-bridge.js build/arm64-v8a/libartpalette.so /data/local/tmp/frida-java-bridge-tests
build/arm64-v8a/runner: 1 file pushed, 0 skipped. 90.3 MB/s (6644256 bytes in 0.070s)
build/tests.dex: 1 file pushed, 0 skipped. 270.4 MB/s (312744 bytes in 0.001s)
build/frida-java-bridge.js: 1 file pushed, 0 skipped. 318.0 MB/s (352730 bytes in 0.001s)
build/arm64-v8a/libartpalette.so: 1 file pushed, 0 skipped. 66.0 MB/s (4680 bytes in 0.000s)
4 files pushed, 0 skipped. 49.0 MB/s (7314410 bytes in 0.142s)
/Users/foo/Downloads/Xcode.app/Contents/Developer/usr/bin/make -C test run
adb shell "LD_PRELOAD=libart.so LD_LIBRARY_PATH='/apex/com.android.runtime/lib64:/apex/com.android.art/lib64:/data/local/tmp/frida-java-bridge-tests' /data/local/tmp/frida-java-bridge-tests/runner "
CANNOT LINK EXECUTABLE "/data/local/tmp/frida-java-bridge-tests/runner": cannot locate symbol "_ZN3fmt2v76detail7vformatENS0_17basic_string_viewIcEENS0_11format_argsE" referenced by "/apex/com.android.art/lib64/libart.so"...
make[2]: *** [run] Error 1
make[1]: *** [check-run] Error 2
make: *** [check] Error 2