cross compile asm
Closed this issue · 4 comments
Very good project. But I have some problems when I try to cross compile.
It seems that only the msvc environment can compile normally. MSYS2 failed.
warning: unwinder@0.1.1: x86_64-w64-mingw32-gcc: warning: src/gateway.asm: linker input file unused because linking not done
warning: unwinder@0.1.1: x86_64-w64-mingw32-ar: /projects/target/x86_64-pc-windows-gnu/release/build/unwinder-5f8cf206a3d006ec/out/src/gateway.o: No such file or directory
error: failed to run custom build command for `unwinder v0.1.1`
I purpose of this is to quickly obfuscate features via rust + OLLVM....
https://vrls.ws/posts/2023/06/obfuscating-rust-binaries-using-llvm-obfuscator-ollvm/
I've never tried to cross compile this code and I'm not completely sure if you can do so. I'll give it a try and let you know if I find any solution to your issue.
Not fully tested.
edit build.rs
extern crate nasm_rs;
fn main() {
let out_dir = std::env::var("OUT_DIR").unwrap();
nasm_rs::compile_library("gateway", &["src/gateway.asm"]).unwrap();
println!("cargo:rerun-if-changed=src/gateway.asm");
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-lib=static=gateway");
}
edit gateway.asm
section .data
struc SPOOFER
.FirstFrameFunctionPointer resq 1
.SecondFrameFunctionPointer resq 1
.JmpRbxGadget resq 1
.AddRspXGadget resq 1
.FirstFrameSize resq 1
.SecondFrameSize resq 1
.JmpRbxGadgetFrameSize resq 1
.AddRspXGadgetFrameSize resq 1
.StackOffsetWhereRbpIsPushed resq 1
.SpoofFunctionPointer resq 1
.ReturnAddress resq 1
.Nargs resq 1
.Arg01 resq 1
.Arg02 resq 1
.Arg03 resq 1
.Arg04 resq 1
.Arg05 resq 1
.Arg06 resq 1
.Arg07 resq 1
.Arg08 resq 1
.Arg09 resq 1
.Arg10 resq 1
.Arg11 resq 1
.Sys resd 0
.SysId resd 0
endstruc
section .text
bits 64
global add_numbers
global spoof_call
global get_current_rsp
add_numbers:
mov rax, rdi
add rax, rsi
ret
get_current_rsp:
mov rax, rsp
add rax, 8
ret
restore:
mov rsp, rbp
mov rbp, [rsp+08h]
mov rbx, [rsp+10h]
ret
parameter_handler:
cmp qword [rcx + SPOOFER.Nargs], 11
je handle_eleven
cmp qword [rcx + SPOOFER.Nargs], 10
je handle_ten
cmp qword [rcx + SPOOFER.Nargs], 9
je handle_nine
cmp qword [rcx + SPOOFER.Nargs], 8
je handle_eight
cmp qword [rcx + SPOOFER.Nargs], 7
je handle_seven
cmp qword [rcx + SPOOFER.Nargs], 6
je handle_six
cmp qword [rcx + SPOOFER.Nargs], 5
je handle_five
cmp qword [rcx + SPOOFER.Nargs], 4
je handle_four
cmp qword [rcx + SPOOFER.Nargs], 3
je handle_three
cmp qword [rcx + SPOOFER.Nargs], 2
je handle_two
cmp qword [rcx + SPOOFER.Nargs], 1
je handle_one
cmp qword [rcx + SPOOFER.Nargs], 0
je handle_none
spoof_call:
mov qword [rsp + 8], rbp
mov [rsp+10h], rbx
mov rbp, rsp
lea rax, [rel restore]
push rax
lea rbx, [rsp]
push qword [rcx + SPOOFER.FirstFrameFunctionPointer]
mov rax, [rcx + SPOOFER.ReturnAddress]
sub rax, [rcx + SPOOFER.FirstFrameSize]
sub rsp, [rcx + SPOOFER.SecondFrameSize]
mov r10, [rcx + SPOOFER.StackOffsetWhereRbpIsPushed]
mov [rsp+r10], rax
push qword [rcx + SPOOFER.SecondFrameFunctionPointer]
sub rsp, [rcx + SPOOFER.JmpRbxGadgetFrameSize]
push qword [rcx + SPOOFER.JmpRbxGadget]
sub rsp, [rcx + SPOOFER.AddRspXGadgetFrameSize]
push qword [rcx + SPOOFER.AddRspXGadget]
mov r11, [rcx + SPOOFER.SpoofFunctionPointer]
jmp parameter_handler
handle_eleven:
push r15
mov r15, [rcx + SPOOFER.Arg11]
mov [rsp+60h], r15
pop r15
jmp handle_ten
handle_ten:
push r15
mov r15, [rcx + SPOOFER.Arg10]
mov [rsp+58h], r15
pop r15
jmp handle_nine
handle_nine:
push r15
mov r15, [rcx + SPOOFER.Arg09]
mov [rsp+50h], r15
pop r15
jmp handle_eight
handle_eight:
push r15
mov r15, [rcx + SPOOFER.Arg08]
mov [rsp+48h], r15
pop r15
jmp handle_seven
handle_seven:
push r15
mov r15, [rcx + SPOOFER.Arg07]
mov [rsp+40h], r15
pop r15
jmp handle_six
handle_six:
push r15
mov r15, [rcx + SPOOFER.Arg06]
mov [rsp+38h], r15
pop r15
jmp handle_five
handle_five:
push r15
mov r15, [rcx + SPOOFER.Arg05]
mov [rsp+30h], r15
pop r15
jmp handle_four
handle_four:
mov r9, [rcx + SPOOFER.Arg04]
jmp handle_three
handle_three:
mov r8, [rcx + SPOOFER.Arg03]
jmp handle_two
handle_two:
mov rdx, [rcx + SPOOFER.Arg02]
jmp handle_one
handle_one:
cmp qword [rcx + SPOOFER.Sys], 0
jne execute_syscall
mov rcx, [rcx + SPOOFER.Arg01]
jmp handle_none
handle_none:
jmp execute
execute:
jmp r11
execute_syscall:
mov r10, [rcx + SPOOFER.Arg01]
mov eax, [rcx + SPOOFER.SysId]
mov rcx, [rcx + SPOOFER.Arg01]
jmp r11
edit Cargo.toml
# add
[build-dependencies]
nasm-rs = "0.3.0"
test
use std::ffi::c_void;
use std::time::Instant;
use untitled1::call_function;
fn main() {
let start_time = Instant::now();
let k32 = dinvoke_rs::dinvoke::get_module_base_address("kernel32.dll");
let sleep = dinvoke_rs::dinvoke::get_function_address(k32, "Sleep"); // Memory address of kernel32.dll!Sleep()
let miliseconds = 5000i32;
unsafe {
call_function!(sleep, false, miliseconds);
}
let end_time = Instant::now();
let elapsed_time = end_time - start_time;
println!("Execution time: {} microseconds", elapsed_time.as_micros());
}
build cargo build --release --target x86_64-pc-windows-gnu
Great you solved it, thank you for the update!
Help me, if I use the asm you provided and compile it under msvc environment the indirect_syscall call is normal, when I try to modify the version of asm and compile it under gnu environment the indirect_syscall call exception