tommoa / rs-process-memory Goto Github PK
View Code? Open in Web Editor NEWA rust library that allows you to read/write into the memory of other processes
License: MIT License
A rust library that allows you to read/write into the memory of other processes
License: MIT License
Hi, Thank you for creating this library.
I'm trying to do this:
let data= unsafe { DataMember::<i64>::new_offset(handle, vec![offset]).read() };
let data2 = unsafe { DataMember::<i32>::new_offset(handle, vec![data, another_offset]).read() };
but since the offset cannot be anything other than usize
I have to cast the data as usize and therefore it corrupts the data.
I'm doing the exact same thing in c#:
Int64 data = _mem.Read<long>(offset); //i64
Int32 data2 = _mem.ReadInt<Int32>(data, another_offset); //i32
so Is it possible to have a generic
T that could be anything (number ofc) rather than just limiting the parameter to usize
?
Currently there are no good libraries for Read/Write actions against Processes that is cross platform (I'd love to be wrong about this), it would be great to expose parts of this library for use by external programs. I figure the main 4-5 functions would be something like the following. Subject to change if you want the library to support hooking only into one PID at a time, or multiple.
get_process_handle_from_pid(pid) -> ProcessHandle
- Assume the calling application can find the target PID.
free_process_handle(process_handle)
- Let Rust handle freeing the process handle.
read_process(process_handle, address, size, *mut buffer)
- Read Process's Memory at address
into a provided buffer
We assume the buffer is properly sized to size
write_process(process_handle, address, size, *mut buffer)
- Same a read_process
, but writing instead. Potentially return a Boolean?
get_last_error() -> str
- Having Rust blowing up the calling thread is a bit frustrating for the other application, so it would be nice to cache the error.
Regarding it being a cdylib
vs dylib
, it would fit my use case the best.
Having DataMember
s do all the handling of architectures makes things very verbose, especially once there's a large number of DataMember
s in use.
It's likely to be incredibly rare that a pointer inside a process is of a different size to any other pointer (unless for some reason the writers are avid users of relative pointers), so if we can somehow put the architecture as a part of the ProcessHandle
instead of the DataMember
, it'll make the API a lot more pleasing.
This can probably be done by changing ProcessHandle
from just being a type wrapper to being an actual struct which contains the architecture enum.
Hi, I'm trying to connect to the Calculator
app and I'm seeing Undefined error: 0 (os error 0)
while running this program with sudo.
use std::{env, error::Error};
use process_memory::*;
struct InputPid {
pid: u32
}
impl InputPid {
fn new(args: &[String]) -> Result<InputPid, Box<dyn Error>> {
if args.len() < 2 {
return Err("Please enter a pid".into());
}
let arg = &args[1];
let pid: u32 = arg.trim().parse().map_err(|_e| format!("Please enter a pid - got: {}", arg))?;
Ok(InputPid { pid })
}
}
fn main() {
let args: Vec<String> = env::args().collect();
let input_pid = InputPid::new(&args).unwrap();
println!("{}", input_pid.pid);
let handle: ProcessHandle = (input_pid.pid as Pid).try_into_process_handle()
.map_err(|e| format!("Could not connect to pid {}: {}", input_pid.pid, e)).unwrap()
.set_arch(Architecture::Arch64Bit);
}
Any ideas how to debug this? I'm on macOS 10.15.7
. Thanks
Admittedly I'm not sure if this crate is still maintained but I'm not aware of any good alternatives.
Something I've recently come across is that it appears that the DataMember::read
function is unsound. Since the only restrictions on T
is that it is Sized + Copy
, it is possible that casting the buffer pointer to *const T
and subsequent reading of it may be undefined behavior if the bit pattern contained in the buffer doesn't correspond to a valid T
. This most clearly a potential issue when reading a bool
which can only be 0 or 1, but could also be an issue for an enum.
I was debugging why something isn't working, and then I realized CopyAddress::get_offset()
is copying too many bytes. My program is 64bit, whereas the game I read from is 32bit.
I believe the culprit is this:
rs-process-memory/src/windows.rs
Line 46 in 5bd1055
from_native()
here? I thought the whole point of having Architecture was to support reading from 32bit processes? Gonna work on a fix while waiting for replies.
If I miss something, sorry, I'm new to rust :).
I was able to read strings using this
// Oh god oh fuck I'm sorry I need to find a better way to do this
pub fn try_read_string(handle: process_memory::ProcessHandle, mut starting_offsets: Vec<usize>, buffer_size : i32) -> Result<String, std::io::Error> {
//Read String 4 in 4 bytes
use process_memory::*;
use std::mem::transmute;
let number_of_passes: f32 = buffer_size as f32 / 4.0;
let last_offset = starting_offsets.pop().unwrap();
let offsets: Vec<usize> = starting_offsets.clone();
let mut string_return = String::new();
'outer: for i in 0..(number_of_passes.ceil() as i32) {
let player_name = DataMember::<u32>::new_offset(handle, [offsets.clone(), vec![last_offset + (4*i as usize)]].concat());
let bytes: [u8; 4] = unsafe { transmute(player_name.read()?.to_le()) };
for byte in bytes.iter() {
if *byte != 0x0_u8 {
string_return.push(*byte as char);
} else {
break 'outer;
}
}
}
return Ok(string_return);
}
it works but is there a way to do it without all this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.