Custom ptrace: added peek/poke data
This commit is contained in:
parent
29e463aced
commit
e61f62487b
|
|
@ -13,6 +13,10 @@ unsafe fn errno() -> c_int {
|
|||
unsafe { *__errno_location() }
|
||||
}
|
||||
|
||||
unsafe fn set_errno(errno: c_int) {
|
||||
unsafe { *__errno_location() = errno; }
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("{}", self.error_message())]
|
||||
pub struct ErrnoError {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::clibwrap::{ErrnoError, Pid};
|
||||
use crate::clibwrap::{errno, set_errno, ErrnoError, Pid};
|
||||
use bitflags::bitflags;
|
||||
use std::ffi::{c_long, c_ulonglong, c_void};
|
||||
use std::mem::MaybeUninit;
|
||||
|
|
@ -6,6 +6,8 @@ use std::mem::MaybeUninit;
|
|||
#[allow(non_camel_case_types)]
|
||||
#[repr(u32)]
|
||||
enum PTraceRequest {
|
||||
PTRACE_PEEKDATA = 2,
|
||||
PTRACE_POKEDATA = 5,
|
||||
PTRACE_CONT = 7,
|
||||
PTRACE_SINGLESTEP = 9,
|
||||
PTRACE_GETREGS = 12,
|
||||
|
|
@ -140,3 +142,25 @@ pub fn set_regs(pid: Pid, registers: registers) -> Result<(), ErrnoError> {
|
|||
unsafe { Err(ErrnoError::from_current_errno()) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peek_data(pid: Pid, address: u64) -> Result<c_long, ErrnoError> {
|
||||
unsafe {
|
||||
set_errno(0);
|
||||
let data = ptrace(PTraceRequest::PTRACE_PEEKDATA, pid, address as _, 0 as _);
|
||||
let errno = errno();
|
||||
if errno != 0 {
|
||||
Err(ErrnoError::from_current_errno())
|
||||
} else {
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn poke_data(pid: Pid, address: u64, data: c_long) -> Result<(), ErrnoError> {
|
||||
let return_code = unsafe { ptrace(PTraceRequest::PTRACE_POKEDATA, pid, address as _, data as _) };
|
||||
if return_code == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
unsafe { Err(ErrnoError::from_current_errno()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
use crate::clibwrap;
|
||||
use crate::debug_target::{CustomPTraceError, DebugError, PTraceError, RunningTarget, WaitError};
|
||||
use crate::debug_target::{CustomPTraceError, DebugError, RunningTarget, WaitError};
|
||||
use crate::syscall_info::{syscall_info, SyscallInfo, SyscallInfoError};
|
||||
use libc::c_long;
|
||||
use nix::sys::wait::{waitid, Id, WaitPidFlag};
|
||||
use nix::unistd::Pid;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::c_void;
|
||||
|
||||
pub struct StoppedTarget {
|
||||
pub pid: Pid,
|
||||
|
|
@ -76,10 +75,10 @@ impl StoppedTarget {
|
|||
if self.breakpoints.contains_key(&address) {
|
||||
return Err(DebugError::DuplicateBreakpoint { address });
|
||||
}
|
||||
let orig_bytes = nix::sys::ptrace::read(self.pid, address as *mut c_void).map_err(PTraceError)?;
|
||||
let orig_bytes = clibwrap::ptrace::peek_data(self.pid.as_raw(), address).map_err(CustomPTraceError)?;
|
||||
let target_byte: u8 = (orig_bytes & 0xFF as c_long) as u8;
|
||||
let new_content = (orig_bytes & (!0xff as c_long)) | (0xCC as c_long);
|
||||
nix::sys::ptrace::write(self.pid, address as *mut c_void, new_content).map_err(PTraceError)?;
|
||||
clibwrap::ptrace::poke_data(self.pid.as_raw(), address, new_content).map_err(CustomPTraceError)?;
|
||||
|
||||
self.breakpoints.insert(address, target_byte);
|
||||
Ok(())
|
||||
|
|
@ -90,9 +89,9 @@ impl StoppedTarget {
|
|||
match self.breakpoints.remove(&address) {
|
||||
None => Err(DebugError::NonExistingBreakpoint { address }),
|
||||
Some(original_byte) => {
|
||||
let content = nix::sys::ptrace::read(self.pid, address as *mut c_void).map_err(PTraceError)?;
|
||||
let content = clibwrap::ptrace::peek_data(self.pid.as_raw(), address).map_err(CustomPTraceError)?;
|
||||
let new_content = (content & (!0xff as c_long)) | (original_byte as c_long);
|
||||
nix::sys::ptrace::write(self.pid, address as *mut c_void, new_content).map_err(PTraceError)?;
|
||||
clibwrap::ptrace::poke_data(self.pid.as_raw(), address, new_content).map_err(CustomPTraceError)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue