Download the maps32 or maps64 from: https://github.com/sha0coder/scemu
Uncompress it somewhere, in the example it's on /tmp/ but dont use tmp.
Create an emu32 or emu64 and it's important to set the maps folder.
```rust use libscemu::emu32;
fn main() { let mut emu = emu32(); emu.setmapsfolder("/tmp/maps32/"); emu.init(); ```
Load your shellcode or PE binary and run the emulator. Zero parameter means emulate for-ever.
rust
emu.load_code("shellcodes32/shikata.bin");
emu.set_verbose(2);
emu.run(None).unwrap();
Or if you prefer call specific function.
```rust emu.load_code("samples/malware.exe");
let cryptokeygen = 0x40112233; let ret_addr = 0x40110000; // any place safe to return.
let param1 = 0x33; let param2outbuff = emu.alloc("buffer", 1024);
emu.maps.memset(param2outbuff, 0, 1024); // non necesary, by default alloc create zeros. emu.maps.writespacedbytes(param2outbuff, "DE CC 6C 83 CC F3 66 85 34"); // example of initialization.
// call function emu.regs.seteip(cryptokeygen); emu.stackpush32(param2outbuff); emu.stackpush32(param1); emu.stackpush32(retaddr); emu.run(Some(retaddr)).unwrap(); // emulate until arrive to ret_addr
// or simpler way: let eax = emu.call32(cryptokeygen, [param1, param2outbuff]).unwrap();
// this would be slower but more control while emu.step() { ... }
// check result println!("return value: 0x{:x}", emu.regs.geteax()); emu.maps.dump(param2out_buff); ```
Now it's possible to do hooks.
```rust use libscemu::emu32;
//need icedx86 crate only for instruction hooks, to get the
//instruction object, so add iced-x86 = "1.17.0"
use icedx86::{Instruction};
fn tracememoryread(emu:&mut libscemu::emu::Emu, ipaddr:u64, memaddr:u64, sz:u8) { println!("0x{:x}: reading {} at 0x{:x}", ipaddr, sz, memaddr); if mem_addr == 0x22dff0 { emu.stop(); } }
fn tracememorywrite(emu:&mut libscemu::emu::Emu, ipaddr:u64, memaddr:u64, sz:u8, value:u128) -> u128 { println!("0x{:x}: writing {} '0x{:x}' at 0x{:x}", ipaddr, sz, value, memaddr); value // I could change the value to write }
fn traceinterrupt(emu:&mut libscemu::emu::Emu, ipaddr:u64, interrupt:u64) -> bool { println!("interrupt {} triggered at eip: 0x{:x}", interrupt, ip_addr); true // do handle interrupts }
fn traceexceptions(emu:&mut libscemu::emu::Emu, ipaddr:u64) -> bool { println!("0x{:x} triggered an exception", ip_addr); true // do handle exceptions }
fn tracepreinstruction(emu:&mut libscemu::emu::Emu, ip_addr:u64, ins:&Instruction, sz:usize) { }
fn tracepostinstruction(emu:&mut libscemu::emu::Emu, ipaddr:u64, ins:&Instruction, sz:usize, emuok:bool) { }
fn tracewinapicall(emu:&mut libscemu::emu::Emu, ipaddr:u64, apiaddr:u64) -> bool { return true; // handle api calls }
fn main() { let mut emu = emu32(); emu.setmapsfolder("../scemu/maps32/"); // download the maps, ideally from scemu git. emu.init();
emu.load_code("/home/sha0/src/scemu/shellcodes32/mars.exe");
emu.hook.on_memory_read(trace_memory_read);
emu.hook.on_memory_write(trace_memory_write);
emu.hook.on_interrupt(trace_interrupt);
emu.hook.on_exception(trace_exceptions);
emu.hook.on_pre_instruction(trace_pre_instruction);
emu.hook.on_post_instruction(trace_post_instruction);
emu.hook.on_winapi_call(trace_winapi_call);
emu.run(None).unwrap();
println!("end!");
} ```