You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Consider the following use of SnapshotModule::{snapshot,reset}:
// cargo init// cargo add --no-default-features --git https://github.com/AFLplusplus/LibAFL libafl_qemu// cargo runuse std::{error, fs, io::Writeas _, path, process};use libafl_qemu::{modules::SnapshotModule,Regs};fnrun_to(qemu:&libafl_qemu::Qemu,addr: libafl_qemu::GuestAddr,) -> Result<(), libafl_qemu::QemuExitError>{
qemu.set_breakpoint(addr);unsafe{ qemu.run()}.unwrap();
qemu.remove_breakpoint(addr);Ok(())}/// Call a function with signature `u64 (*)(void)`fncall(qemu:&libafl_qemu::Qemu,addr: libafl_qemu::GuestAddr) -> u64{// Push return addresslet rip:u64 = qemu.read_reg(Regs::Rip).unwrap();letmut rsp:u64 = qemu.read_reg(Regs::Rsp).unwrap();
rsp -= 8;
qemu.write_mem(rsp,&u64::to_le_bytes(rip)).unwrap();
qemu.write_reg(Regs::Rsp, rsp).unwrap();// Make callprintln!("Calling {addr:#x}");
qemu.write_reg(Regs::Rip, addr).unwrap();run_to(qemu, rip).unwrap();let ret = qemu.read_reg::<_,u64>(Regs::Rax).unwrap();println!("Got {ret:#x}");
ret
}fnmain() -> Result<(),Box<dyn error::Error>>{constPROG:&str = r#"int global = 0xdeadbeef;int get(void) { return global; }void set(void) { global = 1; }int main(int argc, char *argv[]) { set(); return get();}"#;let target = path::PathBuf::from("set");
fs::File::create("set.c")?.write_all(PROG.as_bytes())?;let out = process::Command::new("clang").arg("set.c").arg("-O0").args(["-o","set"]).output()?;assert!(out.status.success());let args = &["qemu".to_string(), target.to_string_lossy().to_string()];let qemu = libafl_qemu::Qemu::init(args)?;letmut elf_buffer = Vec::new();let elf = libafl_qemu::elf::EasyElf::from_file(target.as_path(),&mut elf_buffer)?;let get = elf.resolve_symbol("get", qemu.load_addr()).unwrap();let set = elf.resolve_symbol("set", qemu.load_addr()).unwrap();let main = elf.resolve_symbol("main", qemu.load_addr()).unwrap();println!("get @ {get:#x}");println!("set @ {set:#x}");println!("main @ {main:#x}");// Run to entrypointrun_to(&qemu, main).unwrap();// Check initial valueletmut global = call(&qemu, get);assert_eq!(global, 0xdeadbeef);letmut snap = SnapshotModule::new();println!("Taking snapshot");
snap.snapshot(qemu);// Check that value changes when `set` is calledcall(&qemu, set);
global = call(&qemu, get);assert_eq!(global, 1);// Check that value is reset by snapshotprintln!("Resetting snapshot");
snap.reset(qemu);
global = call(&qemu, get);assert_eq!(global, 0xdeadbeef);// this fails!Ok(())}
The last assertion there fails. I believe this is because SnapshotModule::new doesn't actually install any sort of memory tracing infrastructure, this only happens in init_module. I would say that this is a footgun, the above API usage is pretty reasonable looking, but doesn't do at all what one might expect. I think that this module should probably not expose snapshot and reset, and that these should only be available through the impl EmulatorModule.
The text was updated successfully, but these errors were encountered:
Consider the following use of
SnapshotModule::{snapshot,reset}
:The last assertion there fails. I believe this is because
SnapshotModule::new
doesn't actually install any sort of memory tracing infrastructure, this only happens ininit_module
. I would say that this is a footgun, the above API usage is pretty reasonable looking, but doesn't do at all what one might expect. I think that this module should probably not exposesnapshot
andreset
, and that these should only be available through theimpl EmulatorModule
.The text was updated successfully, but these errors were encountered: