This crate is loosely based on read-process-memory
by luser, but has been extended to be able to write to process memory as well.
The current supported platforms are: - Windows - OSX - Linux
Some examples of use cases for this tool are: - Remote debugging tools - Game "trainers" - Rust clones of Cheat Engine
```rust
// We have a variable with some value let x = 4_u32; println!("Original x-value: {}", x);
// We need to make sure that we get a handle to a process, in this case, ourselves
let handle = (std::process::id() as Pid).tryintoprocesshandle().unwrap();
// We make a DataMember
that has an offset referring to its location in memory
let member = DataMember::newoffset(handle, vec![&x as *const _ as usize]);
// The memory refered to is now the same
println!("Memory location: &x: {}, member: {}", &x as *const _ as usize,
member.getoffset().unwrap());
asserteq!(&x as *const _ as usize, member.getoffset().unwrap());
// The value of the member is the same as the variable
println!("Member value: {}", unsafe { member.read().unwrap() });
asserteq!(x, unsafe { member.read().unwrap() });
// We can write to and modify the value of the variable using the member
member.write(&6u32).unwrap();
println!("New x-value: {}", x);
asserteq!(x, 6_u32);
rust
// We have a variable with some value let x = 4_u32; println!("Original x-value: {}", x);
// We make a LocalMember
that has an offset referring to its location in memory
let member = LocalMember::newoffset(vec![&x as *const _ as usize]);
// The memory refered to is now the same
println!("Memory location: &x: {}, member: {}", &x as *const _ as usize,
member.getoffset().unwrap());
asserteq!(&x as *const _ as usize, member.getoffset().unwrap());
// The value of the member is the same as the variable
println!("Member value: {}", unsafe { member.read().unwrap() });
asserteq!(x, unsafe { member.read().unwrap() });
// We can write to and modify the value of the variable using the member
member.write(&6u32).unwrap();
println!("New x-value: {}", x);
asserteq!(x, 6u32);
no_run
// We get a handle for a target process with a different architecture to ourselves
let handle = getpid("32Bit.exe").tryintoprocesshandle().unwrap()
.setarch(Architecture::Arch32Bit);
// We make a DataMember
that has a series of offsets refering to a known value in
// the target processes memory
let member = DataMember::newoffset(handle, vec![0x01020304, 0x04, 0x08, 0x10]);
// The memory offset can now be correctly calculated:
println!("Target memory location: {}", member.getoffset().unwrap());
// The memory offset can now be used to retrieve and modify values:
println!("Current value: {}", unsafe { member.read().unwrap() });
member.write(&123_u32).unwrap();
```