Open
Description
ptrace::getregs
and ptrace::getregset
are used to get register values of certain process (tracee), which utilizes the ptrace(PTRACE_GETREGSET, ..)
syscall:
pub fn getregset<S: RegisterSet>(pid: Pid) -> Result<S::Regs> {
let request = Request::PTRACE_GETREGSET;
let mut data = mem::MaybeUninit::<S::Regs>::uninit();
let mut iov = libc::iovec {
iov_base: data.as_mut_ptr().cast(),
iov_len: mem::size_of::<S::Regs>(),
};
unsafe {
ptrace_other(
request,
pid,
S::VALUE as i32 as AddressType,
(&mut iov as *mut libc::iovec).cast(),
)?;
};
Ok(unsafe { data.assume_init() })
}
In amd64 Linux, if the tracer is 64bit process, tracee is 32bit process, the S::Regs
will be resolved to 64bit version of libc::user_regs_struct
, while after the syscall return, the S::VALUE
buffer is filled by kernel with 32bit version of such struct. (The iovec.iov_len
field will be 68 after returning, which confirms such thing). Reading the returned S::Regs
will lead to uninitialized data, which is UB.