mirror of
https://github.com/aydencharles/onionHEN.git
synced 2026-10-22 20:02:59 -05:00
Align docs and README with OrionHEN runtime paths, config keys, and payload naming while keeping upstream etaHEN heritage credits.
3.4 KiB
3.4 KiB
ShellUI injection flow & kylin-core libNineS fixes
Call path (OrionHEN)
daemon: cmd_enable_toolbox() [daemon/source/msg.cpp]
├─ get_shellui_pid() // find SceShellUI
└─ Inject_Toolbox(pid, shellui.elf) [libNineS/src/main.c]
└─ inject_elf(proc, elf) [libNineS/src/injector.c]
├─ elevate authid once (debugger / ptrace)
├─ pt_attach(SceShellUI)
├─ init_remote_function_pointers() // malloc, pthread_create, …
├─ elfldr_load() // map ELF into target
├─ elfldr_payload_args()
├─ mmap bootstrap stager + copyin
├─ mmap SCEFunctions blob + copyin
├─ pt_call2(bootstrap) → remote pthread_create(elf_main)
│ stager ends with int3
└─ pt_detach + restore authid
ShellUI payload then signals readiness via /system_tmp/toolbox_online (daemon waits up to ~15s).
kylin-core uses the same inject_elf() path for ShellUI overlay injection (overlay_service.c → inject_elf), plus higher-level retries / kill-respawn / boot-id skip that live outside libNineS.
Inconsistencies found (OrionHEN vs kylin-core)
| Area | OrionHEN (before) | kylin-core | Risk |
|---|---|---|---|
sys_ptrace |
Flip authid to debugger on every ptrace call, then restore | Direct syscall(SYS_ptrace) |
Thread-unsafe race between concurrent ptrace ops; can SIGSEGV daemon or corrupt authid |
pt_call2 |
pt_continue then immediately pt_setregs(bak) |
pt_continue → waitpid → then restore regs |
Critical race: restores ShellUI registers while bootstrap still runs → crash / freeze / power loss |
inject_elf authid |
set_ucred_to_debugger() with no restore |
Backup original authid → elevate → restore on all exits | Daemon stuck elevated; failed inject leaves bad state |
| Error paths | Often leave status=true on load/mmap failure |
Set status=false on each failure |
Caller thinks inject succeeded |
MAP_FAILED |
Only checks !bootstrap |
Also rejects (uint64_t)-1 |
mmap failure treated as success addr |
| mprotect / copyin | Unchecked | Checked, fail inject | Partial maps then trigger entry |
attached flag |
Not cleared after detach | Cleared when detach succeeds | Stale attach state on retry |
Fixes adopted in OrionHEN
Ported into source/libNineS/src/pt.c and source/libNineS/src/injector.c (without kylin-specific logger; uses ps5/klog).
- Scoped debugger authid at
inject_elfentry/exit only - No per-ptrace authid flip in
sys_ptrace waitpidafter stagerpt_continueinpt_call2- Strict validation of null args, entry/args, mmap, mprotect, copyin
- Clear
attachedon successful detach; always try authid restore
Not ported (higher-level kylin-core only)
These live in kylin-core/src/services/overlay_service.c, not libNineS:
- Injection file lock (
/system_tmp/...) - Boot-time “already injected” record / skip
- Multi-attempt inject + kill ShellUI + wait for respawn
Optional follow-up for OrionHEN daemon: add similar retry/respawn around cmd_enable_toolbox() if field failure rate stays high.
Upstream files for reference
kylin-core/third_party/libNineS/src/pt.ckylin-core/third_party/libNineS/src/injector.ckylin-core/src/services/overlay_service.c