LibAFL_QEMU: Don't return a generic Address from Register reads (#2681)
* LibAFL_QEMU: Make ReadReg always return GuestReg type * Don't return a generic address * fix fuzzers * fix mips
This commit is contained in:
parent
f3aa88b400
commit
0ef0684e43
@ -196,7 +196,7 @@ fn fuzz(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Break at {:#x}", qemu.read_reg::<_, u64>(Regs::Pc).unwrap());
|
println!("Break at {:#x}", qemu.read_reg(Regs::Pc).unwrap());
|
||||||
|
|
||||||
let stack_ptr: u64 = qemu.read_reg(Regs::Sp).unwrap();
|
let stack_ptr: u64 = qemu.read_reg(Regs::Sp).unwrap();
|
||||||
let mut ret_addr = [0; 8];
|
let mut ret_addr = [0; 8];
|
||||||
|
@ -194,7 +194,7 @@ fn fuzz(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Break at {:#x}", qemu.read_reg::<_, u64>(Regs::Pc).unwrap());
|
println!("Break at {:#x}", qemu.read_reg(Regs::Pc).unwrap());
|
||||||
|
|
||||||
let stack_ptr: u64 = qemu.read_reg(Regs::Sp).unwrap();
|
let stack_ptr: u64 = qemu.read_reg(Regs::Sp).unwrap();
|
||||||
let mut ret_addr = [0; 8];
|
let mut ret_addr = [0; 8];
|
||||||
|
@ -91,10 +91,7 @@ pub fn capstone() -> capstone::arch::arm64::ArchCapstoneBuilder {
|
|||||||
pub type GuestReg = u64;
|
pub type GuestReg = u64;
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
self.read_reg(Regs::Lr)
|
self.read_reg(Regs::Lr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,10 +102,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
self.write_reg(Regs::Lr, val)
|
self.write_reg(Regs::Lr, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
let reg_id = match idx {
|
let reg_id = match idx {
|
||||||
|
@ -88,10 +88,7 @@ pub fn capstone_thumb() -> capstone::arch::arm::ArchCapstoneBuilder {
|
|||||||
pub type GuestReg = u32;
|
pub type GuestReg = u32;
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
self.read_reg(Regs::Lr)
|
self.read_reg(Regs::Lr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,10 +99,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
self.write_reg(Regs::Lr, val)
|
self.write_reg(Regs::Lr, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
let reg_id = match idx {
|
let reg_id = match idx {
|
||||||
|
@ -92,10 +92,7 @@ impl Regs {
|
|||||||
pub type GuestReg = u32;
|
pub type GuestReg = u32;
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
self.read_reg(Regs::Lr)
|
self.read_reg(Regs::Lr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,10 +103,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
self.write_reg(Regs::Lr, val)
|
self.write_reg(Regs::Lr, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
// Note that 64 bit values may be passed in two registers (and may have padding), then this mapping is off.
|
// Note that 64 bit values may be passed in two registers (and may have padding), then this mapping is off.
|
||||||
|
@ -67,10 +67,7 @@ pub fn capstone() -> capstone::arch::x86::ArchCapstoneBuilder {
|
|||||||
pub type GuestReg = u32;
|
pub type GuestReg = u32;
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
let stack_ptr: GuestReg = self.read_reg(Regs::Esp)?;
|
let stack_ptr: GuestReg = self.read_reg(Regs::Esp)?;
|
||||||
let mut ret_addr = [0; size_of::<GuestReg>()];
|
let mut ret_addr = [0; size_of::<GuestReg>()];
|
||||||
unsafe { self.read_mem(stack_ptr, &mut ret_addr) };
|
unsafe { self.read_mem(stack_ptr, &mut ret_addr) };
|
||||||
@ -88,10 +85,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
match idx {
|
match idx {
|
||||||
|
@ -88,10 +88,7 @@ pub fn capstone() -> capstone::arch::mips::ArchCapstoneBuilder {
|
|||||||
pub type GuestReg = u32;
|
pub type GuestReg = u32;
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
self.read_reg(Regs::Ra)
|
self.read_reg(Regs::Ra)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,10 +99,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
self.write_reg(Regs::Ra, val)
|
self.write_reg(Regs::Ra, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
let reg_id = match idx {
|
let reg_id = match idx {
|
||||||
|
@ -128,10 +128,7 @@ pub fn capstone() -> capstone::arch::ppc::ArchCapstoneBuilder {
|
|||||||
pub type GuestReg = u32;
|
pub type GuestReg = u32;
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
self.read_reg(Regs::Lr)
|
self.read_reg(Regs::Lr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,10 +139,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
self.write_reg(Regs::Lr, val)
|
self.write_reg(Regs::Lr, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
let reg_id = match idx {
|
let reg_id = match idx {
|
||||||
|
@ -95,10 +95,7 @@ pub fn capstone() -> capstone::arch::riscv::ArchCapstoneBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
self.read_reg(Regs::Ra)
|
self.read_reg(Regs::Ra)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,10 +106,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
self.write_reg(Regs::Ra, val)
|
self.write_reg(Regs::Ra, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
// Note that 64 bit values may be passed in two registers (and are even-odd eg. A0, A2 and A3 where A1 is empty), then this mapping is off.
|
// Note that 64 bit values may be passed in two registers (and are even-odd eg. A0, A2 and A3 where A1 is empty), then this mapping is off.
|
||||||
|
@ -78,14 +78,11 @@ pub type GuestReg = u64;
|
|||||||
pub const PROCESS_ADDRESS_RANGE: Range<u64> = 0..0x0000_7fff_ffff_ffff;
|
pub const PROCESS_ADDRESS_RANGE: Range<u64> = 0..0x0000_7fff_ffff_ffff;
|
||||||
|
|
||||||
impl crate::ArchExtras for crate::CPU {
|
impl crate::ArchExtras for crate::CPU {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
|
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
|
||||||
let mut ret_addr = [0; size_of::<GuestReg>()];
|
let mut ret_addr = [0; size_of::<GuestReg>()];
|
||||||
unsafe { self.read_mem_unchecked(stack_ptr, &mut ret_addr) };
|
unsafe { self.read_mem_unchecked(stack_ptr, &mut ret_addr) };
|
||||||
Ok(GuestReg::from_le_bytes(ret_addr).into())
|
Ok(GuestReg::from_le_bytes(ret_addr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_return_address<T>(&self, val: T) -> Result<(), QemuRWError>
|
fn write_return_address<T>(&self, val: T) -> Result<(), QemuRWError>
|
||||||
@ -99,10 +96,11 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
QemuRWError::check_conv(QemuRWErrorKind::Read, CallingConvention::Cdecl, conv)?;
|
||||||
|
|
||||||
let reg_id = match idx {
|
let reg_id = match idx {
|
||||||
|
@ -106,7 +106,7 @@ macro_rules! define_std_command_manager {
|
|||||||
#[deny(unreachable_patterns)]
|
#[deny(unreachable_patterns)]
|
||||||
fn parse(&self, qemu: Qemu) -> Result<Self::Commands, CommandError> {
|
fn parse(&self, qemu: Qemu) -> Result<Self::Commands, CommandError> {
|
||||||
let arch_regs_map: &'static EnumMap<ExitArgs, Regs> = get_exit_arch_regs();
|
let arch_regs_map: &'static EnumMap<ExitArgs, Regs> = get_exit_arch_regs();
|
||||||
let cmd_id = qemu.read_reg::<Regs, GuestReg>(arch_regs_map[ExitArgs::Cmd])? as c_uint;
|
let cmd_id = qemu.read_reg(arch_regs_map[ExitArgs::Cmd])? as c_uint;
|
||||||
|
|
||||||
match cmd_id {
|
match cmd_id {
|
||||||
// <StartPhysCommandParser as NativeCommandParser<S>>::COMMAND_ID => Ok(StdCommandManagerCommands::StartPhysCommandParserCmd(<StartPhysCommandParser as NativeCommandParser<S>>::parse(qemu, arch_regs_map)?)),
|
// <StartPhysCommandParser as NativeCommandParser<S>>::COMMAND_ID => Ok(StdCommandManagerCommands::StartPhysCommandParserCmd(<StartPhysCommandParser as NativeCommandParser<S>>::parse(qemu, arch_regs_map)?)),
|
||||||
|
@ -52,7 +52,7 @@ where
|
|||||||
qemu: Qemu,
|
qemu: Qemu,
|
||||||
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
||||||
) -> Result<Self::OutputCommand, CommandError> {
|
) -> Result<Self::OutputCommand, CommandError> {
|
||||||
let input_phys_addr: GuestPhysAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?;
|
let input_phys_addr: GuestPhysAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?.into();
|
||||||
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
||||||
|
|
||||||
Ok(InputCommand::new(
|
Ok(InputCommand::new(
|
||||||
@ -81,7 +81,7 @@ where
|
|||||||
qemu: Qemu,
|
qemu: Qemu,
|
||||||
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
||||||
) -> Result<Self::OutputCommand, CommandError> {
|
) -> Result<Self::OutputCommand, CommandError> {
|
||||||
let input_virt_addr: GuestVirtAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?;
|
let input_virt_addr: GuestVirtAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?.into();
|
||||||
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
||||||
|
|
||||||
Ok(InputCommand::new(
|
Ok(InputCommand::new(
|
||||||
@ -109,7 +109,7 @@ where
|
|||||||
qemu: Qemu,
|
qemu: Qemu,
|
||||||
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
||||||
) -> Result<Self::OutputCommand, CommandError> {
|
) -> Result<Self::OutputCommand, CommandError> {
|
||||||
let input_phys_addr: GuestPhysAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?;
|
let input_phys_addr: GuestPhysAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?.into();
|
||||||
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
||||||
|
|
||||||
Ok(StartCommand::new(QemuMemoryChunk::phys(
|
Ok(StartCommand::new(QemuMemoryChunk::phys(
|
||||||
@ -138,7 +138,7 @@ where
|
|||||||
qemu: Qemu,
|
qemu: Qemu,
|
||||||
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
||||||
) -> Result<Self::OutputCommand, CommandError> {
|
) -> Result<Self::OutputCommand, CommandError> {
|
||||||
let input_virt_addr: GuestVirtAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?;
|
let input_virt_addr: GuestVirtAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?.into();
|
||||||
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
|
||||||
|
|
||||||
Ok(StartCommand::new(QemuMemoryChunk::virt(
|
Ok(StartCommand::new(QemuMemoryChunk::virt(
|
||||||
@ -237,7 +237,7 @@ where
|
|||||||
qemu: Qemu,
|
qemu: Qemu,
|
||||||
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
|
||||||
) -> Result<Self::OutputCommand, CommandError> {
|
) -> Result<Self::OutputCommand, CommandError> {
|
||||||
let client_version = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?;
|
let client_version = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?.into();
|
||||||
|
|
||||||
Ok(VersionCommand::new(client_version))
|
Ok(VersionCommand::new(client_version))
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ where
|
|||||||
) -> Result<Self::OutputCommand, CommandError> {
|
) -> Result<Self::OutputCommand, CommandError> {
|
||||||
let buf_addr: GuestAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?;
|
let buf_addr: GuestAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?;
|
||||||
let str_size: usize = qemu
|
let str_size: usize = qemu
|
||||||
.read_reg::<Regs, GuestAddr>(arch_regs_map[ExitArgs::Arg2])?
|
.read_reg(arch_regs_map[ExitArgs::Arg2])?
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap(); // without null byte
|
.unwrap(); // without null byte
|
||||||
let cpu = qemu.current_cpu().unwrap();
|
let cpu = qemu.current_cpu().unwrap();
|
||||||
|
@ -320,15 +320,15 @@ impl From<libafl_qemu_sys::MemOpIdx> for MemAccessInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait ArchExtras {
|
pub trait ArchExtras {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError>;
|
||||||
where
|
|
||||||
T: From<GuestReg>;
|
|
||||||
fn write_return_address<T>(&self, val: T) -> Result<(), QemuRWError>
|
fn write_return_address<T>(&self, val: T) -> Result<(), QemuRWError>
|
||||||
where
|
where
|
||||||
T: Into<GuestReg>;
|
T: Into<GuestReg>;
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>;
|
conv: CallingConvention,
|
||||||
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError>;
|
||||||
fn write_function_argument<T>(
|
fn write_function_argument<T>(
|
||||||
&self,
|
&self,
|
||||||
conv: CallingConvention,
|
conv: CallingConvention,
|
||||||
@ -360,10 +360,9 @@ impl CPU {
|
|||||||
unsafe { libafl_qemu_num_regs(self.ptr) }
|
unsafe { libafl_qemu_num_regs(self.ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_reg<R, T>(&self, reg: R) -> Result<T, QemuRWError>
|
pub fn read_reg<R>(&self, reg: R) -> Result<GuestReg, QemuRWError>
|
||||||
where
|
where
|
||||||
R: Into<i32> + Clone,
|
R: Into<i32> + Clone,
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let reg_id = reg.clone().into();
|
let reg_id = reg.clone().into();
|
||||||
@ -824,9 +823,8 @@ impl Qemu {
|
|||||||
.write_reg(reg, val)
|
.write_reg(reg, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_reg<R, T>(&self, reg: R) -> Result<T, QemuRWError>
|
pub fn read_reg<R>(&self, reg: R) -> Result<GuestReg, QemuRWError>
|
||||||
where
|
where
|
||||||
T: Num + PartialOrd + Copy + From<GuestReg>,
|
|
||||||
R: Into<i32> + Clone,
|
R: Into<i32> + Clone,
|
||||||
{
|
{
|
||||||
self.current_cpu()
|
self.current_cpu()
|
||||||
@ -907,17 +905,14 @@ impl Qemu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ArchExtras for Qemu {
|
impl ArchExtras for Qemu {
|
||||||
fn read_return_address<T>(&self) -> Result<T, QemuRWError>
|
fn read_return_address(&self) -> Result<GuestReg, QemuRWError> {
|
||||||
where
|
|
||||||
T: From<GuestReg>,
|
|
||||||
{
|
|
||||||
self.current_cpu()
|
self.current_cpu()
|
||||||
.ok_or(QemuRWError {
|
.ok_or(QemuRWError {
|
||||||
kind: QemuRWErrorKind::Read,
|
kind: QemuRWErrorKind::Read,
|
||||||
cause: QemuRWErrorCause::CurrentCpuNotFound,
|
cause: QemuRWErrorCause::CurrentCpuNotFound,
|
||||||
cpu: None,
|
cpu: None,
|
||||||
})?
|
})?
|
||||||
.read_return_address::<T>()
|
.read_return_address()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_return_address<T>(&self, val: T) -> Result<(), QemuRWError>
|
fn write_return_address<T>(&self, val: T) -> Result<(), QemuRWError>
|
||||||
@ -929,13 +924,14 @@ impl ArchExtras for Qemu {
|
|||||||
.write_return_address::<T>(val)
|
.write_return_address::<T>(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_function_argument<T>(&self, conv: CallingConvention, idx: u8) -> Result<T, QemuRWError>
|
fn read_function_argument(
|
||||||
where
|
&self,
|
||||||
T: From<GuestReg>,
|
conv: CallingConvention,
|
||||||
{
|
idx: u8,
|
||||||
|
) -> Result<GuestReg, QemuRWError> {
|
||||||
self.current_cpu()
|
self.current_cpu()
|
||||||
.ok_or(QemuRWError::current_cpu_not_found(QemuRWErrorKind::Read))?
|
.ok_or(QemuRWError::current_cpu_not_found(QemuRWErrorKind::Read))?
|
||||||
.read_function_argument::<T>(conv, idx)
|
.read_function_argument(conv, idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_function_argument<T>(
|
fn write_function_argument<T>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user