libmwemu 0.24.1

x86 32/64bits and system internals emulator, for securely emulating malware and other stuff.
Documentation
use crate::emu::Emu;
use crate::syscall::linux;
use crate::syscall::windows;
use crate::{color, exception_type};
use iced_x86::Instruction;

pub fn execute(emu: &mut Emu, ins: &Instruction, instruction_sz: usize, _rep_step: bool) -> bool {
    emu.show_instruction(color!("Red"), ins);

    assert!(ins.op_count() == 1);

    let interrupt = match emu.get_operand_value(ins, 0, true) {
        Some(v) => v,
        None => return false,
    };

    let handle_interrupts = if let Some(mut hook_fn) = emu.hooks.hook_on_interrupt.take() {
        let rip = emu.regs().rip;
        let result = hook_fn(emu, rip, interrupt);
        emu.hooks.hook_on_interrupt = Some(hook_fn);
        result
    } else {
        true
    };

    if handle_interrupts {
        match interrupt {
            0x80 => {
                // Do not set `emu.linux` here: it would mis-route later `syscall` on PE/SSDT.
                if emu.linux {
                    if emu.cfg.is_64bits {
                        linux::syscall64::gateway(emu);
                    } else {
                        linux::syscall32::gateway(emu);
                    }
                } else if emu.cfg.is_64bits {
                    windows::syscall64::gateway(emu);
                } else {
                    windows::syscall32::gateway(emu);
                }
            }

            0x29 => {
                log::trace!("call_stack = {:?}", emu.call_stack());
                log::trace!("int 0x29: __fastfail {}", emu.regs().rcx);
                emu.stop();
                return false;
            }

            0x03 => {
                emu.show_instruction(color!("Red"), ins);
                log::trace!("/!\\ int 0x3 sigtrap!!!!");
                emu.exception(exception_type::ExceptionType::Int3);
                return false;
            }

            0xdc => {
                log::trace!("/!\\ direct syscall: NtAlpcSendWaitReceivePort");
            }

            _ => {
                log::trace!("unimplemented interrupt {}", interrupt);
                return false;
            }
        }
    }
    true
}