diff --git a/proxygen-macros/src/lib.rs b/proxygen-macros/src/lib.rs index ff2cd3c..c289bd0 100644 --- a/proxygen-macros/src/lib.rs +++ b/proxygen-macros/src/lib.rs @@ -70,6 +70,7 @@ impl From for ProxySignatureType { // Note: You may not have any instructions in the function body when forwarding function calls #[proc_macro_attribute] pub fn forward(_attr_input: TokenStream, item: TokenStream) -> TokenStream { + unsafe{ let input: ItemFn = syn::parse(item).expect("You may only proxy a function"); let func_name = input.sig.clone().ident; let func_body = input.block.stmts.clone(); @@ -112,7 +113,7 @@ pub fn forward(_attr_input: TokenStream, item: TokenStream) -> TokenStream { pub unsafe extern "C" fn #func_name() { #[cfg(target_arch = "x86_64")] { - std::arch::asm!( + std::arch::naked_asm!( "call {wait_dll_proxy_init}", "mov rax, qword ptr [rip + {ORIG_FUNCS_PTR}]", "add rax, {orig_index} * 8", @@ -122,13 +123,12 @@ pub fn forward(_attr_input: TokenStream, item: TokenStream) -> TokenStream { wait_dll_proxy_init = sym crate::wait_dll_proxy_init, ORIG_FUNCS_PTR = sym crate::ORIG_FUNCS_PTR, orig_index = const #orig_index_ident, - options(noreturn) ) } #[cfg(target_arch = "x86")] { - std::arch::asm!( + std::arch::naked_asm!( "call {wait_dll_proxy_init}", "mov eax, dword ptr [{ORIG_FUNCS_PTR}]", "add eax, {orig_index} * 4", @@ -138,11 +138,11 @@ pub fn forward(_attr_input: TokenStream, item: TokenStream) -> TokenStream { wait_dll_proxy_init = sym crate::wait_dll_proxy_init, ORIG_FUNCS_PTR = sym crate::ORIG_FUNCS_PTR, orig_index = const #orig_index_ident, - options(noreturn) ) } } )) + } } // Proc macro to bring the original function into the scope of an interceptor function as `orig_func` @@ -241,8 +241,6 @@ pub fn pre_hook(attr_input: TokenStream, item: TokenStream) -> TokenStream { let hook_func_name = syn::parse_str::(&format!("Proxygen_PreHook_{}", &func_name)).unwrap(); TokenStream::from(quote!( - #[cfg(not(target_arch = "x86_64"))] - compile_error!("Pre-hooks aren't yet implemented for non x86-64"); #[no_mangle] // TODO: Use the same safety/unsafety modifier as the original here @@ -254,47 +252,93 @@ pub fn pre_hook(attr_input: TokenStream, item: TokenStream) -> TokenStream { #[naked] #(#attrs)* pub unsafe extern "C" fn #func_name() { - std::arch::asm!( - // Wait for dll proxy to initialize - "call {wait_dll_proxy_init}", - "mov rax, qword ptr [rip + {ORIG_FUNCS_PTR}]", - "add rax, {orig_index} * 8", - "mov rax, qword ptr [rax]", + #[cfg(target_arch = "x86")] + { + std::arch::naked_asm!( + "call {wait_dll_proxy_init}", + "mov eax, dword ptr [{ORIG_FUNCS_PTR}]", + "add eax, {orig_index} * 4", // 4 bytes per pointer in 32-bit + "mov eax, dword ptr [eax]", // Push the original function onto the stack - "push rax", + "push eax", // Save the general purpose registers - "push rdi; push rsi; push rcx; push rdx; push r8; push r9", + // Note: i686 doesn't have r8, r9, etc. + "push edi; push esi; push ecx; push edx; push ebx", // Save the 128-bit floating point registers - "sub rsp, 64", - "movaps [rsp], xmm0", - "movaps [rsp + 16], xmm1", - "movaps [rsp + 32], xmm2", - "movaps [rsp + 48], xmm3", + // Note: XMM registers are available in i686 with SSE support + "sub esp, 64", + "movaps [esp], xmm0", + "movaps [esp + 16], xmm1", + "movaps [esp + 32], xmm2", + "movaps [esp + 48], xmm3", // Call our hook code here "call {proxygen_pre_hook_func}", // Restore the 128-bit floating point registers - "movaps xmm3, [rsp + 48]", - "movaps xmm2, [rsp + 32]", - "movaps xmm1, [rsp + 16]", - "movaps xmm0, [rsp]", - "add rsp, 64", + "movaps xmm3, [esp + 48]", + "movaps xmm2, [esp + 32]", + "movaps xmm1, [esp + 16]", + "movaps xmm0, [esp]", + "add esp, 64", // Restore the general purpose registers - "pop r9; pop r8; pop rdx; pop rcx; pop rsi; pop rdi", + "pop ebx; pop edx; pop ecx; pop esi; pop edi", // Return to the original function "ret", - wait_dll_proxy_init = sym crate::wait_dll_proxy_init, - ORIG_FUNCS_PTR = sym crate::ORIG_FUNCS_PTR, - orig_index = const #orig_index_ident, - proxygen_pre_hook_func = sym #hook_func_name, - options(noreturn) - ); + wait_dll_proxy_init = sym crate::wait_dll_proxy_init, + ORIG_FUNCS_PTR = sym crate::ORIG_FUNCS_PTR, + orig_index = const #orig_index_ident, + proxygen_pre_hook_func = sym #hook_func_name, + ); + } + #[cfg(target_arch = "x86_64")] + { + std::arch::naked_asm!( + // Wait for dll proxy to initialize + "call {wait_dll_proxy_init}", + "mov rax, qword ptr [rip + {ORIG_FUNCS_PTR}]", + "add rax, {orig_index} * 8", + "mov rax, qword ptr [rax]", + + // Push the original function onto the stack + "push rax", + + // Save the general purpose registers + "push rdi; push rsi; push rcx; push rdx; push r8; push r9", + + // Save the 128-bit floating point registers + "sub rsp, 64", + "movaps [rsp], xmm0", + "movaps [rsp + 16], xmm1", + "movaps [rsp + 32], xmm2", + "movaps [rsp + 48], xmm3", + + // Call our hook code here + "call {proxygen_pre_hook_func}", + + // Restore the 128-bit floating point registers + "movaps xmm3, [rsp + 48]", + "movaps xmm2, [rsp + 32]", + "movaps xmm1, [rsp + 16]", + "movaps xmm0, [rsp]", + "add rsp, 64", + + // Restore the general purpose registers + "pop r9; pop r8; pop rdx; pop rcx; pop rsi; pop rdi", + + // Return to the original function + "ret", + wait_dll_proxy_init = sym crate::wait_dll_proxy_init, + ORIG_FUNCS_PTR = sym crate::ORIG_FUNCS_PTR, + orig_index = const #orig_index_ident, + proxygen_pre_hook_func = sym #hook_func_name, + ); + } } )) }