Skip to content

Conversation

@oleavr
Copy link
Member

@oleavr oleavr commented Jan 7, 2026

No description provided.

@AeonLucid
Copy link
Contributor

Just gave this a try, when running Frida the system_server crashes.

01-07 22:33:56.729  7956  7956 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-07 22:33:56.729  7956  7956 F DEBUG   : Build fingerprint: 'google/bluejay/bluejay:16/BP4A.251205.006/14401865:user/release-keys'
01-07 22:33:56.729  7956  7956 F DEBUG   : Kernel Release: '6.1.145-android14-11-gc1de4747ac59-ab14219743'
01-07 22:33:56.729  7956  7956 F DEBUG   : Revision: 'MP1.0'
01-07 22:33:56.729  7956  7956 F DEBUG   : ABI: 'arm64'
01-07 22:33:56.729  7956  7956 F DEBUG   : Timestamp: 2026-01-07 22:33:55.686892499+0100
01-07 22:33:56.729  7956  7956 F DEBUG   : Process uptime: 95s
01-07 22:33:56.729  7956  7956 F DEBUG   : Executable: /system/bin/app_process64
01-07 22:33:56.729  7956  7956 F DEBUG   : Cmdline: system_server
01-07 22:33:56.729  7956  7956 F DEBUG   : pid: 2082, tid: 2099, name: binder:2082_1  >>> system_server <<<
01-07 22:33:56.730  7956  7956 F DEBUG   : uid: 1000
01-07 22:33:56.730  7956  7956 F DEBUG   : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
01-07 22:33:56.730  7956  7956 F DEBUG   : esr: 0000000092000006 (Data Abort Exception 0x24)
01-07 22:33:56.730  7956  7956 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000018 (read)
01-07 22:33:56.730  7956  7956 F DEBUG   : Cause: null pointer dereference
01-07 22:33:56.730  7956  7956 F DEBUG   :     x0  0000007117bf6528  x1  0000000000000001  x2  00000071b9348fe8  x3  0000007117bf6264
01-07 22:33:56.730  7956  7956 F DEBUG   :     x4  0000007117bf6750  x5  0000000000000004  x6  0000000000000044  x7  0000007117bf6448
01-07 22:33:56.730  7956  7956 F DEBUG   :     x8  00000000ffffffff  x9  0000007117bf8740  x10 00000071b8d99fc0  x11 00000000ffffffff
01-07 22:33:56.730  7956  7956 F DEBUG   :     x12 0000000000000000  x13 0000000000000018  x14 0000000000000010  x15 0000007451422010
01-07 22:33:56.730  7956  7956 F DEBUG   :     x16 00000071b916a8d0  x17 00000071b896946c  x18 0000000000000000  x19 00000000712fd7e0
01-07 22:33:56.730  7956  7956 F DEBUG   :     x20 0000000000000000  x21 00000000712fd7dc  x22 0000007117bfb640  x23 0000000070aec030
01-07 22:33:56.730  7956  7956 F DEBUG   :     x24 b4000071fe818ef0  x25 0000007117bf65b8  x26 b40000725e8112f0  x27 fffffffffffffffe
01-07 22:33:56.730  7956  7956 F DEBUG   :     x28 00000071b9349000  x29 0000007117bf5fd0
01-07 22:33:56.730  7956  7956 F DEBUG   :     lr  00000071b89693d0  sp  0000007117bf5bd0  pc  00000071b8969510  pst 0000000060001000
01-07 22:33:56.730  7956  7956 F DEBUG   :     esr 0000000092000006
01-07 22:33:56.730  7956  7956 F DEBUG   : 14 total frames
01-07 22:33:56.730  7956  7956 F DEBUG   : backtrace:
01-07 22:33:56.730  7956  7956 F DEBUG   :       #00 pc 000000000022e510  /apex/com.android.art/lib64/libart.so (art::StackVisitor::GetDexPc(bool) const+164) (BuildId: 6cac8d43981d3cdaec56bfd359a7c85c)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #01 pc 000000000022e3cc  /apex/com.android.art/lib64/libart.so (art::Thread::GetCurrentMethod(unsigned int*, bool, bool) const::$_0::operator()(art::StackVisitor const*) const (.__uniq.112444171608964125319761912539055931073)+112) (BuildId: 6cac8d43981d3cdaec56bfd359a7c85c)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #02 pc 00000000003538c4  /apex/com.android.art/lib64/libart.so (void art::StackVisitor::WalkStack<(art::StackVisitor::CountTransitions)0>(bool)+1316) (BuildId: 6cac8d43981d3cdaec56bfd359a7c85c)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #03 pc 00000000002c9134  /apex/com.android.art/lib64/libart.so (art::Thread::ThrowNewWrappedException(char const*, char const*)+564) (BuildId: 6cac8d43981d3cdaec56bfd359a7c85c)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #04 pc 000000000027d050  /apex/com.android.art/lib64/libart.so (art::Thread::ThrowNewExceptionF(char const*, char const*, ...)+196) (BuildId: 6cac8d43981d3cdaec56bfd359a7c85c)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #05 pc 000000000027c700  /apex/com.android.art/lib64/libart.so (art::FindFieldJNI(art::ScopedObjectAccess const&, _jclass*, char const*, char const*, bool, void*)+1860) (BuildId: 6cac8d43981d3cdaec56bfd359a7c85c)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #06 pc 0000000000637574  /apex/com.android.art/lib64/libart.so (art::JNI<false>::GetFieldID(_JNIEnv*, _jclass*, char const*, char const*)+200) (BuildId: 6cac8d43981d3cdaec56bfd359a7c85c)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #07 pc 0000000000a9e45c  /memfd:frida-agent-64.so (deleted)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #08 pc 0000000000a9debc  /memfd:frida-agent-64.so (deleted)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #09 pc 00000000009bbca0  /memfd:frida-agent-64.so (deleted)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #10 pc 0000000000bacd34  /memfd:frida-agent-64.so (deleted)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #11 pc 0000000000bacbe8  /memfd:frida-agent-64.so (deleted)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #12 pc 0000000000bacad0  /memfd:frida-agent-64.so (deleted)
01-07 22:33:56.730  7956  7956 F DEBUG   :       #13 pc 0000000000cf2c68  /memfd:frida-agent-64.so (deleted)

@ExternalAddress4401
Copy link

I tried a quick gadget compile and it didn't work either but I can't be certain I did it right as I rushed through it before work. Just giving a second data point until I can try again later.

@hoo-dles
Copy link

hoo-dles commented Jan 7, 2026

Pixel 6a crashes on start of frida-server (like shows the Google loading splash and restarts the entire launcher). First time compiling from sources, so take it with a grain a salt. I smoke tested what was on origin/main and got the expected Unable to find copied methods ... error message.

Not sure how the bridge is typically included in the build process (looks like just an npm package). npm link didn't seem to include the changes on rebuild, so I just copied the modified sources from the PR branch to where I found them at build/subprojects/frida-core/src/linux/agent/system-server/system-server.js.p/node_modules/frida-java-bridge.

This feels wrong, so if someone wants to correct my build process, I'm happy to test again.

@ExternalAddress4401
Copy link

ExternalAddress4401 commented Jan 7, 2026

Pixel 6a crashes on start of frida-server (like shows the Google loading splash and restarts the entire launcher). First time compiling from sources, so take it with a grain a salt. I smoke tested what was on origin/main and got the expected Unable to find copied methods ... error message.

Not sure how the bridge is typically included in the build process (looks like just an npm package). npm link didn't seem to include the changes on rebuild, so I just copied the modified sources from the PR branch to where I found them at build/subprojects/frida-core/src/linux/agent/system-server/system-server.js.p/node_modules/frida-java-bridge.

This feels wrong, so if someone wants to correct my build process, I'm happy to test again.

Fairly close to what I do. If you're not getting Unable to find copied methods ... then you've clearly done some changes.

I linked build/subprojects/frida-core/src/linux/agent/system-server/system-server.js.p/whatever else nests here/node_modules/frida-java-bridge to my bridge and then I make the changes in my copy. I follow that with node build.js inside the system-server.js.p folder and copy the new system-server.js to the directory above otherwise make doesn't want to build.

@hoo-dles
Copy link

hoo-dles commented Jan 8, 2026

Fairly close to what I do. If you're not getting Unable to find copied methods ... then you've clearly done some changes.

I linked build/subprojects/frida-core/src/linux/agent/system-server/system-server.js.p/whatever else nests here/node_modules/frida-java-bridge to my bridge and then I make the changes in my copy. I follow that with node build.js inside the system-server.js.p folder and copy the new system-server.js to the directory above otherwise make doesn't want to build.

Sanity checked by following your process of symlink and explicit build+copy of system-server.js with the same crash as before.

@AeonLucid
Copy link
Contributor

@hoo-dles I don't have the code at hand, but the build process copies the javascript sources and package.json, and then runs npm install elsewhere. There is a python script that builds this system server.

Under the npm install you can add a new line for npm link, that way it will always build with your package.

@hoo-dles
Copy link

hoo-dles commented Jan 8, 2026

@hoo-dles I don't have the code at hand, but the build process copies the javascript sources and package.json, and then runs npm install elsewhere. There is a python script that builds this system server.

Under the npm install you can add a new line for npm link, that way it will always build with your package.

hmmm, I tried npm link initially, but maybe I was in the wrong place.

@AeonLucid
Copy link
Contributor

@hoo-dles I don't have the code at hand, but the build process copies the javascript sources and package.json, and then runs npm install elsewhere. There is a python script that builds this system server.

Under the npm install you can add a new line for npm link, that way it will always build with your package.

hmmm, I tried npm link initially, but maybe I was in the wrong place.

You need to modify the python script I mentioned so that it runs npm link for you during the build process.

@thinhbuzz
Copy link
Contributor

thinhbuzz commented Jan 8, 2026

@AeonLucid @hoo-dles @ExternalAddress4401
I use verdaccio for customizing frida-java-bridge. You can refer to this guide I wrote.
https://gist.github.com/thinhbuzz/13bb8753821fd80c5dd53c22a63e0a39

You can test with Frida's latest SELinux update by following these guide:
https://gist.github.com/thinhbuzz/97ab9230d733098a0c1bf2932698b970

@thinhbuzz
Copy link
Contributor

I have tested it on the Pixel 6 Pro with Android 16 ROM version 16.0.0 (BP4A.251205.006, Dec 2025), and it is functional but lacks stability. However, using method.implementation = function may randomly cause the application to crash.

@hoo-dles
Copy link

hoo-dles commented Jan 8, 2026

Used verdaccio just to remove another variable even though I already suspected the results would be the same.

rooted Pixel 6a, Android 16 (BP3A.250905.014, Play Nov 1, 2025)

Edit: Adding my crash log for posterity

01-08 10:26:04.278 29024 10828 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10 in tid 10828 (Thread-170), pid 29024 (system_server)
01-08 10:26:05.271 10851 10851 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-08 10:26:05.271 10851 10851 F DEBUG   : Build fingerprint: 'google/bluejay/bluejay:16/BP3A.250905.014/13873947:user/release-keys'
01-08 10:26:05.271 10851 10851 F DEBUG   : Kernel Release: '6.1.134-android14-11-g66e758f7d0c0-ab13748739'
01-08 10:26:05.271 10851 10851 F DEBUG   : Revision: 'MP1.0'
01-08 10:26:05.271 10851 10851 F DEBUG   : ABI: 'arm64'
01-08 10:26:05.271 10851 10851 F DEBUG   : Timestamp: 2026-01-08 10:26:04.593423116-0800
01-08 10:26:05.271 10851 10851 F DEBUG   : Process uptime: 50073s
01-08 10:26:05.271 10851 10851 F DEBUG   : Executable: /system/bin/app_process64
01-08 10:26:05.271 10851 10851 F DEBUG   : Cmdline: system_server
01-08 10:26:05.271 10851 10851 F DEBUG   : pid: 29024, tid: 10828, name: Thread-170  >>> system_server <<<
01-08 10:26:05.271 10851 10851 F DEBUG   : uid: 1000
01-08 10:26:05.271 10851 10851 F DEBUG   : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
01-08 10:26:05.271 10851 10851 F DEBUG   : esr: 0000000092000006 (Data Abort Exception 0x24)
01-08 10:26:05.271 10851 10851 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000010 (read)
01-08 10:26:05.271 10851 10851 F DEBUG   : Cause: null pointer dereference
01-08 10:26:05.271 10851 10851 F DEBUG   :     x0  0000000000000001  x1  00000078b7b4b85e  x2  6c6961460044005a  x3  6e69206f74206465
01-08 10:26:05.271 10851 10851 F DEBUG   :     x4  0000000000000001  x5  0000000000000000  x6  6d681f6e731f6364  x7  7f7f7f7f7f7f7f7f
01-08 10:26:05.271 10851 10851 F DEBUG   :     x8  000000006fb58960  x9  0000000000000000  x10 0000000000000000  x11 0000007720a3c6f0
01-08 10:26:05.271 10851 10851 F DEBUG   :     x12 000000000000000a  x13 0000007b564ce1a8  x14 0000000000000020  x15 000000788fead010
01-08 10:26:05.271 10851 10851 F DEBUG   :     x16 00000078b85065b8  x17 0000007b5b2c89c0  x18 0000000000000000  x19 0000000000000001
01-08 10:26:05.271 10851 10851 F DEBUG   :     x20 00000000000000b4  x21 0000000000000000  x22 000000782222ad00  x23 000000006f26e660
01-08 10:26:05.271 10851 10851 F DEBUG   :     x24 0000000000000000  x25 0000007720a3e880  x26 000000006f1fe370  x27 0000000000000000
01-08 10:26:05.271 10851 10851 F DEBUG   :     x28 0000007720a3c720  x29 0000007720a3c6b0
01-08 10:26:05.271 10851 10851 F DEBUG   :     lr  00000078b7d541e0  sp  0000007720a3c4a0  pc  00000078b7d5421c  pst 0000000000001000
01-08 10:26:05.271 10851 10851 F DEBUG   :     esr 0000000092000006
01-08 10:26:05.271 10851 10851 F DEBUG   : 9 total frames
01-08 10:26:05.271 10851 10851 F DEBUG   : backtrace:
01-08 10:26:05.271 10851 10851 F DEBUG   :       #00 pc 000000000027c21c  /apex/com.android.art/lib64/libart.so (art::FindFieldJNI(art::ScopedObjectAccess const&, _jclass*, char const*, char const*, bool, void*)+608) (BuildId: be34fbe63ff357beb403f9cb39923ea7)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #01 pc 0000000000637678  /apex/com.android.art/lib64/libart.so (art::JNI<false>::GetFieldID(_JNIEnv*, _jclass*, char const*, char const*)+200) (BuildId: be34fbe63ff357beb403f9cb39923ea7)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #02 pc 0000000000a9d93c  /memfd:frida-agent-64.so (deleted)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #03 pc 0000000000a9d3a0  /memfd:frida-agent-64.so (deleted)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #04 pc 00000000009bbce0  /memfd:frida-agent-64.so (deleted)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #05 pc 0000000000bac214  /memfd:frida-agent-64.so (deleted)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #06 pc 0000000000bac0c8  /memfd:frida-agent-64.so (deleted)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #07 pc 0000000000babfb0  /memfd:frida-agent-64.so (deleted)
01-08 10:26:05.271 10851 10851 F DEBUG   :       #08 pc 0000000000cf2c68  /memfd:frida-agent-64.so (deleted)

@oleavr
Copy link
Member Author

oleavr commented Jan 8, 2026

The crash seems to be the long-standing ART bug where it assumes there is a Java stack frame present on the art::Thread's stack. This bug is in the exception-handling code. The way we ensure that a class is initialized is by performing a dummy field lookup, expected to fail. However, since ART's exception handling has this broken assumption, it ends up crashing the process. The existing workaround no longer works, and either we have to update it, or find a way to make our Java.perform() / Java.performNow() call some Java method that calls us back, so our code interacting with the VM satisfies this assumption.

SecKatie added a commit to SecKatie/frida-java-bridge that referenced this pull request Jan 9, 2026
This commit adds support for Android 16+ which has several breaking changes
in ART internals:

1. Skip JVMTI loading on API 36+ - Loading the JVMTI plugin causes system
   instability on these Android versions.

2. Skip ensureClassInitialized GetFieldID trick on API 36+ - This crashes
   due to an ART bug in exception handling when there's no Java stack frame.

3. Handle missing copied_methods_offset_ field - Android 16 removed the
   copied_methods_offset_ field from the ART Class structure. We now return 0
   to signal this and use the array length from the methods array header instead.

4. Force Java reflection path on API 36+ - The ART class/method structures
   have changed in ways that cause incorrect method modifier detection.
   Using Java reflection via Method.getModifiers() gives correct results.

Fixes frida#378

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hoo-dles
Copy link

hoo-dles commented Jan 10, 2026

Not sure if this is a valid approach, but I'm trying to force class initialization by calling Class.ForName() (which has an explicit initialize param) via JNI's CallStaticObjectMethodA. Looks like it goes through a handful of classes and then hangs on android.app.ActivityManager or java.lang.Object (neither print output, but doesn't crash either).

edit: I assume a deadlock, but I'm out here at the edge of my knowledge concerning the JNI and ART

@AeonLucid
Copy link
Contributor

AeonLucid commented Jan 11, 2026

On atleast Android 9 and 10, this PR breaks frida-java-bridge.
On 15 and above it works good together with #379.

import Java from "frida-java-bridge";

console.log("Agent loaded");

if (Java.available) {
    Java.perform(() => {
        send({
            type: "status",
            message: "Application class-loader now available"
        });
    });
} else {
    console.log("No Java VM in this process");
}

Output

Agent loaded
Error: expected a pointer
    at <anonymous> (/agent/index.js:1874)
    at forEach (native)
    at dd (/agent/index.js:1874)
    at ko (/agent/index.js:1874)
    at build (/agent/index.js:1874)
    at _make (/agent/index.js:1875)
    at use (/agent/index.js:1875)
    at <anonymous> (/agent/index.js:1884)
    at <anonymous> (/agent/index.js:1)
    at _performPendingVmOpsWhenReady (/agent/index.js:1884)
    at perform (/agent/index.js:1884)
    at <anonymous> (/agent/index.js:1884)

It's a bit difficult to find the error line due to the frida-compile output.

@hoo-dles
Copy link

On atleast Android 9 and 10, this PR breaks frida-java-bridge. On 15 and above it works good together with #379.
[...]

My guess is it barfs at compileModule(env) in class-model.js because jvmti isn't available:

let j = javaApi;
  [
    jvmti,
    getDeclaredMethods, getDeclaredFields,
    method.getName, method.getModifiers,
    field.getName, field.getModifiers
  ]
    .forEach(value => {
      j = j.writePointer(value).add(pointerSize);
    });

I would try throwing in a quick null-check or something there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants