From 0bcb6ff53b90943cd06cb062b956d65459867b51 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Fri, 24 Apr 2026 19:19:27 -0700 Subject: [PATCH 01/10] Add trampoline preamble with red zone reservation and R11 restart address The syscall rewriter now emits a 12-byte preamble before each trampoline stub: LEA RSP,[RSP-0x80] to reserve the SysV 128-byte red zone, and LEA R11,[RIP+disp32] to load the call-site restart address into R11 for future SA_RESTART support. Platform callbacks are renamed to syscall_callback_redzone to reflect the new calling convention. The callback recovers the architectural RSP with LEA R11,[RSP+128] and saves the restart address to TLS (saved_restart_addr) before clobbering R11. The rewriter also emits a size=0 header sentinel for binaries with no syscall instructions, allowing the loader to distinguish 'checked, no syscalls' from 'never processed.' The is_already_hooked check treats size=0 as already-hooked. The rtld_audit library is updated to handle both the new calling convention (red zone + R11) and size=0 binaries (via mincore probe before reading trampoline memory). --- litebox_common_linux/src/loader.rs | 5 +- litebox_platform_linux_userland/src/lib.rs | 39 +++- litebox_platform_windows_userland/src/lib.rs | 46 +++- litebox_rtld_audit/rtld_audit.c | 35 ++- litebox_syscall_rewriter/src/lib.rs | 75 +++++- .../snapshots/snapshot_tests__hello-diff.snap | 217 +++++++++--------- 6 files changed, 277 insertions(+), 140 deletions(-) diff --git a/litebox_common_linux/src/loader.rs b/litebox_common_linux/src/loader.rs index 243c8bfdc..59e1c537a 100644 --- a/litebox_common_linux/src/loader.rs +++ b/litebox_common_linux/src/loader.rs @@ -291,9 +291,10 @@ impl ElfParsedFile { ) }; - // Validate trampoline size + // Size=0 sentinel: "checked by rewriter, no syscalls to patch." + // Treat the same as "no trampoline found." if trampoline_size == 0 { - return Err(ElfParseError::BadTrampoline); + return Ok(()); } // Verify the file offset is page-aligned (as required by the rewriter) diff --git a/litebox_platform_linux_userland/src/lib.rs b/litebox_platform_linux_userland/src/lib.rs index a1ccf7fdc..8587861ef 100644 --- a/litebox_platform_linux_userland/src/lib.rs +++ b/litebox_platform_linux_userland/src/lib.rs @@ -508,6 +508,8 @@ core::arch::global_asm!( " .section .tbss .align 8 +saved_restart_addr: + .quad 0 scratch: .quad 0 host_sp: @@ -563,7 +565,7 @@ fn get_guest_fsbase() -> usize { /// /// This saves all non-volatile register state then switches to the guest /// context. When the guest makes a syscall, it jumps back into the middle of -/// this routine, at `syscall_callback`. This code then updates the guest +/// this routine, at the syscall callback. This code then updates the guest /// context structure, switches back to the host stack, and calls the syscall /// handler. /// @@ -616,22 +618,34 @@ unsafe extern "C-unwind" fn run_thread_arch( // At entry, the register context is the guest context with the // return address in rcx. r11 is an available scratch register (it would // contain rflags if the syscall instruction had actually been issued). - .globl syscall_callback -syscall_callback: + .globl syscall_callback_redzone +syscall_callback_redzone: + // the trampoline has already reserved 128 bytes below RSP to protect the + // SysV red zone. // Clear in_guest flag. This must be the first instruction to match the // expectations of `interrupt_signal_handler`. mov BYTE PTR gs:in_guest@tpoff, 0 + // Save guest R11 (syscall call-site restart address from the rewriter + // trampoline) to TLS before it is clobbered by the fsbase/gsbase save + // sequence below. This value is not placed in pt_regs (which holds + // RFLAGS in the r11 slot per the kernel ABI); instead it is kept in + // TLS for future SA_RESTART support. + mov gs:saved_restart_addr@tpoff, r11 + // Restore host fs base. rdfsbase r11 mov gs:guest_fsbase@tpoff, r11 rdgsbase r11 wrfsbase r11 - // Switch to the top of the guest context. - mov r11, rsp + // The trampoline lowered RSP by 128 bytes with LEA, so recover the + // architectural guest stack pointer before saving pt_regs. + lea r11, [rsp + 128] mov rsp, fs:guest_context_top@tpoff +.Lsyscall_save_regs: + // TODO: save float and vector registers (xsave or fxsave) // Save caller-saved registers push 0x2b // pt_regs->ss = __USER_DS @@ -649,7 +663,7 @@ syscall_callback: push r8 // pt_regs->r8 push r9 // pt_regs->r9 push r10 // pt_regs->r10 - push [rsp + 88] // pt_regs->r11 = rflags + push [rsp + 88] // pt_regs->r11 = rflags (matching real syscall ABI) push rbx // pt_regs->bx push rbp // pt_regs->bp push r12 // pt_regs->r12 @@ -811,7 +825,7 @@ fn thread_start( let shim = init_thread.init(); run_thread_inner(shim.as_ref(), &mut ctx, false); - // TODO: have syscall_callback return if we need to terminate the process. + // TODO: have the syscall callback return if we need to terminate the process. // We should return this value to the caller so load_program can return it // to the user. } @@ -1584,7 +1598,8 @@ impl litebox::platform::StdioProvider for LinuxUserland { unsafe extern "C" { // Defined in asm blocks above - fn syscall_callback() -> isize; + #[cfg(target_arch = "x86_64")] + fn syscall_callback_redzone() -> isize; fn exception_callback(); fn interrupt_callback(); fn switch_to_guest_start(); @@ -1665,7 +1680,10 @@ impl ThreadContext<'_> { impl litebox::platform::SystemInfoProvider for LinuxUserland { fn get_syscall_entry_point(&self) -> usize { - syscall_callback as *const () as usize + #[cfg(target_arch = "x86_64")] + { + syscall_callback_redzone as *const () as usize + } } fn get_vdso_address(&self) -> Option { @@ -2186,7 +2204,8 @@ unsafe fn interrupt_signal_handler( // FUTURE: handle trampoline code, too. This is somewhat less important // because it's probably fine for the shim to observe a guest context that // is inside the trampoline. - if ip == syscall_callback as *const () as usize { + #[cfg(target_arch = "x86_64")] + if ip == syscall_callback_redzone as *const () as usize { // No need to clear `in_guest` or set interrupt; the syscall handler will // clear `in_guest` and call into the shim. return; diff --git a/litebox_platform_windows_userland/src/lib.rs b/litebox_platform_windows_userland/src/lib.rs index 396282544..a6b04257d 100644 --- a/litebox_platform_windows_userland/src/lib.rs +++ b/litebox_platform_windows_userland/src/lib.rs @@ -414,6 +414,10 @@ struct TlsState { host_bp: Cell<*mut u128>, guest_context_top: Cell<*mut litebox_common_linux::PtRegs>, scratch: Cell, + /// Syscall call-site restart address from the rewriter trampoline, + /// saved here for future SA_RESTART support. Not stored in pt_regs + /// (which holds RFLAGS in the r11 slot per the kernel ABI). + saved_restart_addr: Cell, is_in_guest: Cell, interrupt: Cell, continue_context: @@ -433,6 +437,7 @@ impl TlsState { host_bp: Cell::new(core::ptr::null_mut()), guest_context_top: core::ptr::null_mut::().into(), scratch: 0.into(), + saved_restart_addr: 0.into(), is_in_guest: false.into(), interrupt: false.into(), continue_context: Box::default(), @@ -480,7 +485,7 @@ fn get_tls_ptr() -> Option<*const TlsState> { /// /// This saves all non-volatile register state then switches to the guest /// context. When the guest makes a syscall, it jumps back into the middle of -/// this routine, at `syscall_callback`. This code then updates the guest +/// this routine, at the syscall callback. This code then updates the guest /// context structure, switches back to the host stack, and calls the syscall /// handler. /// @@ -549,19 +554,37 @@ unsafe extern "C-unwind" fn run_thread_arch(thread_ctx: &mut ThreadContext, tls_ jmp .Ldone // This entry point is called from the guest when it issues a syscall - // instruction. + // instruction. The rewriter trampoline has already: + // 1. Reserved 128 bytes below RSP to protect the SysV red zone + // 2. Loaded the call-site restart address into R11 (for SA_RESTART) + // 3. Loaded the return address into RCX // - // At entry, the register context is the guest context with the - // return address in rcx. r11 is an available scratch register (it would - // contain rflags if the syscall instruction had actually been issued). - .globl syscall_callback -syscall_callback: + // All other registers hold guest state. + .globl syscall_callback_redzone +syscall_callback_redzone: + // Save guest R11 (restart address from rewriter trampoline) to + // TEB.ArbitraryUserPointer (gs:[0x28]) before the TLS index lookup + // clobbers R11. This slot is per-thread and the window is very + // narrow: only ~20 instructions of inline asm with no API calls, + // no Rust code, and no DLL activity, so the ntdll loader (which + // also uses this slot for debugger communication) cannot interfere. + mov gs:[0x28], r11 // Get the TLS state from the TLS slot and clear the in-guest flag. mov r11d, DWORD PTR [rip + {TLS_INDEX}] mov r11, QWORD PTR gs:[r11 * 8 + TEB_TLS_SLOTS_OFFSET] mov BYTE PTR [r11 + {IS_IN_GUEST}], 0 - // Set rsp to the top of the guest context. + // Recover the restart address from the TEB slot and store it in TLS. + // We use SCRATCH as a temporary since all guest GPRs must be preserved + // and RSP modifications would break the stack pointer recovery below. + push QWORD PTR gs:[0x28] + pop QWORD PTR [r11 + {SAVED_RESTART_ADDR}] + // Recover the architectural guest stack pointer (undo the 128-byte + // red zone reservation) and store it in SCRATCH. LEA is used instead + // of ADD to avoid clobbering RFLAGS before pushfq. + lea rsp, [rsp + 128] mov QWORD PTR [r11 + {SCRATCH}], rsp + +.Lsyscall_callback_common: mov rsp, QWORD PTR [r11 + {GUEST_CONTEXT_TOP}] // TODO: save float and vector registers (xsave or fxsave) @@ -581,7 +604,7 @@ syscall_callback: push r8 // pt_regs->r8 push r9 // pt_regs->r9 push r10 // pt_regs->r10 - push [rsp + 88] // pt_regs->r11 = rflags + push [rsp + 88] // pt_regs->r11 = rflags (matching real syscall ABI) push rbx // pt_regs->bx push rbp // pt_regs->bp push r12 @@ -646,6 +669,7 @@ interrupt_callback: HOST_BP = const core::mem::offset_of!(TlsState, host_bp), GUEST_CONTEXT_TOP = const core::mem::offset_of!(TlsState, guest_context_top), SCRATCH = const core::mem::offset_of!(TlsState, scratch), + SAVED_RESTART_ADDR = const core::mem::offset_of!(TlsState, saved_restart_addr), IS_IN_GUEST = const core::mem::offset_of!(TlsState, is_in_guest), ); } @@ -1938,7 +1962,7 @@ impl litebox::mm::allocator::MemoryProvider for WindowsUserland { unsafe extern "C" { // Defined in asm blocks above - fn syscall_callback() -> isize; + fn syscall_callback_redzone() -> isize; fn exception_callback() -> isize; fn interrupt_callback(); fn switch_to_guest_start(); @@ -2028,7 +2052,7 @@ impl ThreadContext<'_> { impl litebox::platform::SystemInfoProvider for WindowsUserland { fn get_syscall_entry_point(&self) -> usize { - syscall_callback as *const () as usize + syscall_callback_redzone as *const () as usize } fn get_vdso_address(&self) -> Option { diff --git a/litebox_rtld_audit/rtld_audit.c b/litebox_rtld_audit/rtld_audit.c index 51713f941..7bec7e9ee 100644 --- a/litebox_rtld_audit/rtld_audit.c +++ b/litebox_rtld_audit/rtld_audit.c @@ -69,7 +69,9 @@ static long do_syscall(long num, long a1, long a2, long a3, long a4, long a5, register long r8 __asm__("r8") = a5; register long r9 __asm__("r9") = a6; - __asm__ volatile("leaq 1f(%%rip), %%rcx\n" + __asm__ volatile("leaq -128(%%rsp), %%rsp\n" // reserve red zone + "leaq 1f(%%rip), %%r11\n" // R11 = restart addr (call-site) + "leaq 1f(%%rip), %%rcx\n" // RCX = return addr "jmp *%[entry]\n" "1:\n" : "+r"(rax) @@ -177,6 +179,25 @@ void print_hex(uint64_t data) { /// The trampoline is already mapped by the litebox loader at (base + vaddr). /// The entry point is at offset 0 of the mapped trampoline. The litebox loader /// already validated the magic when parsing the file header. +/// +/// For binaries processed by the rewriter but containing no syscall instructions +/// (trampoline_size=0 sentinel), no trampoline pages are mapped. We detect this +/// by probing the expected address with `mincore` via a raw syscall. +static long raw_syscall3(long num, long a1, long a2, long a3) { + long ret; + register long r10 __asm__("r10") = 0; + register long r8 __asm__("r8") = 0; + register long r9 __asm__("r9") = 0; + __asm__ volatile("syscall" + : "=a"(ret) + : "0"(num), "D"(a1), "S"(a2), "d"(a3), + "r"(r10), "r"(r8), "r"(r9) + : "rcx", "r11", "memory"); + return ret; +} + +#define SYS_mincore 27 + int parse_object(const struct link_map *map) { unsigned long max_addr = 0; Elf64_Ehdr *eh = (Elf64_Ehdr *)map->l_addr; @@ -202,6 +223,15 @@ int parse_object(const struct link_map *map) { } max_addr = align_up(max_addr, 0x1000); void *trampoline_addr = (void *)map->l_addr + max_addr; + + // Check if the trampoline page is mapped. Binaries with no syscall + // instructions have a size=0 sentinel header and no trampoline pages. + unsigned char vec; + if (raw_syscall3(SYS_mincore, (long)trampoline_addr, 0x1000, (long)&vec) < 0) { + syscall_print("[audit] no trampoline page mapped\n", 34); + return 1; + } + // The trampoline code has the syscall entry point at offset 0. syscall_entry = (syscall_stub_t)read_u64(trampoline_addr); if (syscall_entry == 0) { @@ -324,9 +354,8 @@ unsigned int la_objopen(struct link_map *map, do_syscall(SYS_munmap, (long)header_page, 0x1000, 0, 0, 0, 0); syscall_print("[audit] found trampoline header at end of file\n", 47); - // Validate trampoline size + // Validate trampoline size (size=0 is a sentinel meaning "no syscalls to patch") if (tramp_size_raw == 0) { - syscall_print("[audit] trampoline code size invalid\n", 37); do_syscall(SYS_close, fd, 0, 0, 0, 0, 0); return 0; } diff --git a/litebox_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index e45437691..654ce8648 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -182,7 +182,9 @@ pub fn hook_syscalls_in_elf(input_binary: &[u8], trampoline: Option) -> Res let text_sections = match text_sections(&file) { Ok(sections) => sections, - Err(InternalError::NoTextSectionFound) => return Ok(input_binary.to_vec()), + Err(InternalError::NoTextSectionFound) => { + return Ok(input_binary.to_vec()); + } Err(InternalError::Public(e)) => return Err(e), Err(e) => unreachable!("unexpected internal error: {e:?}"), }; @@ -216,6 +218,7 @@ pub fn hook_syscalls_in_elf(input_binary: &[u8], trampoline: Option) -> Res } // Patch syscalls in-place in buf let mut skipped_addrs = Vec::new(); + let mut syscall_insns_found = false; for s in &text_sections { let section_data = section_slice_mut(buf, s)?; match hook_syscalls_in_section( @@ -228,13 +231,34 @@ pub fn hook_syscalls_in_elf(input_binary: &[u8], trampoline: Option) -> Res dl_sysinfo_int80, &mut trampoline_data, ) { - Ok(addrs) => skipped_addrs.extend(addrs), + Ok(addrs) => { + skipped_addrs.extend(addrs); + syscall_insns_found = true; + } Err(InternalError::NoSyscallInstructionsFound) => {} Err(InternalError::Public(e)) => return Err(e), Err(e) => unreachable!("unexpected internal error: {e:?}"), } } + if !syscall_insns_found { + // No syscall instructions found. Append a header-only marker so the + // loader can distinguish "checked by rewriter, nothing to patch" from + // "never processed." The trampoline_size=0 sentinel tells the loader + // to skip trampoline mapping entirely. + // Use the original input (not `buf`) to avoid emitting the phdr + // alignment fixup that was only needed for the `object` crate parser. + let mut out = input_binary.to_vec(); + let header = TrampolineHeader64 { + magic: *TRAMPOLINE_MAGIC, + file_offset: 0, + vaddr: 0, + trampoline_size: 0, + }; + out.extend_from_slice(header.as_bytes()); + return Ok(out); + } + // Build output: [patched ELF][padding to page boundary][trampoline code][header] let mut out = buf.to_vec(); let remain = out.len() % 0x1000; @@ -346,7 +370,8 @@ fn is_already_hooked(input_binary: &[u8], arch: Arch) -> bool { }; if trampoline_size == 0 { - return false; + // Size=0 sentinel: "checked by rewriter, no syscalls to patch." + return true; } if file_offset % 0x1000 != 0 { return false; @@ -475,6 +500,8 @@ fn hook_syscalls_in_section( let return_addr = inst.next_ip(); if arch == Arch::X86_64 { + emit_trampoline_preamble(trampoline_base_addr, replace_start, trampoline_data)?; + // Put jump back location into rcx. let jmp_back_base = checked_add_u64( trampoline_base_addr, @@ -616,8 +643,8 @@ fn fixup_phdr_alignment(buf: &mut [u8]) { return; }; - if old_end > buf.len() || new_end > buf.len() { - return; // corrupt phdr table or not enough room + if new_end > buf.len() { + return; // not enough room } // Only relocate when the overwritten bytes are padding. Otherwise this would corrupt the file @@ -714,6 +741,42 @@ fn checked_sub_u64(base: u64, subtrahend: u64, context: &'static str) -> Result< .ok_or_else(|| Error::AddressOverflow(format!("{context} address underflow"))) } +/// Emit the trampoline preamble: reserve the SysV red zone and load R11 with +/// the call-site restart address. +/// +/// The red zone reservation (`LEA RSP, [RSP - 0x80]`) prevents async guest +/// signal delivery / interrupt handling from clobbering stack locals parked +/// below the architectural RSP. +/// +/// R11 is loaded with `call_site_addr` (the address of the original JMP that +/// entered the trampoline) so that SA_RESTART can rewind `ctx.rip` to re-enter +/// the trampoline. The real `syscall` instruction clobbers R11 with RFLAGS, so +/// this register is free from the guest's perspective. +/// +/// CONTRACT: R11 carries the call-site restart address from this point until +/// the platform callback saves it to a dedicated TLS variable +/// (`saved_restart_addr`). The platform MUST preserve R11 before any clobbering +/// instructions (fsbase swap, TLS lookup). +fn emit_trampoline_preamble( + trampoline_base_addr: u64, + call_site_addr: u64, + trampoline_data: &mut Vec, +) -> Result<()> { + // LEA RSP, [RSP - 0x80] + trampoline_data.extend_from_slice(&[0x48, 0x8D, 0x64, 0x24, 0x80]); + + // LEA R11, [RIP + disp32] — disp32 targets call_site_addr + let r11_rip = checked_add_u64( + trampoline_base_addr, + trampoline_data.len() as u64 + 7, + "trampoline R11 displacement base", + )?; + let r11_disp = i64::try_from(call_site_addr).unwrap() - i64::try_from(r11_rip).unwrap(); + trampoline_data.extend_from_slice(&[0x4C, 0x8D, 0x1D]); + trampoline_data.extend_from_slice(&(i32::try_from(r11_disp).unwrap().to_le_bytes())); + Ok(()) +} + fn rel32_bytes(target: u64, base: u64, context: &'static str) -> Result<[u8; 4]> { let disp = i128::from(target) - i128::from(base); let disp = i32::try_from(disp).map_err(|_| { @@ -939,6 +1002,8 @@ fn hook_syscall_and_after( )?; if arch == Arch::X86_64 { + emit_trampoline_preamble(trampoline_base_addr, replace_start, trampoline_data)?; + // Put jump back location into rcx, via lea rcx, [next instruction] trampoline_data.extend_from_slice(&[0x48, 0x8D, 0x0D]); // LEA RCX, [RIP + disp32] trampoline_data.extend_from_slice(&6u32.to_le_bytes()); diff --git a/litebox_syscall_rewriter/tests/snapshots/snapshot_tests__hello-diff.snap b/litebox_syscall_rewriter/tests/snapshots/snapshot_tests__hello-diff.snap index 9f933eb4d..e13332c63 100644 --- a/litebox_syscall_rewriter/tests/snapshots/snapshot_tests__hello-diff.snap +++ b/litebox_syscall_rewriter/tests/snapshots/snapshot_tests__hello-diff.snap @@ -1,6 +1,5 @@ --- source: litebox_syscall_rewriter/tests/snapshot_tests.rs -assertion_line: 99 expression: diff --- --- original @@ -24,7 +23,7 @@ expression: diff - 401e78: 31 ff xor %edi,%edi - 401e7a: 89 d0 mov %edx,%eax - 401e7c: 0f 05 syscall -+ 401e78: ++ 401e78: + 401e7d: 90 nop 401e7e: eb f8 jmp 401e78 <__libc_start_call_main+0x88> 401e80: 31 c0 xor %eax,%eax @@ -35,7 +34,7 @@ expression: diff 403ee0: bf 01 50 00 00 mov $0x5001,%edi - 403ee5: b8 9e 00 00 00 mov $0x9e,%eax - 403eea: 0f 05 syscall -+ 403ee5: ++ 403ee5: + 403eea: 90 nop + 403eeb: 90 nop 403eec: 44 89 ef mov %r13d,%edi @@ -47,7 +46,7 @@ expression: diff 4043ce: 48 89 36 mov %rsi,(%rsi) - 4043d1: 48 89 76 10 mov %rsi,0x10(%rsi) - 4043d5: 0f 05 syscall -+ 4043d1: ++ 4043d1: + 4043d6: 90 nop 4043d7: 85 c0 test %eax,%eax 4043d9: 74 24 je 4043ff <__libc_setup_tls+0x1df> @@ -56,7 +55,7 @@ expression: diff 4043e5: b8 01 00 00 00 mov $0x1,%eax - 4043ea: 48 8d 35 c7 d1 07 00 lea 0x7d1c7(%rip),%rsi # 4815b8 - 4043f1: 0f 05 syscall -+ 4043ea: ++ 4043ea: + 4043ef: 90 nop + 4043f0: 90 nop + 4043f1: 90 nop @@ -64,7 +63,7 @@ expression: diff 4043f3: bf 7f 00 00 00 mov $0x7f,%edi - 4043f8: b8 e7 00 00 00 mov $0xe7,%eax - 4043fd: 0f 05 syscall -+ 4043f8: ++ 4043f8: + 4043fd: 90 nop + 4043fe: 90 nop 4043ff: e8 dc ba 01 00 call 41fee0 <__tls_init_tp> @@ -76,7 +75,7 @@ expression: diff 4044ba: b8 01 00 00 00 mov $0x1,%eax - 4044bf: 48 8d 35 f2 d0 07 00 lea 0x7d0f2(%rip),%rsi # 4815b8 - 4044c6: 0f 05 syscall -+ 4044bf: ++ 4044bf: + 4044c4: 90 nop + 4044c5: 90 nop + 4044c6: 90 nop @@ -84,7 +83,7 @@ expression: diff 4044c8: bf 7f 00 00 00 mov $0x7f,%edi - 4044cd: b8 e7 00 00 00 mov $0xe7,%eax - 4044d2: 0f 05 syscall -+ 4044cd: ++ 4044cd: + 4044d2: 90 nop + 4044d3: 90 nop 4044d4: e9 70 fe ff ff jmp 404349 <__libc_setup_tls+0x129> @@ -96,7 +95,7 @@ expression: diff 40a3e7: bf 02 00 00 00 mov $0x2,%edi - 40a3ec: 44 89 c8 mov %r9d,%eax - 40a3ef: 0f 05 syscall -+ 40a3ec: ++ 40a3ec: 40a3f1: 48 83 f8 fc cmp $0xfffffffffffffffc,%rax 40a3f5: 74 e9 je 40a3e0 <__libc_message_impl+0x150> 40a3f7: 45 31 c9 xor %r9d,%r9d @@ -106,7 +105,7 @@ expression: diff 40a5cf: be 80 00 00 00 mov $0x80,%esi - 40a5d4: b8 ca 00 00 00 mov $0xca,%eax - 40a5d9: 0f 05 syscall -+ 40a5d4: ++ 40a5d4: + 40a5d9: 90 nop + 40a5da: 90 nop 40a5db: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -118,7 +117,7 @@ expression: diff 40a635: b8 ca 00 00 00 mov $0xca,%eax - 40a63a: 40 80 f6 80 xor $0x80,%sil - 40a63e: 0f 05 syscall -+ 40a63a: ++ 40a63a: + 40a63f: 90 nop 40a640: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 40a646: 76 d6 jbe 40a61e <__lll_lock_wait+0xe> @@ -129,7 +128,7 @@ expression: diff 40a67c: be 81 00 00 00 mov $0x81,%esi - 40a681: b8 ca 00 00 00 mov $0xca,%eax - 40a686: 0f 05 syscall -+ 40a681: ++ 40a681: + 40a686: 90 nop + 40a687: 90 nop 40a688: c3 ret @@ -141,7 +140,7 @@ expression: diff 40a69b: ba 01 00 00 00 mov $0x1,%edx - 40a6a0: b8 ca 00 00 00 mov $0xca,%eax - 40a6a5: 0f 05 syscall -+ 40a6a0: ++ 40a6a0: + 40a6a5: 90 nop + 40a6a6: 90 nop 40a6a7: c3 ret @@ -153,7 +152,7 @@ expression: diff 40bbdb: c6 05 3e 4c 0a 00 01 movb $0x1,0xa4c3e(%rip) # 4b0820 <__malloc_initialized> - 40bbe2: b8 3e 01 00 00 mov $0x13e,%eax - 40bbe7: 0f 05 syscall -+ 40bbe2: ++ 40bbe2: + 40bbe7: 90 nop + 40bbe8: 90 nop 40bbe9: 48 8d 5d d0 lea -0x30(%rbp),%rbx @@ -165,7 +164,7 @@ expression: diff 4181de: 66 90 xchg %ax,%ax - 4181e0: b8 e4 00 00 00 mov $0xe4,%eax - 4181e5: 0f 05 syscall -+ 4181e0: ++ 4181e0: + 4181e5: 90 nop + 4181e6: 90 nop 4181e7: 85 c0 test %eax,%eax @@ -177,7 +176,7 @@ expression: diff 418249: 89 d0 mov %edx,%eax - 41824b: 0f 05 syscall - 41824d: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax -+ 41824b: ++ 41824b: + 418250: 90 nop + 418251: 90 nop + 418252: 90 nop @@ -190,7 +189,7 @@ expression: diff 418260: f3 0f 1e fa endbr64 - 418264: b8 05 00 00 00 mov $0x5,%eax - 418269: 0f 05 syscall -+ 418264: ++ 418264: + 418269: 90 nop + 41826a: 90 nop 41826b: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -202,7 +201,7 @@ expression: diff 418290: f3 0f 1e fa endbr64 - 418294: b8 03 00 00 00 mov $0x3,%eax - 418299: 0f 05 syscall -+ 418294: ++ 418294: + 418299: 90 nop + 41829a: 90 nop 41829b: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -214,7 +213,7 @@ expression: diff 4182f9: 74 25 je 418320 <__fcntl64_nocancel+0x60> - 4182fb: b8 48 00 00 00 mov $0x48,%eax - 418300: 0f 05 syscall -+ 4182fb: ++ 4182fb: + 418300: 90 nop + 418301: 90 nop 418302: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -226,7 +225,7 @@ expression: diff 418324: be 10 00 00 00 mov $0x10,%esi - 418329: b8 48 00 00 00 mov $0x48,%eax - 41832e: 0f 05 syscall -+ 418329: ++ 418329: + 41832e: 90 nop + 41832f: 90 nop 418330: 3d 00 f0 ff ff cmp $0xfffff000,%eax @@ -238,7 +237,7 @@ expression: diff 41837e: 74 20 je 4183a0 <__fcntl64_nocancel_adjusted+0x40> - 418380: b8 48 00 00 00 mov $0x48,%eax - 418385: 0f 05 syscall -+ 418380: ++ 418380: + 418385: 90 nop + 418386: 90 nop 418387: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -250,7 +249,7 @@ expression: diff 4183a4: be 10 00 00 00 mov $0x10,%esi - 4183a9: b8 48 00 00 00 mov $0x48,%eax - 4183ae: 0f 05 syscall -+ 4183a9: ++ 4183a9: + 4183ae: 90 nop + 4183af: 90 nop 4183b0: 3d 00 f0 ff ff cmp $0xfffff000,%eax @@ -262,7 +261,7 @@ expression: diff 41841a: 48 89 fe mov %rdi,%rsi - 41841d: bf 9c ff ff ff mov $0xffffff9c,%edi - 418422: 0f 05 syscall -+ 41841d: ++ 41841d: + 418422: 90 nop + 418423: 90 nop 418424: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -275,7 +274,7 @@ expression: diff - 418480: f3 0f 1e fa endbr64 - 418484: 31 c0 xor %eax,%eax - 418486: 0f 05 syscall -+ 418480: ++ 418480: + 418485: 90 nop + 418486: 90 nop + 418487: 90 nop @@ -288,7 +287,7 @@ expression: diff 4184b0: f3 0f 1e fa endbr64 - 4184b4: b8 0c 00 00 00 mov $0xc,%eax - 4184b9: 0f 05 syscall -+ 4184b4: ++ 4184b4: + 4184b9: 90 nop + 4184ba: 90 nop 4184bb: 48 89 05 96 83 09 00 mov %rax,0x98396(%rip) # 4b0858 <__curbrk> @@ -300,7 +299,7 @@ expression: diff 41871a: 48 8d 95 f0 ef ff ff lea -0x1010(%rbp),%rdx - 418721: b8 cc 00 00 00 mov $0xcc,%eax - 418726: 0f 05 syscall -+ 418721: ++ 418721: + 418726: 90 nop + 418727: 90 nop 418728: 85 c0 test %eax,%eax @@ -312,7 +311,7 @@ expression: diff 418b40: f3 0f 1e fa endbr64 - 418b44: b8 1c 00 00 00 mov $0x1c,%eax - 418b49: 0f 05 syscall -+ 418b44: ++ 418b44: + 418b49: 90 nop + 418b4a: 90 nop 418b4b: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -324,7 +323,7 @@ expression: diff 418b92: 48 89 df mov %rbx,%rdi - 418b95: b8 09 00 00 00 mov $0x9,%eax - 418b9a: 0f 05 syscall -+ 418b95: ++ 418b95: + 418b9a: 90 nop + 418b9b: 90 nop 418b9c: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -336,7 +335,7 @@ expression: diff 418bed: b8 09 00 00 00 mov $0x9,%eax - 418bf2: 41 83 ca 40 or $0x40,%r10d - 418bf6: 0f 05 syscall -+ 418bf2: ++ 418bf2: + 418bf7: 90 nop 418bf8: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 418bfe: 76 a4 jbe 418ba4 <__mmap64+0x34> @@ -347,7 +346,7 @@ expression: diff 418c30: f3 0f 1e fa endbr64 - 418c34: b8 0a 00 00 00 mov $0xa,%eax - 418c39: 0f 05 syscall -+ 418c34: ++ 418c34: + 418c39: 90 nop + 418c3a: 90 nop 418c3b: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -359,7 +358,7 @@ expression: diff 418c60: f3 0f 1e fa endbr64 - 418c64: b8 0b 00 00 00 mov $0xb,%eax - 418c69: 0f 05 syscall -+ 418c64: ++ 418c64: + 418c69: 90 nop + 418c6a: 90 nop 418c6b: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -371,7 +370,7 @@ expression: diff 418d47: 45 31 c0 xor %r8d,%r8d - 418d4a: b8 19 00 00 00 mov $0x19,%eax - 418d4f: 0f 05 syscall -+ 418d4a: ++ 418d4a: + 418d4f: 90 nop + 418d50: 90 nop 418d51: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -383,7 +382,7 @@ expression: diff 418e23: bf 41 4d 56 53 mov $0x53564d41,%edi - 418e28: b8 9d 00 00 00 mov $0x9d,%eax - 418e2d: 0f 05 syscall -+ 418e28: ++ 418e28: + 418e2d: 90 nop + 418e2e: 90 nop 418e2f: 83 f8 ea cmp $0xffffffea,%eax @@ -395,7 +394,7 @@ expression: diff 418e50: f3 0f 1e fa endbr64 - 418e54: b8 63 00 00 00 mov $0x63,%eax - 418e59: 0f 05 syscall -+ 418e54: ++ 418e54: + 418e59: 90 nop + 418e5a: 90 nop 418e5b: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -407,7 +406,7 @@ expression: diff 41e494: 48 8d 9d e0 ef ff ff lea -0x1020(%rbp),%rbx - 41e49b: 48 89 da mov %rbx,%rdx - 41e49e: 0f 05 syscall -+ 41e49b: ++ 41e49b: 41e4a0: 85 c0 test %eax,%eax 41e4a2: 7e 5c jle 41e500 <_dl_get_origin+0xa0> 41e4a4: 0f b6 95 e0 ef ff ff movzbl -0x1020(%rbp),%edx @@ -417,7 +416,7 @@ expression: diff 41e6db: 48 8d b5 d0 f6 ff ff lea -0x930(%rbp),%rsi - 41e6e2: b8 14 00 00 00 mov $0x14,%eax - 41e6e7: 0f 05 syscall -+ 41e6e2: ++ 41e6e2: + 41e6e7: 90 nop + 41e6e8: 90 nop 41e6e9: 48 81 c4 38 09 00 00 add $0x938,%rsp @@ -429,7 +428,7 @@ expression: diff 41ff24: 48 8d bb d0 02 00 00 lea 0x2d0(%rbx),%rdi - 41ff2b: b8 da 00 00 00 mov $0xda,%eax - 41ff30: 0f 05 syscall -+ 41ff2b: ++ 41ff2b: + 41ff30: 90 nop + 41ff31: 90 nop 41ff32: 89 83 d0 02 00 00 mov %eax,0x2d0(%rbx) @@ -441,7 +440,7 @@ expression: diff 41ff81: 66 0f 6c c0 punpcklqdq %xmm0,%xmm0 - 41ff85: 0f 11 83 d8 02 00 00 movups %xmm0,0x2d8(%rbx) - 41ff8c: 0f 05 syscall -+ 41ff85: ++ 41ff85: + 41ff8a: 90 nop + 41ff8b: 90 nop + 41ff8c: 90 nop @@ -455,7 +454,7 @@ expression: diff 41fff4: 48 89 df mov %rbx,%rdi - 41fff7: b8 4e 01 00 00 mov $0x14e,%eax - 41fffc: 0f 05 syscall -+ 41fff7: ++ 41fff7: + 41fffc: 90 nop + 41fffd: 90 nop 41fffe: 3d 00 f0 ff ff cmp $0xfffff000,%eax @@ -467,7 +466,7 @@ expression: diff 421344: bf 02 50 00 00 mov $0x5002,%edi - 421349: b8 9e 00 00 00 mov $0x9e,%eax - 42134e: 0f 05 syscall -+ 421349: ++ 421349: + 42134e: 90 nop + 42134f: 90 nop 421350: 89 c7 mov %eax,%edi @@ -479,7 +478,7 @@ expression: diff 4213a5: 48 89 e5 mov %rsp,%rbp - 4213a8: 48 8d 75 f8 lea -0x8(%rbp),%rsi - 4213ac: 0f 05 syscall -+ 4213a8: ++ 4213a8: + 4213ad: 90 nop 4213ae: 48 85 c0 test %rax,%rax 4213b1: 74 15 je 4213c8 <_dl_cet_setup_features+0x38> @@ -491,7 +490,7 @@ expression: diff - 4213f7: bf 03 50 00 00 mov $0x5003,%edi - 4213fc: 89 d0 mov %edx,%eax - 4213fe: 0f 05 syscall -+ 4213f7: ++ 4213f7: + 4213fc: 90 nop + 4213fd: 90 nop + 4213fe: 90 nop @@ -506,13 +505,13 @@ expression: diff - 421455: 31 ff xor %edi,%edi - 421457: 89 f0 mov %esi,%eax - 421459: 0f 05 syscall -+ 421455: ++ 421455: + 42145a: 90 nop 42145b: 48 89 c2 mov %rax,%rdx - 42145e: 48 8d 3c 18 lea (%rax,%rbx,1),%rdi - 421462: 89 f0 mov %esi,%eax - 421464: 0f 05 syscall -+ 42145e: ++ 42145e: + 421463: 90 nop + 421464: 90 nop + 421465: 90 nop @@ -525,7 +524,7 @@ expression: diff 421481: 48 89 de mov %rbx,%rsi - 421484: b8 09 00 00 00 mov $0x9,%eax - 421489: 0f 05 syscall -+ 421484: ++ 421484: + 421489: 90 nop + 42148a: 90 nop 42148b: 31 d2 xor %edx,%edx @@ -537,7 +536,7 @@ expression: diff 444c16: 48 8d 35 b3 0a 04 00 lea 0x40ab3(%rip),%rsi # 4856d0 - 444c1d: b8 0e 00 00 00 mov $0xe,%eax - 444c22: 0f 05 syscall -+ 444c1d: ++ 444c1d: + 444c22: 90 nop + 444c23: 90 nop 444c24: 31 c0 xor %eax,%eax @@ -549,7 +548,7 @@ expression: diff 444c63: bf 02 00 00 00 mov $0x2,%edi - 444c68: b8 0e 00 00 00 mov $0xe,%eax - 444c6d: 0f 05 syscall -+ 444c68: ++ 444c68: + 444c6d: 90 nop + 444c6e: 90 nop 444c6f: 48 8b 45 d8 mov -0x28(%rbp),%rax @@ -561,7 +560,7 @@ expression: diff 444ca8: 89 de mov %ebx,%esi - 444caa: b8 ea 00 00 00 mov $0xea,%eax - 444caf: 0f 05 syscall -+ 444caa: ++ 444caa: + 444caf: 90 nop + 444cb0: 90 nop 444cb1: 3d 00 f0 ff ff cmp $0xfffff000,%eax @@ -572,7 +571,7 @@ expression: diff 444cbe: 66 90 xchg %ax,%ax - 444cc0: b8 ba 00 00 00 mov $0xba,%eax - 444cc5: 0f 05 syscall -+ 444cc0: ++ 444cc0: + 444cc5: 90 nop + 444cc6: 90 nop 444cc7: 89 c3 mov %eax,%ebx @@ -582,7 +581,7 @@ expression: diff 444cd3: 89 c7 mov %eax,%edi - 444cd5: b8 ea 00 00 00 mov $0xea,%eax - 444cda: 0f 05 syscall -+ 444cd5: ++ 444cd5: + 444cda: 90 nop + 444cdb: 90 nop 444cdc: 89 c3 mov %eax,%ebx @@ -594,7 +593,7 @@ expression: diff 444d78: 4c 89 fa mov %r15,%rdx - 444d7b: 48 8d 35 4e 09 04 00 lea 0x4094e(%rip),%rsi # 4856d0 - 444d82: 0f 05 syscall -+ 444d7b: ++ 444d7b: + 444d80: 90 nop + 444d81: 90 nop + 444d82: 90 nop @@ -608,7 +607,7 @@ expression: diff 444dc4: bf 02 00 00 00 mov $0x2,%edi - 444dc9: b8 0e 00 00 00 mov $0xe,%eax - 444dce: 0f 05 syscall -+ 444dc9: ++ 444dc9: + 444dce: 90 nop + 444dcf: 90 nop 444dd0: 48 8b 45 c8 mov -0x38(%rbp),%rax @@ -620,7 +619,7 @@ expression: diff 444e08: 89 de mov %ebx,%esi - 444e0a: b8 ea 00 00 00 mov $0xea,%eax - 444e0f: 0f 05 syscall -+ 444e0a: ++ 444e0a: + 444e0f: 90 nop + 444e10: 90 nop 444e11: 3d 00 f0 ff ff cmp $0xfffff000,%eax @@ -630,7 +629,7 @@ expression: diff 444e1e: eb 8a jmp 444daa <__pthread_kill+0x8a> - 444e20: b8 ba 00 00 00 mov $0xba,%eax - 444e25: 0f 05 syscall -+ 444e20: ++ 444e20: + 444e25: 90 nop + 444e26: 90 nop 444e27: 89 c3 mov %eax,%ebx @@ -640,7 +639,7 @@ expression: diff 444e33: 89 c7 mov %eax,%edi - 444e35: b8 ea 00 00 00 mov $0xea,%eax - 444e3a: 0f 05 syscall -+ 444e35: ++ 444e35: + 444e3a: 90 nop + 444e3b: 90 nop 444e3c: 41 89 c6 mov %eax,%r14d @@ -652,7 +651,7 @@ expression: diff 445107: f7 d6 not %esi - 445109: 81 e6 80 00 00 00 and $0x80,%esi - 44510f: 0f 05 syscall -+ 445109: ++ 445109: + 44510e: 90 nop + 44510f: 90 nop + 445110: 90 nop @@ -665,7 +664,7 @@ expression: diff 4452e4: 48 89 df mov %rbx,%rdi - 4452e7: b8 ca 00 00 00 mov $0xca,%eax - 4452ec: 0f 05 syscall -+ 4452e7: ++ 4452e7: + 4452ec: 90 nop + 4452ed: 90 nop 4452ee: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -677,7 +676,7 @@ expression: diff 4454ff: be 07 00 00 00 mov $0x7,%esi - 445504: b8 ca 00 00 00 mov $0xca,%eax - 445509: 0f 05 syscall -+ 445504: ++ 445504: + 445509: 90 nop + 44550a: 90 nop 44550b: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -689,7 +688,7 @@ expression: diff 445aa9: 81 e6 80 00 00 00 and $0x80,%esi - 445aaf: 40 80 f6 81 xor $0x81,%sil - 445ab3: 0f 05 syscall -+ 445aaf: ++ 445aaf: + 445ab4: 90 nop 445ab5: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 445abb: 0f 87 0e 02 00 00 ja 445ccf <__pthread_mutex_unlock_full+0x3bf> @@ -700,7 +699,7 @@ expression: diff 445cfd: 4c 89 c7 mov %r8,%rdi - 445d00: b8 ca 00 00 00 mov $0xca,%eax - 445d05: 0f 05 syscall -+ 445d00: ++ 445d00: + 445d05: 90 nop + 445d06: 90 nop 445d07: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -712,7 +711,7 @@ expression: diff 445d29: 4c 89 c7 mov %r8,%rdi - 445d2c: b8 ca 00 00 00 mov $0xca,%eax - 445d31: 0f 05 syscall -+ 445d2c: ++ 445d2c: + 445d31: 90 nop + 445d32: 90 nop 445d33: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -724,7 +723,7 @@ expression: diff 44600f: 48 89 df mov %rbx,%rdi - 446012: b8 ca 00 00 00 mov $0xca,%eax - 446017: 0f 05 syscall -+ 446012: ++ 446012: + 446017: 90 nop + 446018: 90 nop 446019: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -736,7 +735,7 @@ expression: diff 4460b0: 48 89 df mov %rbx,%rdi - 4460b3: b8 ca 00 00 00 mov $0xca,%eax - 4460b8: 0f 05 syscall -+ 4460b3: ++ 4460b3: + 4460b8: 90 nop + 4460b9: 90 nop 4460ba: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -748,7 +747,7 @@ expression: diff 446142: be 81 00 00 00 mov $0x81,%esi - 446147: b8 ca 00 00 00 mov $0xca,%eax - 44614c: 0f 05 syscall -+ 446147: ++ 446147: + 44614c: 90 nop + 44614d: 90 nop 44614e: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -760,7 +759,7 @@ expression: diff 4462e3: c1 e6 07 shl $0x7,%esi - 4462e6: 40 80 f6 81 xor $0x81,%sil - 4462ea: 0f 05 syscall -+ 4462e6: ++ 4462e6: + 4462eb: 90 nop 4462ec: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 4462f2: 0f 86 2e ff ff ff jbe 446226 <___pthread_rwlock_rdlock+0x46> @@ -771,7 +770,7 @@ expression: diff 446437: 40 80 f6 81 xor $0x81,%sil - 44643b: b8 ca 00 00 00 mov $0xca,%eax - 446440: 0f 05 syscall -+ 44643b: ++ 44643b: + 446440: 90 nop + 446441: 90 nop 446442: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -783,7 +782,7 @@ expression: diff 44648a: b8 ca 00 00 00 mov $0xca,%eax - 44648f: 40 80 f6 81 xor $0x81,%sil - 446493: 0f 05 syscall -+ 44648f: ++ 44648f: + 446494: 90 nop 446495: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 44649b: 76 83 jbe 446420 <___pthread_rwlock_unlock+0x50> @@ -794,7 +793,7 @@ expression: diff 446511: 40 80 f6 81 xor $0x81,%sil - 446515: b8 ca 00 00 00 mov $0xca,%eax - 44651a: 0f 05 syscall -+ 446515: ++ 446515: + 44651a: 90 nop + 44651b: 90 nop 44651c: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -806,7 +805,7 @@ expression: diff 446577: b8 ca 00 00 00 mov $0xca,%eax - 44657c: 40 80 f6 81 xor $0x81,%sil - 446580: 0f 05 syscall -+ 44657c: ++ 44657c: + 446581: 90 nop 446582: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 446588: 0f 86 6c ff ff ff jbe 4464fa <___pthread_rwlock_unlock+0x12a> @@ -817,7 +816,7 @@ expression: diff 446855: 40 80 f6 81 xor $0x81,%sil - 446859: b8 ca 00 00 00 mov $0xca,%eax - 44685e: 0f 05 syscall -+ 446859: ++ 446859: + 44685e: 90 nop + 44685f: 90 nop 446860: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -829,7 +828,7 @@ expression: diff 446880: 40 80 f6 81 xor $0x81,%sil - 446884: b8 ca 00 00 00 mov $0xca,%eax - 446889: 0f 05 syscall -+ 446884: ++ 446884: + 446889: 90 nop + 44688a: 90 nop 44688b: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -841,7 +840,7 @@ expression: diff 446924: 40 80 f6 81 xor $0x81,%sil - 446928: b8 ca 00 00 00 mov $0xca,%eax - 44692d: 0f 05 syscall -+ 446928: ++ 446928: + 44692d: 90 nop + 44692e: 90 nop 44692f: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -853,7 +852,7 @@ expression: diff 446a0b: 41 ba 08 00 00 00 mov $0x8,%r10d - 446a11: b8 0e 00 00 00 mov $0xe,%eax - 446a16: 0f 05 syscall -+ 446a11: ++ 446a11: + 446a16: 90 nop + 446a17: 90 nop 446a18: 89 c2 mov %eax,%edx @@ -865,7 +864,7 @@ expression: diff 45ba2c: 48 0f 47 d0 cmova %rax,%rdx - 45ba30: b8 d9 00 00 00 mov $0xd9,%eax - 45ba35: 0f 05 syscall -+ 45ba30: ++ 45ba30: + 45ba35: 90 nop + 45ba36: 90 nop 45ba37: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -877,7 +876,7 @@ expression: diff 45bb50: f3 0f 1e fa endbr64 - 45bb54: b8 27 00 00 00 mov $0x27,%eax - 45bb59: 0f 05 syscall -+ 45bb54: ++ 45bb54: + 45bb59: 90 nop + 45bb5a: 90 nop 45bb5b: c3 ret @@ -889,7 +888,7 @@ expression: diff 45bba0: f3 0f 1e fa endbr64 - 45bba4: b8 8f 00 00 00 mov $0x8f,%eax - 45bba9: 0f 05 syscall -+ 45bba4: ++ 45bba4: + 45bba9: 90 nop + 45bbaa: 90 nop 45bbab: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -901,7 +900,7 @@ expression: diff 45bbd0: f3 0f 1e fa endbr64 - 45bbd4: b8 91 00 00 00 mov $0x91,%eax - 45bbd9: 0f 05 syscall -+ 45bbd4: ++ 45bbd4: + 45bbd9: 90 nop + 45bbda: 90 nop 45bbdb: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -913,7 +912,7 @@ expression: diff 45bc00: f3 0f 1e fa endbr64 - 45bc04: b8 92 00 00 00 mov $0x92,%eax - 45bc09: 0f 05 syscall -+ 45bc04: ++ 45bc04: + 45bc09: 90 nop + 45bc0a: 90 nop 45bc0b: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -925,7 +924,7 @@ expression: diff 45bc30: f3 0f 1e fa endbr64 - 45bc34: b8 93 00 00 00 mov $0x93,%eax - 45bc39: 0f 05 syscall -+ 45bc34: ++ 45bc34: + 45bc39: 90 nop + 45bc3a: 90 nop 45bc3b: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -937,7 +936,7 @@ expression: diff 45bc60: f3 0f 1e fa endbr64 - 45bc64: b8 90 00 00 00 mov $0x90,%eax - 45bc69: 0f 05 syscall -+ 45bc64: ++ 45bc64: + 45bc69: 90 nop + 45bc6a: 90 nop 45bc6b: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax @@ -949,7 +948,7 @@ expression: diff 45bd0d: 48 8b bd 08 ff ff ff mov -0xf8(%rbp),%rdi - 45bd14: b8 4f 00 00 00 mov $0x4f,%eax - 45bd19: 0f 05 syscall -+ 45bd14: ++ 45bd14: + 45bd19: 90 nop + 45bd1a: 90 nop 45bd1b: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -961,7 +960,7 @@ expression: diff 45c510: f3 0f 1e fa endbr64 - 45c514: b8 08 00 00 00 mov $0x8,%eax - 45c519: 0f 05 syscall -+ 45c514: ++ 45c514: + 45c519: 90 nop + 45c51a: 90 nop 45c51b: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -973,7 +972,7 @@ expression: diff 45c5a9: bf 9c ff ff ff mov $0xffffff9c,%edi - 45c5ae: b8 01 01 00 00 mov $0x101,%eax - 45c5b3: 0f 05 syscall -+ 45c5ae: ++ 45c5ae: + 45c5b3: 90 nop + 45c5b4: 90 nop 45c5b5: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -985,7 +984,7 @@ expression: diff 45c619: bf 9c ff ff ff mov $0xffffff9c,%edi - 45c61e: b8 01 01 00 00 mov $0x101,%eax - 45c623: 0f 05 syscall -+ 45c61e: ++ 45c61e: + 45c623: 90 nop + 45c624: 90 nop 45c625: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -997,7 +996,7 @@ expression: diff 45c6b9: 74 51 je 45c70c <__libc_openat64+0x8c> - 45c6bb: b8 01 01 00 00 mov $0x101,%eax - 45c6c0: 0f 05 syscall -+ 45c6bb: ++ 45c6bb: + 45c6c0: 90 nop + 45c6c1: 90 nop 45c6c2: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1009,7 +1008,7 @@ expression: diff 45c72d: 8b 7d a8 mov -0x58(%rbp),%edi - 45c730: b8 01 01 00 00 mov $0x101,%eax - 45c735: 0f 05 syscall -+ 45c730: ++ 45c730: + 45c735: 90 nop + 45c736: 90 nop 45c737: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1021,7 +1020,7 @@ expression: diff 45c79d: 31 c0 xor %eax,%eax - 45c79f: 0f 05 syscall - 45c7a1: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax -+ 45c79f: ++ 45c79f: + 45c7a4: 90 nop + 45c7a5: 90 nop + 45c7a6: 90 nop @@ -1035,7 +1034,7 @@ expression: diff - 45c7d3: 8b 7d f8 mov -0x8(%rbp),%edi - 45c7d6: 31 c0 xor %eax,%eax - 45c7d8: 0f 05 syscall -+ 45c7d3: ++ 45c7d3: + 45c7d8: 90 nop + 45c7d9: 90 nop 45c7da: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1047,7 +1046,7 @@ expression: diff 45c85b: 74 13 je 45c870 <__libc_write+0x20> - 45c85d: b8 01 00 00 00 mov $0x1,%eax - 45c862: 0f 05 syscall -+ 45c85d: ++ 45c85d: + 45c862: 90 nop + 45c863: 90 nop 45c864: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1059,7 +1058,7 @@ expression: diff 45c893: 8b 7d f8 mov -0x8(%rbp),%edi - 45c896: b8 01 00 00 00 mov $0x1,%eax - 45c89b: 0f 05 syscall -+ 45c896: ++ 45c896: + 45c89b: 90 nop + 45c89c: 90 nop 45c89d: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1071,7 +1070,7 @@ expression: diff 45c920: 74 26 je 45c948 <__openat64_nocancel+0x58> - 45c922: b8 01 01 00 00 mov $0x101,%eax - 45c927: 0f 05 syscall -+ 45c922: ++ 45c922: + 45c927: 90 nop + 45c928: 90 nop 45c929: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1083,7 +1082,7 @@ expression: diff 45c984: 49 89 ca mov %rcx,%r10 - 45c987: b8 11 00 00 00 mov $0x11,%eax - 45c98c: 0f 05 syscall -+ 45c987: ++ 45c987: + 45c98c: 90 nop + 45c98d: 90 nop 45c98e: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1095,7 +1094,7 @@ expression: diff 45c9c0: f3 0f 1e fa endbr64 - 45c9c4: b8 01 00 00 00 mov $0x1,%eax - 45c9c9: 0f 05 syscall -+ 45c9c4: ++ 45c9c4: + 45c9c9: 90 nop + 45c9ca: 90 nop 45c9cb: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1107,7 +1106,7 @@ expression: diff 45ca13: 48 8d 55 d0 lea -0x30(%rbp),%rdx - 45ca17: b8 10 00 00 00 mov $0x10,%eax - 45ca1c: 0f 05 syscall -+ 45ca17: ++ 45ca17: + 45ca1c: 90 nop + 45ca1d: 90 nop 45ca1e: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1120,7 +1119,7 @@ expression: diff - 45cabb: b8 2e 01 00 00 mov $0x12e,%eax - 45cac0: 31 ff xor %edi,%edi - 45cac2: 0f 05 syscall -+ 45cabb: ++ 45cabb: + 45cac0: 90 nop + 45cac1: 90 nop + 45cac2: 90 nop @@ -1134,7 +1133,7 @@ expression: diff 45ffa0: 48 8d 78 1c lea 0x1c(%rax),%rdi - 45ffa4: b8 ca 00 00 00 mov $0xca,%eax - 45ffa9: 0f 05 syscall -+ 45ffa4: ++ 45ffa4: + 45ffa9: 90 nop + 45ffaa: 90 nop 45ffab: 48 8d 3d 6e ab 04 00 lea 0x4ab6e(%rip),%rdi # 4aab20 <_dl_load_lock> @@ -1146,7 +1145,7 @@ expression: diff 46306a: be 80 00 00 00 mov $0x80,%esi - 46306f: 44 89 c8 mov %r9d,%eax - 463072: 0f 05 syscall -+ 46306f: ++ 46306f: 463074: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 46307a: 76 dc jbe 463058 <__thread_gscope_wait+0x88> 46307c: 83 f8 f5 cmp $0xfffffff5,%eax @@ -1156,7 +1155,7 @@ expression: diff 46310a: be 80 00 00 00 mov $0x80,%esi - 46310f: 44 89 c8 mov %r9d,%eax - 463112: 0f 05 syscall -+ 46310f: ++ 46310f: 463114: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 46311a: 76 dc jbe 4630f8 <__thread_gscope_wait+0x128> 46311c: 83 f8 f5 cmp $0xfffffff5,%eax @@ -1166,7 +1165,7 @@ expression: diff 00000000004669d0 <__restore_rt>: - 4669d0: 48 c7 c0 0f 00 00 00 mov $0xf,%rax - 4669d7: 0f 05 syscall -+ 4669d0: ++ 4669d0: + 4669d5: 90 nop + 4669d6: 90 nop + 4669d7: 90 nop @@ -1180,7 +1179,7 @@ expression: diff 466aad: 41 ba 08 00 00 00 mov $0x8,%r10d - 466ab3: b8 0d 00 00 00 mov $0xd,%eax - 466ab8: 0f 05 syscall -+ 466ab3: ++ 466ab3: + 466ab8: 90 nop + 466ab9: 90 nop 466aba: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax @@ -1192,7 +1191,7 @@ expression: diff 46cb16: be 80 00 00 00 mov $0x80,%esi - 46cb1b: 44 89 c0 mov %r8d,%eax - 46cb1e: 0f 05 syscall -+ 46cb1b: ++ 46cb1b: 46cb20: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax 46cb26: 77 0d ja 46cb35 <__pthread_disable_asynccancel+0x65> 46cb28: 8b 0f mov (%rdi),%ecx @@ -1202,7 +1201,7 @@ expression: diff 46ccdf: 44 31 c6 xor %r8d,%esi - 46cce2: 45 31 c0 xor %r8d,%r8d - 46cce5: 0f 05 syscall -+ 46cce2: ++ 46cce2: 46cce7: 85 c0 test %eax,%eax 46cce9: 7f 27 jg 46cd12 <__futex_abstimed_wait64+0x62> 46cceb: 83 f8 ea cmp $0xffffffea,%eax @@ -1212,7 +1211,7 @@ expression: diff 46cd89: 44 89 e2 mov %r12d,%edx - 46cd8c: b8 ca 00 00 00 mov $0xca,%eax - 46cd91: 0f 05 syscall -+ 46cd8c: ++ 46cd8c: + 46cd91: 90 nop + 46cd92: 90 nop 46cd93: 48 89 c3 mov %rax,%rbx @@ -1224,7 +1223,7 @@ expression: diff 46ce17: 44 89 e2 mov %r12d,%edx - 46ce1a: b8 ca 00 00 00 mov $0xca,%eax - 46ce1f: 0f 05 syscall -+ 46ce1a: ++ 46ce1a: + 46ce1f: 90 nop + 46ce20: 90 nop 46ce21: 44 89 ef mov %r13d,%edi @@ -1236,7 +1235,7 @@ expression: diff 46ce6c: 31 d2 xor %edx,%edx - 46ce6e: b8 ca 00 00 00 mov $0xca,%eax - 46ce73: 0f 05 syscall -+ 46ce6e: ++ 46ce6e: + 46ce73: 90 nop + 46ce74: 90 nop 46ce75: 83 f8 da cmp $0xffffffda,%eax @@ -1248,7 +1247,7 @@ expression: diff 46f344: 41 89 ca mov %ecx,%r10d - 46f347: b8 06 01 00 00 mov $0x106,%eax - 46f34c: 0f 05 syscall -+ 46f347: ++ 46f347: + 46f34c: 90 nop + 46f34d: 90 nop 46f34e: 3d 00 f0 ff ff cmp $0xfffff000,%eax @@ -1260,7 +1259,7 @@ expression: diff 472975: 48 8d 78 1c lea 0x1c(%rax),%rdi - 472979: b8 ca 00 00 00 mov $0xca,%eax - 47297e: 0f 05 syscall -+ 472979: ++ 472979: + 47297e: 90 nop + 47297f: 90 nop 472980: eb 8c jmp 47290e <_dl_fixup+0x10e> @@ -1272,7 +1271,7 @@ expression: diff 476c10: 48 8d 78 1c lea 0x1c(%rax),%rdi - 476c14: b8 ca 00 00 00 mov $0xca,%eax - 476c19: 0f 05 syscall -+ 476c14: ++ 476c14: + 476c19: 90 nop + 476c1a: 90 nop 476c1b: 48 83 7d 98 00 cmpq $0x0,-0x68(%rbp) @@ -1284,7 +1283,7 @@ expression: diff 476e4a: 48 8d 78 1c lea 0x1c(%rax),%rdi - 476e4e: b8 ca 00 00 00 mov $0xca,%eax - 476e53: 0f 05 syscall -+ 476e4e: ++ 476e4e: + 476e53: 90 nop + 476e54: 90 nop 476e55: 48 83 7d 98 00 cmpq $0x0,-0x68(%rbp) From 19b575c257ed1f606b5318bc19566bf0672fa677 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 11:37:44 -0700 Subject: [PATCH 02/10] Fix size=0 sentinel comments to accurately describe semantics --- litebox_common_linux/src/loader.rs | 6 +++--- litebox_syscall_rewriter/src/lib.rs | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/litebox_common_linux/src/loader.rs b/litebox_common_linux/src/loader.rs index 59e1c537a..de794afe5 100644 --- a/litebox_common_linux/src/loader.rs +++ b/litebox_common_linux/src/loader.rs @@ -291,8 +291,8 @@ impl ElfParsedFile { ) }; - // Size=0 sentinel: "checked by rewriter, no syscalls to patch." - // Treat the same as "no trampoline found." + // Size=0 sentinel: the rewriter processed this binary but found no + // syscall instructions, so there is no trampoline region to map. if trampoline_size == 0 { return Ok(()); } @@ -601,7 +601,7 @@ pub trait MapMemory { /// /// Fails if any of the parameters are not page-aligned. fn protect(&mut self, address: usize, len: usize, prot: &Protection) - -> Result<(), Self::Error>; + -> Result<(), Self::Error>; } /// Trait for reading and writing memory that has been mapped via [`MapMemory`]. diff --git a/litebox_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index 654ce8648..18a728811 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -370,7 +370,8 @@ fn is_already_hooked(input_binary: &[u8], arch: Arch) -> bool { }; if trampoline_size == 0 { - // Size=0 sentinel: "checked by rewriter, no syscalls to patch." + // Size=0 sentinel: the rewriter processed this binary but found no + // syscall instructions. It is already hooked (nothing to do). return true; } if file_offset % 0x1000 != 0 { @@ -535,8 +536,8 @@ fn hook_syscalls_in_section( trampoline_data.extend_from_slice(&[0xE8, 0x0, 0x0, 0x0, 0x0]); // CALL next instruction trampoline_data.push(0x58); // POP EAX (effectively store IP in EAX) trampoline_data.extend_from_slice(&[0xFF, 0x90]); // CALL [EAX + offset] - // EAX = trampoline_base_addr + (trampoline_data.len() - 3) - // We want: EAX + offset = syscall_entry_addr + // EAX = trampoline_base_addr + (trampoline_data.len() - 3) + // We want: EAX + offset = syscall_entry_addr let call_base = checked_add_u64( trampoline_base_addr, trampoline_data.len() as u64 - 3, @@ -1027,8 +1028,8 @@ fn hook_syscall_and_after( trampoline_data.extend_from_slice(&[0xE8, 0x0, 0x0, 0x0, 0x0]); // CALL next instruction trampoline_data.push(0x58); // POP EAX (effectively store IP in EAX) trampoline_data.extend_from_slice(&[0xFF, 0x90]); // CALL [EAX + offset] - // EAX = trampoline_base_addr + (trampoline_data.len() - 3) - // We want: EAX + offset = syscall_entry_addr + // EAX = trampoline_base_addr + (trampoline_data.len() - 3) + // We want: EAX + offset = syscall_entry_addr let call_base = checked_add_u64( trampoline_base_addr, trampoline_data.len() as u64, @@ -1171,8 +1172,8 @@ fn hook_syscall_before_and_after( trampoline_data.extend_from_slice(&[0xE8, 0x0, 0x0, 0x0, 0x0]); // CALL next instruction trampoline_data.push(0x58); // POP EAX (effectively store IP in EAX) trampoline_data.extend_from_slice(&[0xFF, 0x90]); // CALL [EAX + offset] - // EAX = trampoline_base_addr + (trampoline_data.len() - 3) - // We want: EAX + offset = syscall_entry_addr + // EAX = trampoline_base_addr + (trampoline_data.len() - 3) + // We want: EAX + offset = syscall_entry_addr let call_base = checked_add_u64( trampoline_base_addr, trampoline_data.len() as u64, From f1d1aef87bd23a3e26d927410c3aefd12f7b8f7f Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 11:46:00 -0700 Subject: [PATCH 03/10] Minor style cleanup: simplify match arm and fix comment indentation --- litebox_syscall_rewriter/src/lib.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/litebox_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index 18a728811..32f4d126a 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -182,9 +182,7 @@ pub fn hook_syscalls_in_elf(input_binary: &[u8], trampoline: Option) -> Res let text_sections = match text_sections(&file) { Ok(sections) => sections, - Err(InternalError::NoTextSectionFound) => { - return Ok(input_binary.to_vec()); - } + Err(InternalError::NoTextSectionFound) => return Ok(input_binary.to_vec()), Err(InternalError::Public(e)) => return Err(e), Err(e) => unreachable!("unexpected internal error: {e:?}"), }; @@ -536,8 +534,8 @@ fn hook_syscalls_in_section( trampoline_data.extend_from_slice(&[0xE8, 0x0, 0x0, 0x0, 0x0]); // CALL next instruction trampoline_data.push(0x58); // POP EAX (effectively store IP in EAX) trampoline_data.extend_from_slice(&[0xFF, 0x90]); // CALL [EAX + offset] - // EAX = trampoline_base_addr + (trampoline_data.len() - 3) - // We want: EAX + offset = syscall_entry_addr + // EAX = trampoline_base_addr + (trampoline_data.len() - 3) + // We want: EAX + offset = syscall_entry_addr let call_base = checked_add_u64( trampoline_base_addr, trampoline_data.len() as u64 - 3, @@ -1028,8 +1026,8 @@ fn hook_syscall_and_after( trampoline_data.extend_from_slice(&[0xE8, 0x0, 0x0, 0x0, 0x0]); // CALL next instruction trampoline_data.push(0x58); // POP EAX (effectively store IP in EAX) trampoline_data.extend_from_slice(&[0xFF, 0x90]); // CALL [EAX + offset] - // EAX = trampoline_base_addr + (trampoline_data.len() - 3) - // We want: EAX + offset = syscall_entry_addr + // EAX = trampoline_base_addr + (trampoline_data.len() - 3) + // We want: EAX + offset = syscall_entry_addr let call_base = checked_add_u64( trampoline_base_addr, trampoline_data.len() as u64, @@ -1172,8 +1170,8 @@ fn hook_syscall_before_and_after( trampoline_data.extend_from_slice(&[0xE8, 0x0, 0x0, 0x0, 0x0]); // CALL next instruction trampoline_data.push(0x58); // POP EAX (effectively store IP in EAX) trampoline_data.extend_from_slice(&[0xFF, 0x90]); // CALL [EAX + offset] - // EAX = trampoline_base_addr + (trampoline_data.len() - 3) - // We want: EAX + offset = syscall_entry_addr + // EAX = trampoline_base_addr + (trampoline_data.len() - 3) + // We want: EAX + offset = syscall_entry_addr let call_base = checked_add_u64( trampoline_base_addr, trampoline_data.len() as u64, From 3bd6fb516cb41753f5d18f3055a587d557b7d82e Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 11:53:11 -0700 Subject: [PATCH 04/10] Fix rustfmt edition 2024 formatting in loader.rs --- litebox_common_linux/src/loader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litebox_common_linux/src/loader.rs b/litebox_common_linux/src/loader.rs index de794afe5..b2b4832ac 100644 --- a/litebox_common_linux/src/loader.rs +++ b/litebox_common_linux/src/loader.rs @@ -601,7 +601,7 @@ pub trait MapMemory { /// /// Fails if any of the parameters are not page-aligned. fn protect(&mut self, address: usize, len: usize, prot: &Protection) - -> Result<(), Self::Error>; + -> Result<(), Self::Error>; } /// Trait for reading and writing memory that has been mapped via [`MapMemory`]. From 88c4346e7847b29280072bdbaa8e6402ba6675c8 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 11:57:30 -0700 Subject: [PATCH 05/10] Fix Windows test: rewrite litebox_rtld_audit.so to get new trampoline format --- litebox_runner_linux_on_windows_userland/tests/loader.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/litebox_runner_linux_on_windows_userland/tests/loader.rs b/litebox_runner_linux_on_windows_userland/tests/loader.rs index e6f470e34..066190f70 100644 --- a/litebox_runner_linux_on_windows_userland/tests/loader.rs +++ b/litebox_runner_linux_on_windows_userland/tests/loader.rs @@ -360,8 +360,9 @@ fn test_testcase_dynamic_with_rewriter() { let libs_to_rewrite = [ ("libc.so.6", "/lib/x86_64-linux-gnu"), ("ld-linux-x86-64.so.2", "/lib64"), + ("litebox_rtld_audit.so", "/lib"), ]; - let libs_without_rewrite = [("litebox_rtld_audit.so", "/lib")]; + let libs_without_rewrite: [(&str, &str); 0] = []; // Run run_dynamic_linked_prog_with_rewriter( From 2d8d49d98281131f4a89f7bbda24cb7469763863 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 12:06:07 -0700 Subject: [PATCH 06/10] Rebuild litebox_rtld_audit.so with new trampoline format (redzone + R11) The pre-built binary had old-format trampolines that jumped to syscall_callback_redzone without reserving the red zone, causing an access violation (0xc0000005) on Windows. --- .../tests/test-bins/litebox_rtld_audit.so | Bin 14480 -> 16453 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so diff --git a/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so b/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so old mode 100644 new mode 100755 index 66e3687ee7123e5078d29c6187bfa7d0671b23be..b51bb34f379b8e55de14af8957720702d68d6993 GIT binary patch literal 16453 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 TgD-W)kohDs&4S`U5HJ4#5}~PB literal 14480 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 I1-0A%9o;rSZU6uP From 77092403ac580ff94e6fc105646e2177048a7bd7 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 12:12:52 -0700 Subject: [PATCH 07/10] Fix: don't rewrite litebox_rtld_audit.so (it has raw syscall for mincore probe) The rtld_audit library uses a real syscall instruction in raw_syscall3() for the mincore probe before syscall_entry is known. Rewriting it would hook that instruction and jump to address 0. Rebuild from source (which already has the new do_syscall preamble) and copy without rewriting. --- .../tests/loader.rs | 3 +-- .../tests/test-bins/litebox_rtld_audit.so | Bin 16453 -> 14328 bytes 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/litebox_runner_linux_on_windows_userland/tests/loader.rs b/litebox_runner_linux_on_windows_userland/tests/loader.rs index 066190f70..e6f470e34 100644 --- a/litebox_runner_linux_on_windows_userland/tests/loader.rs +++ b/litebox_runner_linux_on_windows_userland/tests/loader.rs @@ -360,9 +360,8 @@ fn test_testcase_dynamic_with_rewriter() { let libs_to_rewrite = [ ("libc.so.6", "/lib/x86_64-linux-gnu"), ("ld-linux-x86-64.so.2", "/lib64"), - ("litebox_rtld_audit.so", "/lib"), ]; - let libs_without_rewrite: [(&str, &str); 0] = []; + let libs_without_rewrite = [("litebox_rtld_audit.so", "/lib")]; // Run run_dynamic_linked_prog_with_rewriter( diff --git a/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so b/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so index b51bb34f379b8e55de14af8957720702d68d6993..3222d1484b2422b8f59aec1da2ebe44fcd3bb102 100755 GIT binary patch delta 20 ccmX@w!1yD7!x0fSpKjj+{H&W#iRdW<0ALmf761SM delta 87 zcmey7f3$&d!x0g-m-f~S3==k=646uMY``MGVe8ZFd%&YNMWw-~S9Z;j|NlLDc~=9e b|EjlvgpX&4tCN3(0fPer1Oz}RRVWt#Cj1?_ From 9c9e8d1d7448f87e30c4edccb0293f2bd2e9f2b9 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 12:17:29 -0700 Subject: [PATCH 08/10] Remove raw_syscall3/mincore probe from rtld_audit parse_object is only called for the main binary and interpreter, which always have syscall instructions and mapped trampolines. The mincore probe for the size=0 sentinel case is unnecessary. Removing the raw syscall instruction also means the rewriter can safely process rtld_audit.so (it finds no syscall instructions to hook). --- litebox_rtld_audit/rtld_audit.c | 30 +++--------------- .../tests/test-bins/litebox_rtld_audit.so | Bin 14328 -> 14288 bytes 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/litebox_rtld_audit/rtld_audit.c b/litebox_rtld_audit/rtld_audit.c index 7bec7e9ee..8af458f30 100644 --- a/litebox_rtld_audit/rtld_audit.c +++ b/litebox_rtld_audit/rtld_audit.c @@ -180,24 +180,10 @@ void print_hex(uint64_t data) { /// The entry point is at offset 0 of the mapped trampoline. The litebox loader /// already validated the magic when parsing the file header. /// -/// For binaries processed by the rewriter but containing no syscall instructions -/// (trampoline_size=0 sentinel), no trampoline pages are mapped. We detect this -/// by probing the expected address with `mincore` via a raw syscall. -static long raw_syscall3(long num, long a1, long a2, long a3) { - long ret; - register long r10 __asm__("r10") = 0; - register long r8 __asm__("r8") = 0; - register long r9 __asm__("r9") = 0; - __asm__ volatile("syscall" - : "=a"(ret) - : "0"(num), "D"(a1), "S"(a2), "d"(a3), - "r"(r10), "r"(r8), "r"(r9) - : "rcx", "r11", "memory"); - return ret; -} - -#define SYS_mincore 27 - +/// This is only called for the main binary and the interpreter, both of which +/// are expected to contain syscall instructions (and thus have a mapped +/// trampoline region). Binaries with no syscalls (trampoline_size=0 sentinel) +/// are not expected here. int parse_object(const struct link_map *map) { unsigned long max_addr = 0; Elf64_Ehdr *eh = (Elf64_Ehdr *)map->l_addr; @@ -224,14 +210,6 @@ int parse_object(const struct link_map *map) { max_addr = align_up(max_addr, 0x1000); void *trampoline_addr = (void *)map->l_addr + max_addr; - // Check if the trampoline page is mapped. Binaries with no syscall - // instructions have a size=0 sentinel header and no trampoline pages. - unsigned char vec; - if (raw_syscall3(SYS_mincore, (long)trampoline_addr, 0x1000, (long)&vec) < 0) { - syscall_print("[audit] no trampoline page mapped\n", 34); - return 1; - } - // The trampoline code has the syscall entry point at offset 0. syscall_entry = (syscall_stub_t)read_u64(trampoline_addr); if (syscall_entry == 0) { diff --git a/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so b/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so index 3222d1484b2422b8f59aec1da2ebe44fcd3bb102..e84b58e4d0073de1c809330dccd8231c5203119a 100755 GIT binary patch delta 849 zcmYk3QAkr^6vw}FS5vp?Y~C@aqup7#>C~Jtmym6if)#;~NQ8pIf;|*!l+=SJs6koe zJTDUo)CeL7f{UO&83`FZq)=iJ=$@PqwycNM24CmiYvF-=f9IV4|N9R2+*J2U_m~G- zqGjEN4I@)y!x){ZGGsujG7$Z;mJ`+r7RGsaEY=3!Pp(JT%0D>H$S;?gZq40Xn8$YE z8pQCO5EObu*`T{FtLrbBKH&`h4;-O;~S!+ zTBk^lVBB>?AEr#&kqsp~Ci;AjoT_>bWl7~1QM77chlv8qVlAT9P{&g0#(1?Y$G@ja z2tKzxL>18bQl}}|7w53SXS26c2bhT^g8L*&Z(uK}{ghdhITlS-mq6(Qoc7sZ9DO<) zOyH_uD|x!-Oy+COJ`L=}UcW~~LrtaJSknvg+=(d=?i%rme*nVx*?;`dZAr8LaNS1E z1HD605%wW4?uRfxI5OM(HX*_!$oh2sP)#kECfv^5y+QQAeSYWs&;L9R_grqwpYV^D z(#xSe{!G7`B$r6@6I%X|;gb{MgK2tG-_gIsFU;)YW}J(W&lY`AjZeG< zZH$l3!va&s5Cfm7@@S|Rj_VH4KA6yL(h%Ip%OC6wvq8`7YyqD3nrI0TA{ep538D!~ zmq*;&6tP+>sa$_pNXL{7q#P}mT(yk|q8a_ynU{3d+OZ-W+!jSV0Tsfzx7p#h-cxg( zofR6(h$N9_HUJxWosEIsI2&jd*nnq+jkse{2^m!wPLgvc@cuZ<^$IN4ywb!q$C@~I zw2AYCH7RVsy~J|vC1}tOGBaB+r!UjJD8oL@=w95VMqyxU!mzvG66Vs&jTFoJ5*w`U zKuzf10++!|>-jcAoMsiL<2cgLA{^mcjTadvx(V-0UzlIT@Z5Z#wt~B$g;M@O!F$z& zRew(U7SasjKSVK(1M)TSs1bbCvE1`LNwNIz*P(n$>BYlIi(H57);xCrH){f_{M*=eOL2|ib>jT z)#DMkj>#Z9kqk*AL;va0;3a)U(M^iK3Q0*evAbj;UC|qml79+T?IqL$xelYLC0WZL zTB~AGZ~ Date: Sat, 25 Apr 2026 12:29:41 -0700 Subject: [PATCH 09/10] Restore raw_syscall3/mincore probe in rtld_audit parse_object can be called on binaries without mapped trampolines (e.g. vdso, non-PIE main). The mincore probe safely detects this case. The raw syscall instruction is needed because syscall_entry may not be initialized yet at probe time. --- litebox_rtld_audit/rtld_audit.c | 30 +++++++++++++++--- .../tests/test-bins/litebox_rtld_audit.so | Bin 14288 -> 14328 bytes 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/litebox_rtld_audit/rtld_audit.c b/litebox_rtld_audit/rtld_audit.c index 8af458f30..7bec7e9ee 100644 --- a/litebox_rtld_audit/rtld_audit.c +++ b/litebox_rtld_audit/rtld_audit.c @@ -180,10 +180,24 @@ void print_hex(uint64_t data) { /// The entry point is at offset 0 of the mapped trampoline. The litebox loader /// already validated the magic when parsing the file header. /// -/// This is only called for the main binary and the interpreter, both of which -/// are expected to contain syscall instructions (and thus have a mapped -/// trampoline region). Binaries with no syscalls (trampoline_size=0 sentinel) -/// are not expected here. +/// For binaries processed by the rewriter but containing no syscall instructions +/// (trampoline_size=0 sentinel), no trampoline pages are mapped. We detect this +/// by probing the expected address with `mincore` via a raw syscall. +static long raw_syscall3(long num, long a1, long a2, long a3) { + long ret; + register long r10 __asm__("r10") = 0; + register long r8 __asm__("r8") = 0; + register long r9 __asm__("r9") = 0; + __asm__ volatile("syscall" + : "=a"(ret) + : "0"(num), "D"(a1), "S"(a2), "d"(a3), + "r"(r10), "r"(r8), "r"(r9) + : "rcx", "r11", "memory"); + return ret; +} + +#define SYS_mincore 27 + int parse_object(const struct link_map *map) { unsigned long max_addr = 0; Elf64_Ehdr *eh = (Elf64_Ehdr *)map->l_addr; @@ -210,6 +224,14 @@ int parse_object(const struct link_map *map) { max_addr = align_up(max_addr, 0x1000); void *trampoline_addr = (void *)map->l_addr + max_addr; + // Check if the trampoline page is mapped. Binaries with no syscall + // instructions have a size=0 sentinel header and no trampoline pages. + unsigned char vec; + if (raw_syscall3(SYS_mincore, (long)trampoline_addr, 0x1000, (long)&vec) < 0) { + syscall_print("[audit] no trampoline page mapped\n", 34); + return 1; + } + // The trampoline code has the syscall entry point at offset 0. syscall_entry = (syscall_stub_t)read_u64(trampoline_addr); if (syscall_entry == 0) { diff --git a/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so b/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so index e84b58e4d0073de1c809330dccd8231c5203119a..3222d1484b2422b8f59aec1da2ebe44fcd3bb102 100755 GIT binary patch delta 1012 zcmZ9LZAepL6vvaNS1E z1HD605%wW4?uRfxI5OM(HX*_!$oh2sP)#kECfv^5y+QQAeSYWs&;L9R_grqwpYV^D z(#xSe{!G7`B$r6@6I%X|;gb{MgK2tG-_gIsFU;)YW}J(W&lY`AjZeG< zZH$l3!va&s5Cfm7@@S|Rj_VH4KA6yL(h%Ip%OC6wvq8`7YyqD3nrI0TA{ep538D!~ zmq*;&6tP+>sa$_pNXL{7q#P}mT(yk|q8a_ynU{3d+OZ-W+!jSV0Tsfzx7p#h-cxg( zofR6(h$N9_HUJxWosEIsI2&jd*nnq+jkse{2^m!wPLgvc@cuZ<^$IN4ywb!q$C@~I zw2AYCH7RVsy~J|vC1}tOGBaB+r!UjJD8oL@=w95VMqyxU!mzvG66Vs&jTFoJ5*w`U zKuzf10++!|>-jcAoMsiL<2cgLA{^mcjTadvx(V-0UzlIT@Z5Z#wt~B$g;M@O!F$z& zRew(U7SasjKSVK(1M)TSs1bbCvE1`LNwNIz*P(n$>BYlIi(H57);xCrH){f_{M*=eOL2|ib>jT z)#DMkj>#Z9kqk*AL;va0;3a)U(M^iK3Q0*evAbj;UC|qml79+T?IqL$xelYLC0WZL zTB~AGZ~C~Jtmym6if)#;~NQ8pIf;|*!l+=SJs6koe zJTDUo)CeL7f{UO&83`FZq)=iJ=$@PqwycNM24CmiYvF-=f9IV4|N9R2+*J2U_m~G- zqGjEN4I@)y!x){ZGGsujG7$Z;mJ`+r7RGsaEY=3!Pp(JT%0D>H$S;?gZq40Xn8$YE z8pQCO5EObu*`T{FtLrbBKH&`h4;-O;~S!+ zTBk^lVBB>?AEr#&kqsp~Ci;AjoT_>bWl7~1QM77chlv8qVlAT9P{&g0#(1?Y$G@ja z2tKzxL>18bQl}}|7w53SXS26c2bhT^g8L*&Z(uK}{ghdhITlS-mq6(Qoc7sZ9DO<) zOyH_uD|x!-Oy+COJ`L=}UcW~~LrtaJSknvg+=(d=?i%rme*nVx*?;`dZAr8L Date: Sat, 25 Apr 2026 14:31:27 -0700 Subject: [PATCH 10/10] Remove raw_syscall3/mincore probe from rtld_audit The raw syscall instruction breaks on Windows. This will be fully resolved when runtime patching (PR4) lands and removes rtld_audit. --- litebox_rtld_audit/rtld_audit.c | 28 ------------------ .../tests/test-bins/litebox_rtld_audit.so | Bin 14328 -> 14288 bytes 2 files changed, 28 deletions(-) diff --git a/litebox_rtld_audit/rtld_audit.c b/litebox_rtld_audit/rtld_audit.c index 7bec7e9ee..7d05c26a7 100644 --- a/litebox_rtld_audit/rtld_audit.c +++ b/litebox_rtld_audit/rtld_audit.c @@ -179,25 +179,6 @@ void print_hex(uint64_t data) { /// The trampoline is already mapped by the litebox loader at (base + vaddr). /// The entry point is at offset 0 of the mapped trampoline. The litebox loader /// already validated the magic when parsing the file header. -/// -/// For binaries processed by the rewriter but containing no syscall instructions -/// (trampoline_size=0 sentinel), no trampoline pages are mapped. We detect this -/// by probing the expected address with `mincore` via a raw syscall. -static long raw_syscall3(long num, long a1, long a2, long a3) { - long ret; - register long r10 __asm__("r10") = 0; - register long r8 __asm__("r8") = 0; - register long r9 __asm__("r9") = 0; - __asm__ volatile("syscall" - : "=a"(ret) - : "0"(num), "D"(a1), "S"(a2), "d"(a3), - "r"(r10), "r"(r8), "r"(r9) - : "rcx", "r11", "memory"); - return ret; -} - -#define SYS_mincore 27 - int parse_object(const struct link_map *map) { unsigned long max_addr = 0; Elf64_Ehdr *eh = (Elf64_Ehdr *)map->l_addr; @@ -223,15 +204,6 @@ int parse_object(const struct link_map *map) { } max_addr = align_up(max_addr, 0x1000); void *trampoline_addr = (void *)map->l_addr + max_addr; - - // Check if the trampoline page is mapped. Binaries with no syscall - // instructions have a size=0 sentinel header and no trampoline pages. - unsigned char vec; - if (raw_syscall3(SYS_mincore, (long)trampoline_addr, 0x1000, (long)&vec) < 0) { - syscall_print("[audit] no trampoline page mapped\n", 34); - return 1; - } - // The trampoline code has the syscall entry point at offset 0. syscall_entry = (syscall_stub_t)read_u64(trampoline_addr); if (syscall_entry == 0) { diff --git a/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so b/litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so index 3222d1484b2422b8f59aec1da2ebe44fcd3bb102..e84b58e4d0073de1c809330dccd8231c5203119a 100755 GIT binary patch delta 849 zcmYk3QAkr^6vw}FS5vp?Y~C@aqup7#>C~Jtmym6if)#;~NQ8pIf;|*!l+=SJs6koe zJTDUo)CeL7f{UO&83`FZq)=iJ=$@PqwycNM24CmiYvF-=f9IV4|N9R2+*J2U_m~G- zqGjEN4I@)y!x){ZGGsujG7$Z;mJ`+r7RGsaEY=3!Pp(JT%0D>H$S;?gZq40Xn8$YE z8pQCO5EObu*`T{FtLrbBKH&`h4;-O;~S!+ zTBk^lVBB>?AEr#&kqsp~Ci;AjoT_>bWl7~1QM77chlv8qVlAT9P{&g0#(1?Y$G@ja z2tKzxL>18bQl}}|7w53SXS26c2bhT^g8L*&Z(uK}{ghdhITlS-mq6(Qoc7sZ9DO<) zOyH_uD|x!-Oy+COJ`L=}UcW~~LrtaJSknvg+=(d=?i%rme*nVx*?;`dZAr8LaNS1E z1HD605%wW4?uRfxI5OM(HX*_!$oh2sP)#kECfv^5y+QQAeSYWs&;L9R_grqwpYV^D z(#xSe{!G7`B$r6@6I%X|;gb{MgK2tG-_gIsFU;)YW}J(W&lY`AjZeG< zZH$l3!va&s5Cfm7@@S|Rj_VH4KA6yL(h%Ip%OC6wvq8`7YyqD3nrI0TA{ep538D!~ zmq*;&6tP+>sa$_pNXL{7q#P}mT(yk|q8a_ynU{3d+OZ-W+!jSV0Tsfzx7p#h-cxg( zofR6(h$N9_HUJxWosEIsI2&jd*nnq+jkse{2^m!wPLgvc@cuZ<^$IN4ywb!q$C@~I zw2AYCH7RVsy~J|vC1}tOGBaB+r!UjJD8oL@=w95VMqyxU!mzvG66Vs&jTFoJ5*w`U zKuzf10++!|>-jcAoMsiL<2cgLA{^mcjTadvx(V-0UzlIT@Z5Z#wt~B$g;M@O!F$z& zRew(U7SasjKSVK(1M)TSs1bbCvE1`LNwNIz*P(n$>BYlIi(H57);xCrH){f_{M*=eOL2|ib>jT z)#DMkj>#Z9kqk*AL;va0;3a)U(M^iK3Q0*evAbj;UC|qml79+T?IqL$xelYLC0WZL zTB~AGZ~