Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Muqito committed Jan 1, 2021
0 parents commit 431d9e8
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
.idea
30 changes: 30 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "change-memory-value"
version = "0.1.0"
authors = ["Christoffer Lantz <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
winapi = { version = "*", features = ["winuser", "wingdi", "libloaderapi", "memoryapi", "winnt", "processthreadsapi", "tlhelp32", "impl-default"] }
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Memory modify
This is just an example of how you can modify other programs memory in Windows

## Example
Start a process you'd like to modify memory on, ex. the provided example
```
cargo run --example modify-memory
```

Also run our main program in order to modify memory
```
cargo run
```

## Questions

### Can I write to a random memory without winapi?
No you cannot; not without being in ring0/acting as a kernel-driver(?) going outside the OS level

https://stackoverflow.com/questions/25599701/how-do-i-edit-random-memory
25 changes: 25 additions & 0 deletions examples/modify-memory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use std::ffi::CString;

fn main() {
let program_name = CString::new("modify-memory.exe").unwrap();
let mut value = -1;
let ptr_x = &mut value as *mut i32;
let module_addr =
unsafe { winapi::um::libloaderapi::GetModuleHandleA(program_name.as_ptr() as *const i8) };
println!(
"My pid: {}, value_ptr_addr: {:p}, base_addr: {:p}",
std::process::id(),
ptr_x,
module_addr
);
println!("Initial value: {}", value);

let mut old_value = value;
loop {
if value != old_value {
old_value = value;
println!("New value: {}", value);
}
std::thread::sleep(std::time::Duration::from_millis(200));
}
}
17 changes: 17 additions & 0 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use change_memory_value::input::{read_input, read_memory_addr};
use change_memory_value::process::{open_process, write_to_process};

fn main() {
let proc_id: u32 = read_input("What process id?").expect("No process id?");
let addr = read_memory_addr("What memory addr?").expect("No memory addr?");

let handle = open_process(proc_id).expect("No handle");

loop {
let new_value: usize = read_input("New value?").unwrap();

if !write_to_process(handle, addr, new_value) {
break;
}
}
}
23 changes: 23 additions & 0 deletions src/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pub fn read_input<T>(prompt: impl std::fmt::Display) -> Option<T>
where
T: std::str::FromStr,
{
println!("{}", prompt);
let mut input = String::new();
if let Err(_) = std::io::stdin().read_line(&mut input) {
return None;
}

input = input.trim().parse().unwrap();

T::from_str(&input).ok()
}
pub fn read_memory_addr(prompt: impl std::fmt::Display) -> Option<usize> {
println!("{}", prompt);
let mut input = String::new();
if let Err(_) = std::io::stdin().read_line(&mut input) {
return None;
}

usize::from_str_radix(input.trim_start_matches("0x").trim_end(), 16).ok()
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod input;
pub mod process;
84 changes: 84 additions & 0 deletions src/process.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use std::ffi::CString;
use winapi::shared::minwindef::DWORD;
use winapi::shared::windef::HWND;
use winapi::um::memoryapi::WriteProcessMemory;
use winapi::um::processthreadsapi::OpenProcess;
use winapi::um::tlhelp32::{
CreateToolhelp32Snapshot, Process32Next, PROCESSENTRY32, TH32CS_SNAPALL,
};
use winapi::um::winnt::PROCESS_ALL_ACCESS;
use winapi::um::winuser::{FindWindowA, GetWindowThreadProcessId};

type Handle = winapi::ctypes::c_void;
#[derive(Debug)]
pub enum WindowHandleError {
NoWindow,
NoProcess,
NoHandle,
Unknown,
}
pub fn open_process(proc_id: u32) -> Result<*mut Handle, WindowHandleError> {
let handle = unsafe { OpenProcess(PROCESS_ALL_ACCESS, 0, proc_id as DWORD) };

match handle != std::ptr::null_mut() {
true => Ok(handle),
false => Err(WindowHandleError::NoHandle),
}
}
pub fn find_window(window_name: &str) -> Result<u32, WindowHandleError> {
let hwnd: HWND = unsafe {
let window_name = match CString::new(window_name) {
Ok(value) => value,
Err(_) => return Err(WindowHandleError::Unknown),
};
FindWindowA(std::ptr::null(), window_name.as_ptr() as *const i8)
};
if hwnd.is_null() {
return Err(WindowHandleError::NoWindow);
}
let proc_id = unsafe { GetWindowThreadProcessId(hwnd as HWND, std::ptr::null_mut()) };
match proc_id {
0 => Err(WindowHandleError::NoProcess),
id => Ok(id),
}
}
pub unsafe fn get_process_name(process_entry: &PROCESSENTRY32) -> String {
std::ffi::CStr::from_ptr(&process_entry.szExeFile[0])
.to_string_lossy()
.into_owned()
}
pub fn get_process_list() -> Vec<String> {
let mut processes = vec![];
unsafe {
let handle = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
let mut pe32 = std::mem::zeroed::<PROCESSENTRY32>();
pe32.dwSize = std::mem::size_of::<PROCESSENTRY32>() as DWORD;

while Process32Next(handle, &mut pe32) != 0 {
if pe32.th32ProcessID == 0 {
continue;
}
let name = get_process_name(&pe32);
/* let pid = DWORD::from(pe32.th32ProcessID.clone());
let process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid.clone());*/

processes.push(name);
}
};
return processes;
}

pub fn write_to_process<T>(handle: *mut Handle, addr: usize, new_value: T) -> bool {
let mut input = new_value;
let written = unsafe {
WriteProcessMemory(
handle,
addr as *mut _,
&mut input as *mut _ as *mut _,
std::mem::size_of::<T>(),
std::ptr::null_mut(),
)
};

written != 0
}

0 comments on commit 431d9e8

Please sign in to comment.