-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 431d9e8
Showing
9 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/target | ||
.idea |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod input; | ||
pub mod process; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |