241 个版本 (13 个破坏性更新)
新增 0.17.3 | 2024 年 8 月 21 日 |
---|---|
0.16.7 | 2024 年 7 月 14 日 |
0.15.6 | 2024 年 3 月 27 日 |
0.14.1 | 2023 年 12 月 22 日 |
0.8.9 | 2022 年 11 月 11 日 |
#20 在 模拟器
每月 503 次下载
2MB
37K SLoC
SCEMU 库
使用方法
从以下网址下载 maps32 或 maps64: https://github.com/sha0coder/scemu
解压缩到某个位置,例如 /tmp/,但不要使用 tmp。
创建 emu32 或 emu64,并设置 maps 文件夹非常重要。
use libscemu::emu32;
fn main() {
let mut emu = emu32();
emu.set_maps_folder("/tmp/maps32/");
emu.init();
加载您的 shellcode 或 PE 二进制文件并运行模拟器。零参数表示无限模拟。
emu.load_code("shellcodes32/shikata.bin");
emu.set_verbose(2);
emu.run(None).unwrap();
或者,如果您更喜欢调用特定函数。
emu.load_code("samples/malware.exe");
let crypto_key_gen = 0x40112233;
let ret_addr = 0x40110000; // any place safe to return.
let param1 = 0x33;
let param2_out_buff = emu.alloc("buffer", 1024);
emu.maps.memset(param2_out_buff, 0, 1024); // non necesary, by default alloc create zeros.
emu.maps.write_spaced_bytes(param2_out_buff,
"DE CC 6C 83 CC F3 66 85 34"); // example of initialization.
// call function
emu.regs.set_eip(crypto_key_gen);
emu.stack_push32(param2_out_buff);
emu.stack_push32(param1);
emu.stack_push32(ret_addr);
emu.run(Some(ret_addr)).unwrap(); // emulate until arrive to ret_addr
// or simpler way:
let eax = emu.call32(crypto_key_gen, &[param1, param2_out_buff]).unwrap();
// this would be slower but more control
while emu.step() {
...
}
// check result
println!("return value: 0x{:x}", emu.regs.get_eax());
emu.maps.dump(param2_out_buff);
现在可以进行钩子操作。
use libscemu::emu32;
//need iced_x86 crate only for instruction hooks, to get the
//instruction object, so add `iced-x86 = "1.17.0"`
use iced_x86::{Instruction};
fn trace_memory_read(emu:&mut libscemu::emu::Emu, ip_addr:u64,
mem_addr:u64, sz:u8) {
println!("0x{:x}: reading {} at 0x{:x}", ip_addr, sz, mem_addr);
if mem_addr == 0x22dff0 {
emu.stop();
}
}
fn trace_memory_write(emu:&mut libscemu::emu::Emu, ip_addr:u64,
mem_addr:u64, sz:u8, value:u128) -> u128 {
println!("0x{:x}: writing {} '0x{:x}' at 0x{:x}", ip_addr, sz,
value, mem_addr);
value // I could change the value to write
}
fn trace_interrupt(emu:&mut libscemu::emu::Emu, ip_addr:u64,
interrupt:u64) -> bool {
println!("interrupt {} triggered at eip: 0x{:x}", interrupt,
ip_addr);
true // do handle interrupts
}
fn trace_exceptions(emu:&mut libscemu::emu::Emu, ip_addr:u64) -> bool {
println!("0x{:x} triggered an exception", ip_addr);
true // do handle exceptions
}
fn trace_pre_instruction(emu:&mut libscemu::emu::Emu, ip_addr:u64,
ins:&Instruction, sz:usize) {
}
fn trace_post_instruction(emu:&mut libscemu::emu::Emu, ip_addr:u64,
ins:&Instruction, sz:usize, emu_ok:bool) {
}
fn trace_winapi_call(emu:&mut libscemu::emu::Emu, ip_addr:u64, api_addr:u64) -> bool {
return true; // handle api calls
}
fn main() {
let mut emu = emu32();
emu.set_maps_folder("../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!");
}
依赖项
~20–29MB
~466K SLoC