Skip to content

Conversation

@Mansive
Copy link
Collaborator

@Mansive Mansive commented Dec 28, 2025

Leaving this here for anyone smarter than me. This is my attempt to hook Eden on the NCE backend. It has a million problems, and I've only gotten it properly working with one game (Taishou x Alice).

  1. frida-server and frida-gadget will cause the game to launch with a black screen and zero framerate with the following repeated indefinitely in Eden's logs:
    [  83.853289] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x281300004000
    [  83.853367] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x50000
    [  83.853384] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x724c416000
    [  83.853388] Core.ARM <Warning> core/hle/kernel/physical_core.cpp:RunThread:112: vtable bouncing B40000724C416100
    [  83.853411] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x724c416000
    [  83.853416] Core.ARM <Warning> core/hle/kernel/physical_core.cpp:RunThread:112: vtable bouncing B40000724C416100
    
    • frida-gum needs to be compiled without SIGSEGV and SIGBUS signal handling because NCE needs them:
        const gint handled_signals[] = {
          SIGABRT,
          // SIGSEGV,
          // SIGBUS,
          SIGILL,
          SIGFPE,
          SIGTRAP,
          SIGSYS,
        };
      
    • Used this to automatically put frida-gadget into the Eden APK. This method doesn’t require a rooted device.
  2. Because of the nature of Native Code Execution, the instructions being executed by the emulator are almost exactly the same as in the game's binary. This means you can:
    1. Open up the dumped main file in Ghidra, jump to the guest address (e.g. 0x81f96bfc assuming the base address is 0x80004000)
    2. Copy the instruction bytes
    3. Use them in Memory.scanSync() without any wildcards to find its current address on the host (e.g. 0x1a2a304bfc) in the emulator.
  3. While it's easy to find the host address on Dynarmic using the codeAddress from CreateProcessParameter, for some reason on NCE each game has a unique offset that needs to be applied to codeAddress. Double check the calculated address with the address obtained from number 2 above. I have no idea where these offsets come from.
    • Taishou x Alice and Summer Pockets REFLECTION BLUE both have an offset of 0x6000
    • Wand of Fortune R has an offset of 0x4000
  4. It's risky to use Frida's Interceptor.attach(), because for some reason it needs a whopping 16 bytes for the hook. Because each instruction is 4 bytes long, that's 4 instructions converted for the hook, which will cause a crash if the emulator jumps to one of the latter 3 converted instructions. The PR uses a UDF instruction for an exception hook because it only uses 4 bytes.
  5. Taishou x Alice is one of the three games I've tested that work fine with the NCE hooks. The other two, Summer Pockets, and Wand of Fortune, have a high chance of freezing when their hooks are triggered for the first time. They seem kind of stable if they survive the first trigger. This problem is probably the most important one that needs to be fixed. Eden's logs will spam this during the freeze:
    [  38.611268] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x2a2f304000
    [  38.611297] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x2a2f304000
    [  38.611304] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x2a2f304000
    [  38.611310] HW.Memory <Error> core/memory.cpp:operator():1094: Unmapped InvalidateNCE for 4096 bytes @ 0x2a2f304000
    
  6. Can't attach hooks too early because the emulator might not have finished setting up all the instructions for NCE.

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.

1 participant