From 0dc108639862d7380e4f9d30472a8cf57bac50d3 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Fri, 24 Apr 2026 19:19:27 -0700 Subject: [PATCH 1/8] 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 | 2 +- litebox_platform_linux_userland/src/lib.rs | 39 +++- litebox_platform_windows_userland/src/lib.rs | 46 +++- litebox_syscall_rewriter/src/lib.rs | 82 ++++++- .../snapshots/snapshot_tests__hello-diff.snap | 217 +++++++++--------- 5 files changed, 248 insertions(+), 138 deletions(-) diff --git a/litebox_common_linux/src/loader.rs b/litebox_common_linux/src/loader.rs index c61bfc78b2..931019dede 100644 --- a/litebox_common_linux/src/loader.rs +++ b/litebox_common_linux/src/loader.rs @@ -616,7 +616,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_platform_linux_userland/src/lib.rs b/litebox_platform_linux_userland/src/lib.rs index a1ccf7fdcf..8587861ef0 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 3962825449..a6b04257d7 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_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index 13c3df910a..a340b01287 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -163,7 +163,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:?}"), }; @@ -191,6 +193,7 @@ pub fn hook_syscalls_in_elf(input_binary: &[u8], trampoline: Option) -> Res trampoline_data.extend_from_slice(&trampoline.to_le_bytes()); // 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( @@ -202,13 +205,34 @@ pub fn hook_syscalls_in_elf(input_binary: &[u8], trampoline: Option) -> Res trampoline_base_addr, // entry point is at offset 0 of trampoline &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; @@ -293,7 +317,8 @@ fn is_already_hooked(input_binary: &[u8], arch: Arch) -> bool { (header.file_offset, header.vaddr, header.trampoline_size); 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; @@ -431,6 +456,8 @@ fn hook_syscalls_in_section( trampoline_data.extend_from_slice(&presyscall_bytes); let return_addr = inst.next_ip(); + 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, @@ -538,8 +565,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 @@ -630,6 +657,42 @@ fn checked_add_u64(base: u64, addend: u64, context: &'static str) -> Result .ok_or_else(|| Error::AddressOverflow(format!("{context} address overflow"))) } +/// 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(|_| { @@ -914,8 +977,12 @@ fn hook_syscall_and_after( // Compute preamble size so we can determine where post-syscall // instructions will land and encode them before committing anything. - // x86_64: LEA RCX,[RIP+disp32] (7) + JMP [RIP+disp32] (6) = 13 - let preamble_len: u64 = 13; + // x86_64 preamble: + // LEA RSP,[RSP-0x80] (5) + // LEA R11,[RIP+disp32] (7) + // LEA RCX,[RIP+disp32] (7) + // JMP [RIP+disp32] (6) + let preamble_len: u64 = 25; // Encode the post-syscall instructions for the trampoline, re-encoding // any RIP-relative memory operands for the new location. @@ -932,6 +999,7 @@ fn hook_syscall_and_after( } else { Vec::new() }; + 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] 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 9f933eb4d9..e13332c63d 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 14a3db8e242cbf6071690ab34780ee22b7ed6e06 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 11:37:44 -0700 Subject: [PATCH 2/8] Fix size=0 sentinel comments to accurately describe semantics --- litebox_common_linux/src/loader.rs | 4 ++-- litebox_syscall_rewriter/src/lib.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/litebox_common_linux/src/loader.rs b/litebox_common_linux/src/loader.rs index 931019dede..3d6f60a7b0 100644 --- a/litebox_common_linux/src/loader.rs +++ b/litebox_common_linux/src/loader.rs @@ -300,8 +300,8 @@ impl ElfParsedFile { ) }; - // trampoline_size == 0 means the rewriter checked this binary and found - // no syscall instructions. + // 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(()); } diff --git a/litebox_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index a340b01287..21f7311d5d 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -317,7 +317,8 @@ fn is_already_hooked(input_binary: &[u8], arch: Arch) -> bool { (header.file_offset, header.vaddr, header.trampoline_size); 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 { From e2093dd620003f2e4ada3fd08fd2b70b554b286b Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 11:53:11 -0700 Subject: [PATCH 3/8] 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 3d6f60a7b0..7bc41a2fa1 100644 --- a/litebox_common_linux/src/loader.rs +++ b/litebox_common_linux/src/loader.rs @@ -616,7 +616,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 f3c3f912e2eeee377a24af31a3743b4cdceba8cb Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 11:57:30 -0700 Subject: [PATCH 4/8] Fix Windows test: rewrite litebox_rtld_audit.so to get new trampoline format --- litebox_runner_linux_on_windows_userland/tests/loader.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/litebox_runner_linux_on_windows_userland/tests/loader.rs b/litebox_runner_linux_on_windows_userland/tests/loader.rs index 1a0849aefc..0d427fd4f4 100644 --- a/litebox_runner_linux_on_windows_userland/tests/loader.rs +++ b/litebox_runner_linux_on_windows_userland/tests/loader.rs @@ -342,6 +342,7 @@ 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"), ]; // Run run_dynamic_linked_prog_with_rewriter(&libs_to_rewrite, exec_name, &[], |_| {}); From 597a75c0b771116c40f0a522cc0e5520ede8027e Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Sat, 25 Apr 2026 12:06:07 -0700 Subject: [PATCH 5/8] 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 f0a5e06586260ad7d1ca0031657ec61e087dc21e Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Wed, 6 May 2026 21:45:29 -0700 Subject: [PATCH 6/8] Address trampoline review feedback --- litebox_platform_windows_userland/src/lib.rs | 28 ++++++++++++------ .../tests/loader.rs | 1 - .../tests/test-bins/litebox_rtld_audit.so | Bin 16453 -> 14480 bytes litebox_syscall_rewriter/src/lib.rs | 20 +++++++++++-- 4 files changed, 37 insertions(+), 12 deletions(-) mode change 100755 => 100644 litebox_runner_linux_on_windows_userland/tests/test-bins/litebox_rtld_audit.so diff --git a/litebox_platform_windows_userland/src/lib.rs b/litebox_platform_windows_userland/src/lib.rs index a6b04257d7..e10dc172d0 100644 --- a/litebox_platform_windows_userland/src/lib.rs +++ b/litebox_platform_windows_userland/src/lib.rs @@ -414,6 +414,8 @@ struct TlsState { host_bp: Cell<*mut u128>, guest_context_top: Cell<*mut litebox_common_linux::PtRegs>, scratch: Cell, + scratch2: Cell, + teb_arbitrary_user_pointer: 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). @@ -437,6 +439,8 @@ impl TlsState { host_bp: Cell::new(core::ptr::null_mut()), guest_context_top: core::ptr::null_mut::().into(), scratch: 0.into(), + scratch2: 0.into(), + teb_arbitrary_user_pointer: 0.into(), saved_restart_addr: 0.into(), is_in_guest: false.into(), interrupt: false.into(), @@ -549,6 +553,8 @@ unsafe extern "C-unwind" fn run_thread_arch(thread_ctx: &mut ThreadContext, tls_ // Save the host rsp and rbp into the TLS state. mov QWORD PTR [rdx + {HOST_SP}], rsp mov QWORD PTR [rdx + {HOST_BP}], rbp + mov rax, QWORD PTR gs:[0x28] + mov QWORD PTR [rdx + {TEB_ARBITRARY_USER_POINTER}], rax call {init_handler} jmp .Ldone @@ -564,20 +570,22 @@ unsafe extern "C-unwind" fn run_thread_arch(thread_ctx: &mut ThreadContext, tls_ 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. + // clobbers R11. This slot is per-thread and the window is very narrow: + // only inline asm with no API calls, Rust code, or DLL activity. 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 - // 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 restart address from the TEB slot and store it in TLS + // without touching the guest stack. RAX is saved in a dedicated TLS + // scratch slot for this tiny window, then restored before pt_regs capture. + mov QWORD PTR [r11 + {SCRATCH2}], rax + mov rax, QWORD PTR gs:[0x28] + mov QWORD PTR [r11 + {SAVED_RESTART_ADDR}], rax + mov rax, QWORD PTR [r11 + {TEB_ARBITRARY_USER_POINTER}] + mov QWORD PTR gs:[0x28], rax + mov rax, QWORD PTR [r11 + {SCRATCH2}] // 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. @@ -669,6 +677,8 @@ 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), + SCRATCH2 = const core::mem::offset_of!(TlsState, scratch2), + TEB_ARBITRARY_USER_POINTER = const core::mem::offset_of!(TlsState, teb_arbitrary_user_pointer), SAVED_RESTART_ADDR = const core::mem::offset_of!(TlsState, saved_restart_addr), IS_IN_GUEST = const core::mem::offset_of!(TlsState, is_in_guest), ); diff --git a/litebox_runner_linux_on_windows_userland/tests/loader.rs b/litebox_runner_linux_on_windows_userland/tests/loader.rs index 0d427fd4f4..1a0849aefc 100644 --- a/litebox_runner_linux_on_windows_userland/tests/loader.rs +++ b/litebox_runner_linux_on_windows_userland/tests/loader.rs @@ -342,7 +342,6 @@ 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"), ]; // Run run_dynamic_linked_prog_with_rewriter(&libs_to_rewrite, exec_name, &[], |_| {}); 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 100755 new mode 100644 index b51bb34f379b8e55de14af8957720702d68d6993..66e3687ee7123e5078d29c6187bfa7d0671b23be GIT binary patch literal 14480 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 I1-0A%9o;rSZU6uP literal 16453 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 TgD-W)kohDs&4S`U5HJ4#5}~PB diff --git a/litebox_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index 21f7311d5d..7f35715382 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -688,9 +688,12 @@ fn emit_trampoline_preamble( 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())); + trampoline_data.extend_from_slice(&rel32_bytes( + call_site_addr, + r11_rip, + "trampoline R11 restart address", + )?); Ok(()) } @@ -1053,3 +1056,16 @@ fn hook_syscall_and_after( Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn trampoline_preamble_reports_out_of_range_r11_displacement() { + let mut trampoline_data = Vec::new(); + let result = emit_trampoline_preamble(0x8000_0000, 0, &mut trampoline_data); + + assert!(matches!(result, Err(Error::AddressOverflow(_)))); + } +} From 0514bf3f09741fec5e7f941452395903c780cb0b Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Thu, 7 May 2026 11:02:23 -0700 Subject: [PATCH 7/8] Address trampoline callback review feedback --- litebox_common_linux/src/loader.rs | 4 +-- litebox_platform_linux_userland/src/lib.rs | 19 ++++------ litebox_platform_windows_userland/src/lib.rs | 38 ++++++++------------ litebox_syscall_rewriter/src/lib.rs | 19 ++-------- 4 files changed, 25 insertions(+), 55 deletions(-) diff --git a/litebox_common_linux/src/loader.rs b/litebox_common_linux/src/loader.rs index 7bc41a2fa1..c61bfc78b2 100644 --- a/litebox_common_linux/src/loader.rs +++ b/litebox_common_linux/src/loader.rs @@ -300,8 +300,8 @@ impl ElfParsedFile { ) }; - // Size=0 sentinel: the rewriter processed this binary but found no - // syscall instructions, so there is no trampoline region to map. + // trampoline_size == 0 means the rewriter checked this binary and found + // no syscall instructions. if trampoline_size == 0 { return Ok(()); } diff --git a/litebox_platform_linux_userland/src/lib.rs b/litebox_platform_linux_userland/src/lib.rs index 8587861ef0..8972d55cb3 100644 --- a/litebox_platform_linux_userland/src/lib.rs +++ b/litebox_platform_linux_userland/src/lib.rs @@ -565,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 the syscall callback. This code then updates the guest +/// this routine, at `syscall_callback`. This code then updates the guest /// context structure, switches back to the host stack, and calls the syscall /// handler. /// @@ -618,8 +618,8 @@ 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_redzone -syscall_callback_redzone: + .globl syscall_callback +syscall_callback: // 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 @@ -825,7 +825,7 @@ fn thread_start( let shim = init_thread.init(); run_thread_inner(shim.as_ref(), &mut ctx, false); - // TODO: have the syscall callback return if we need to terminate the process. + // TODO: have 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. } @@ -1598,8 +1598,7 @@ impl litebox::platform::StdioProvider for LinuxUserland { unsafe extern "C" { // Defined in asm blocks above - #[cfg(target_arch = "x86_64")] - fn syscall_callback_redzone() -> isize; + fn syscall_callback() -> isize; fn exception_callback(); fn interrupt_callback(); fn switch_to_guest_start(); @@ -1680,10 +1679,7 @@ impl ThreadContext<'_> { impl litebox::platform::SystemInfoProvider for LinuxUserland { fn get_syscall_entry_point(&self) -> usize { - #[cfg(target_arch = "x86_64")] - { - syscall_callback_redzone as *const () as usize - } + syscall_callback as *const () as usize } fn get_vdso_address(&self) -> Option { @@ -2204,8 +2200,7 @@ 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. - #[cfg(target_arch = "x86_64")] - if ip == syscall_callback_redzone as *const () as usize { + if ip == syscall_callback 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 e10dc172d0..64c0cd89ac 100644 --- a/litebox_platform_windows_userland/src/lib.rs +++ b/litebox_platform_windows_userland/src/lib.rs @@ -414,8 +414,6 @@ struct TlsState { host_bp: Cell<*mut u128>, guest_context_top: Cell<*mut litebox_common_linux::PtRegs>, scratch: Cell, - scratch2: Cell, - teb_arbitrary_user_pointer: 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). @@ -439,8 +437,6 @@ impl TlsState { host_bp: Cell::new(core::ptr::null_mut()), guest_context_top: core::ptr::null_mut::().into(), scratch: 0.into(), - scratch2: 0.into(), - teb_arbitrary_user_pointer: 0.into(), saved_restart_addr: 0.into(), is_in_guest: false.into(), interrupt: false.into(), @@ -489,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 the syscall callback. This code then updates the guest +/// this routine, at `syscall_callback`. This code then updates the guest /// context structure, switches back to the host stack, and calls the syscall /// handler. /// @@ -553,8 +549,6 @@ unsafe extern "C-unwind" fn run_thread_arch(thread_ctx: &mut ThreadContext, tls_ // Save the host rsp and rbp into the TLS state. mov QWORD PTR [rdx + {HOST_SP}], rsp mov QWORD PTR [rdx + {HOST_BP}], rbp - mov rax, QWORD PTR gs:[0x28] - mov QWORD PTR [rdx + {TEB_ARBITRARY_USER_POINTER}], rax call {init_handler} jmp .Ldone @@ -566,33 +560,31 @@ unsafe extern "C-unwind" fn run_thread_arch(thread_ctx: &mut ThreadContext, tls_ // 3. Loaded the return address into RCX // // All other registers hold guest state. - .globl syscall_callback_redzone -syscall_callback_redzone: + .globl syscall_callback +syscall_callback: // 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 inline asm with no API calls, Rust code, or DLL activity. + // clobbers R11. Windows has no direct equivalent of Linux's TLS-relative + // store before TLS lookup, so this per-thread TEB slot is used as the + // narrow pre-TLS scratch location. No calls, Rust code, or DLL activity + // occur before the value is copied into TlsState below. 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 // Recover the restart address from the TEB slot and store it in TLS - // without touching the guest stack. RAX is saved in a dedicated TLS - // scratch slot for this tiny window, then restored before pt_regs capture. - mov QWORD PTR [r11 + {SCRATCH2}], rax + // without touching the guest stack. SCRATCH is reused below for the + // recovered guest RSP after RAX has been restored. + mov QWORD PTR [r11 + {SCRATCH}], rax mov rax, QWORD PTR gs:[0x28] mov QWORD PTR [r11 + {SAVED_RESTART_ADDR}], rax - mov rax, QWORD PTR [r11 + {TEB_ARBITRARY_USER_POINTER}] - mov QWORD PTR gs:[0x28], rax - mov rax, QWORD PTR [r11 + {SCRATCH2}] + mov rax, QWORD PTR [r11 + {SCRATCH}] // 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) @@ -612,7 +604,7 @@ syscall_callback_redzone: push r8 // pt_regs->r8 push r9 // pt_regs->r9 push r10 // pt_regs->r10 - push [rsp + 88] // pt_regs->r11 = rflags (matching real syscall ABI) + push [rsp + 88] // pt_regs->r11 = rflags push rbx // pt_regs->bx push rbp // pt_regs->bp push r12 @@ -677,8 +669,6 @@ 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), - SCRATCH2 = const core::mem::offset_of!(TlsState, scratch2), - TEB_ARBITRARY_USER_POINTER = const core::mem::offset_of!(TlsState, teb_arbitrary_user_pointer), SAVED_RESTART_ADDR = const core::mem::offset_of!(TlsState, saved_restart_addr), IS_IN_GUEST = const core::mem::offset_of!(TlsState, is_in_guest), ); @@ -1972,7 +1962,7 @@ impl litebox::mm::allocator::MemoryProvider for WindowsUserland { unsafe extern "C" { // Defined in asm blocks above - fn syscall_callback_redzone() -> isize; + fn syscall_callback() -> isize; fn exception_callback() -> isize; fn interrupt_callback(); fn switch_to_guest_start(); @@ -2062,7 +2052,7 @@ impl ThreadContext<'_> { impl litebox::platform::SystemInfoProvider for WindowsUserland { fn get_syscall_entry_point(&self) -> usize { - syscall_callback_redzone as *const () as usize + syscall_callback as *const () as usize } fn get_vdso_address(&self) -> Option { diff --git a/litebox_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index 7f35715382..1fc4636a0d 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -163,9 +163,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:?}"), }; @@ -221,7 +219,7 @@ pub fn hook_syscalls_in_elf(input_binary: &[u8], trampoline: Option) -> Res // "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. + // alignment fixup that is only needed for the `object` crate parser. let mut out = input_binary.to_vec(); let header = TrampolineHeader64 { magic: *TRAMPOLINE_MAGIC, @@ -1056,16 +1054,3 @@ fn hook_syscall_and_after( Ok(()) } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn trampoline_preamble_reports_out_of_range_r11_displacement() { - let mut trampoline_data = Vec::new(); - let result = emit_trampoline_preamble(0x8000_0000, 0, &mut trampoline_data); - - assert!(matches!(result, Err(Error::AddressOverflow(_)))); - } -} From 9faf56b0b56c6a27018f0f228c9f8e098a5177b3 Mon Sep 17 00:00:00 2001 From: Weidong Cui Date: Mon, 11 May 2026 15:47:48 -0700 Subject: [PATCH 8/8] Drop R11 restart address and red zone preamble; unify RCX as in-trampoline anchor Per CvvT's review: the R11 restart-address load and the SysV red zone preamble exist to support each other (the Windows callback's R11 shuttle was the only thing that wrote to the guest stack pre-stack-switch, and the red zone reservation existed to protect against that shuttle). Replace the scheme so every stub satisfies: pt_regs.rcx - 6 == address of JMP [syscall_entry_slot] RCX uniformly points at the in-trampoline `post_jmp`, which is now a 5-byte `JMP rel32 -> guest_text` tail in every stub. The callback's `jmp rcx` return path lands at post_jmp and falls through to guest text. The SA_RESTART handler can rewind ctx.rip with a single subtract, with no per-variant layout knowledge. Drops, both platforms: - saved_restart_addr TLS slot - Windows TEB-slot shuttle (mov gs:[0x28], r11; etc.) - lea r11, [rsp+128] architectural-RSP recovery - LEA RSP, [RSP-0x80] red zone preamble - LEA R11, [RIP+disp32] restart-address load The post_jmp tail adds 5 bytes per stub. Net: -7 bytes per stub vs. the prior approach, with the SA_RESTART invariant baked in for free. Snapshot regenerated to reflect the new 18-byte-per-stub layout. Co-Authored-By: Claude Opus 4.7 (1M context) --- litebox_platform_linux_userland/src/lib.rs | 20 +- litebox_platform_windows_userland/src/lib.rs | 34 +-- litebox_syscall_rewriter/src/lib.rs | 89 +++----- .../snapshots/snapshot_tests__hello-diff.snap | 216 +++++++++--------- 4 files changed, 143 insertions(+), 216 deletions(-) diff --git a/litebox_platform_linux_userland/src/lib.rs b/litebox_platform_linux_userland/src/lib.rs index 8972d55cb3..a1ccf7fdcf 100644 --- a/litebox_platform_linux_userland/src/lib.rs +++ b/litebox_platform_linux_userland/src/lib.rs @@ -508,8 +508,6 @@ core::arch::global_asm!( " .section .tbss .align 8 -saved_restart_addr: - .quad 0 scratch: .quad 0 host_sp: @@ -620,32 +618,20 @@ unsafe extern "C-unwind" fn run_thread_arch( // contain rflags if the syscall instruction had actually been issued). .globl syscall_callback syscall_callback: - // 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 - // The trampoline lowered RSP by 128 bytes with LEA, so recover the - // architectural guest stack pointer before saving pt_regs. - lea r11, [rsp + 128] + // Switch to the top of the guest context. + mov r11, rsp 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 @@ -663,7 +649,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 (matching real syscall ABI) + push [rsp + 88] // pt_regs->r11 = rflags push rbx // pt_regs->bx push rbp // pt_regs->bp push r12 // pt_regs->r12 diff --git a/litebox_platform_windows_userland/src/lib.rs b/litebox_platform_windows_userland/src/lib.rs index 64c0cd89ac..3962825449 100644 --- a/litebox_platform_windows_userland/src/lib.rs +++ b/litebox_platform_windows_userland/src/lib.rs @@ -414,10 +414,6 @@ 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: @@ -437,7 +433,6 @@ 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(), @@ -554,36 +549,18 @@ 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. 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 + // instruction. // - // All other registers hold guest state. + // 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: - // Save guest R11 (restart address from rewriter trampoline) to - // TEB.ArbitraryUserPointer (gs:[0x28]) before the TLS index lookup - // clobbers R11. Windows has no direct equivalent of Linux's TLS-relative - // store before TLS lookup, so this per-thread TEB slot is used as the - // narrow pre-TLS scratch location. No calls, Rust code, or DLL activity - // occur before the value is copied into TlsState below. - 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 - // Recover the restart address from the TEB slot and store it in TLS - // without touching the guest stack. SCRATCH is reused below for the - // recovered guest RSP after RAX has been restored. - mov QWORD PTR [r11 + {SCRATCH}], rax - mov rax, QWORD PTR gs:[0x28] - mov QWORD PTR [r11 + {SAVED_RESTART_ADDR}], rax - mov rax, QWORD PTR [r11 + {SCRATCH}] - // 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] + // Set rsp to the top of the guest context. mov QWORD PTR [r11 + {SCRATCH}], rsp mov rsp, QWORD PTR [r11 + {GUEST_CONTEXT_TOP}] @@ -669,7 +646,6 @@ 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), ); } diff --git a/litebox_syscall_rewriter/src/lib.rs b/litebox_syscall_rewriter/src/lib.rs index 1fc4636a0d..c1bb12b917 100644 --- a/litebox_syscall_rewriter/src/lib.rs +++ b/litebox_syscall_rewriter/src/lib.rs @@ -455,20 +455,13 @@ fn hook_syscalls_in_section( trampoline_data.extend_from_slice(&presyscall_bytes); let return_addr = inst.next_ip(); - 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, - trampoline_data.len() as u64 + 7, - "x86_64 trampoline jump-back base", - )?; - trampoline_data.extend_from_slice(&[0x48, 0x8D, 0x0D]); // LEA RCX, [RIP + disp32] - trampoline_data.extend_from_slice(&rel32_bytes( - return_addr, - jmp_back_base, - "x86_64 trampoline jump-back", - )?); + // LEA RCX, [RIP + 6] — load RCX with the address of the in-trampoline + // `post_jmp` (the instruction immediately after the indirect JMP into + // the callback). The SA_RESTART handler relies on the invariant that + // pt_regs.rcx - 6 points at the indirect JMP itself, so it can rewind + // ctx.rip and re-enter the callback. + trampoline_data.extend_from_slice(&[0x48, 0x8D, 0x0D, 0x06, 0x00, 0x00, 0x00]); // Add jmp [rip + offset_to_entry_point] trampoline_data.extend_from_slice(&[0xFF, 0x25]); @@ -485,6 +478,20 @@ fn hook_syscalls_in_section( "x86_64 trampoline entry", )?); + // post_jmp: JMP rel32 back to the guest instruction following the + // original syscall. The callback returns via `jmp rcx` and lands here. + let jmp_back_base = checked_add_u64( + trampoline_base_addr, + trampoline_data.len() as u64 + 5, + "x86_64 trampoline jump-back base", + )?; + trampoline_data.push(0xE9); + trampoline_data.extend_from_slice(&rel32_bytes( + return_addr, + jmp_back_base, + "x86_64 trampoline jump-back", + )?); + // Replace original instructions with jump to trampoline let replace_offset = usize::try_from(replace_start - section_base_addr).unwrap(); section_data[replace_offset] = 0xE9; // JMP rel32 @@ -656,45 +663,6 @@ fn checked_add_u64(base: u64, addend: u64, context: &'static str) -> Result .ok_or_else(|| Error::AddressOverflow(format!("{context} address overflow"))) } -/// 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", - )?; - trampoline_data.extend_from_slice(&[0x4C, 0x8D, 0x1D]); - trampoline_data.extend_from_slice(&rel32_bytes( - call_site_addr, - r11_rip, - "trampoline R11 restart address", - )?); - 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(|_| { @@ -979,12 +947,8 @@ fn hook_syscall_and_after( // Compute preamble size so we can determine where post-syscall // instructions will land and encode them before committing anything. - // x86_64 preamble: - // LEA RSP,[RSP-0x80] (5) - // LEA R11,[RIP+disp32] (7) - // LEA RCX,[RIP+disp32] (7) - // JMP [RIP+disp32] (6) - let preamble_len: u64 = 25; + // x86_64: LEA RCX,[RIP+disp32] (7) + JMP [RIP+disp32] (6) = 13 + let preamble_len: u64 = 13; // Encode the post-syscall instructions for the trampoline, re-encoding // any RIP-relative memory operands for the new location. @@ -1001,11 +965,12 @@ fn hook_syscall_and_after( } else { Vec::new() }; - 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()); + // LEA RCX, [RIP + 6] — make RCX point at the instruction immediately + // following the indirect JMP: the start of postsyscall_bytes (or, when + // none, the unconditional JMP back to guest). The SA_RESTART handler + // relies on pt_regs.rcx - 6 pointing at the indirect JMP itself. + trampoline_data.extend_from_slice(&[0x48, 0x8D, 0x0D, 0x06, 0x00, 0x00, 0x00]); // Add jmp [rip + offset_to_entry_point] trampoline_data.extend_from_slice(&[0xFF, 0x25]); // RIP after this instruction = trampoline_base_addr + trampoline_data.len() + 4 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 e13332c63d..5c41cdaaad 100644 --- a/litebox_syscall_rewriter/tests/snapshots/snapshot_tests__hello-diff.snap +++ b/litebox_syscall_rewriter/tests/snapshots/snapshot_tests__hello-diff.snap @@ -23,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 @@ -34,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 @@ -46,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> @@ -55,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 @@ -63,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> @@ -75,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 @@ -83,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> @@ -95,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 @@ -105,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 @@ -117,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> @@ -128,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 @@ -140,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 @@ -152,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 @@ -164,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 @@ -176,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 @@ -189,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 @@ -201,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 @@ -213,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 @@ -225,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 @@ -237,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 @@ -249,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 @@ -261,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 @@ -274,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 @@ -287,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> @@ -299,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 @@ -311,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 @@ -323,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 @@ -335,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> @@ -346,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 @@ -358,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 @@ -370,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 @@ -382,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 @@ -394,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 @@ -406,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 @@ -416,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 @@ -428,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) @@ -440,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 @@ -454,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 @@ -466,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 @@ -478,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> @@ -490,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 @@ -505,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 @@ -524,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 @@ -536,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 @@ -548,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 @@ -560,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 @@ -571,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 @@ -581,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 @@ -593,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 @@ -607,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 @@ -619,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 @@ -629,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 @@ -639,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 @@ -651,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 @@ -664,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 @@ -676,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 @@ -688,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> @@ -699,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 @@ -711,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 @@ -723,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 @@ -735,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 @@ -747,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 @@ -759,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> @@ -770,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 @@ -782,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> @@ -793,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 @@ -805,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> @@ -816,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 @@ -828,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 @@ -840,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 @@ -852,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 @@ -864,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 @@ -876,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 @@ -888,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 @@ -900,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 @@ -912,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 @@ -924,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 @@ -936,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 @@ -948,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 @@ -960,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 @@ -972,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 @@ -984,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 @@ -996,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 @@ -1008,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 @@ -1020,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 @@ -1034,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 @@ -1046,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 @@ -1058,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 @@ -1070,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 @@ -1082,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 @@ -1094,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 @@ -1106,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 @@ -1119,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 @@ -1133,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> @@ -1145,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 @@ -1155,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 @@ -1165,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 @@ -1179,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 @@ -1191,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 @@ -1201,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 @@ -1211,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 @@ -1223,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 @@ -1235,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 @@ -1247,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 @@ -1259,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> @@ -1271,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) @@ -1283,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)