#vm #instance #callback #register #binding #qbdi

sys qbdi-sys

QBDI library rust binding (use rust bindgen)

1 unstable release

0.1.2 Mar 12, 2024
0.1.1 Mar 10, 2024
0.1.0 Mar 10, 2024

#53 in #callback

MIT license

225KB
6.5K SLoC

install deps

https://github.com/QBDI/QBDI/releases

useage

cargo add qbdi-sys

example

        // define callback
    unsafe extern "C" fn on_post_instruction(
        vm: VMInstanceRef,
        gpr_state: *mut GPRState,
        fpr_state: *mut FPRState,
        data: *mut c_void,
    ) -> VMAction {
        let runner = data as *mut Self;
        let inst_analysis = Self::get_inst_analysis(vm);
        let asm = CStr::from_ptr((*inst_analysis).disassembly)
            .to_str()
            .unwrap()
            .to_string();
        println!(
            "on_post_instruction: [{}],pc:{:p},asm:{}",
            (*runner).i,
            (*inst_analysis).address as *const c_void,
            asm
        );
        (*runner).i += 1;

        // unimplemented!()
        VMAction_QBDI_CONTINUE
    }



        //  QBDI::VM vm;
        let mut instance: VMInstanceRef = std::ptr::null_mut();
        let cpu: *const c_char = std::ptr::null();
        let mut mattrs: *const c_char = std::ptr::null_mut();
        let opts: Options = Options_QBDI_NO_OPT;
        unsafe {
            qbdi_initVM(&mut instance, cpu, &mut mattrs, opts);
        }

        //   Get the VM state
        // QBDI::GPRState *state = vm.getGPRState();
        let state = unsafe { qbdi_getGPRState(instance) };
        // // Allocate the virtual stack
        // static const size_t STACK_SIZE = 0x100000; // 1MB
        let stack_size = 0x100000;

        let mut stack: *mut u8 = std::ptr::null_mut();
        // auto res = QBDI::allocateVirtualStack(state, STACK_SIZE, &fakestack);
        let _ = unsafe { qbdi_allocateVirtualStack(state, stack_size, &mut stack) };

        // register callback
        let _pre_call_id = unsafe {
             qbdi_addMnemonicCB(
                 instance,
                 "CALL*".as_ptr() as *const ::std::os::raw::c_char,
                 InstPosition_QBDI_PREINST,
                 Some(Self::on_pre_call_instruction),
                 self as *mut Runner as *mut c_void,
                 0,
             )
        };




        let start = context.entry as u64;
        let end = start + context.size as u64;
        println!(
            "start:{:p},end:{:p},size:{},instance:{:p}",
            start as *const c_void, end as *const c_void, context.size, instance as *const c_void
        );

        unsafe { qbdi_addInstrumentedModuleFromAddr(instance, start) };
        // unsafe { qbdi_addInstrumentedRange(instance, start, end) };

        // // // // Running DBI execution
        // // // res = vm.run(
        // // //     (QBDI::rword)entry, (QBDI::rword)entry + size);
        let stop = end;

        unsafe { qbdi_run(instance, start, end) };

        // unsafe {
        //     // Execute the shellcode.
        //     let runner: unsafe extern "system" fn() = std::mem::transmute(context.entry);
        //     runner();
        // }

        // free fakestack
        unsafe { qbdi_alignedFree(stack as *mut c_void) };

No runtime deps

~0–1.8MB
~36K SLoC