Implement read/write memory
This commit is contained in:
Родитель
c6da286630
Коммит
07ca23ee42
|
@ -11,7 +11,7 @@ bytes = "0.6"
|
|||
log = "0.4.11"
|
||||
pretty_env_logger = "0.4.0"
|
||||
tokio = { version = "0.3.3", features = ["net", "rt-multi-thread", "io-util"] }
|
||||
winapi = { version = "0.3.9", features = ["processthreadsapi", "tlhelp32"], optional = true }
|
||||
winapi = { version = "0.3.9", features = ["memoryapi", "processthreadsapi", "tlhelp32"], optional = true }
|
||||
|
||||
|
||||
[features]
|
||||
|
|
|
@ -161,3 +161,50 @@ impl CERequest for GetSymbolListFromFileRequest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReadProcessMemoryRequest {
|
||||
pub handle: u32,
|
||||
pub address: u64,
|
||||
pub size: u32,
|
||||
pub compress: bool,
|
||||
}
|
||||
|
||||
impl CERequest for ReadProcessMemoryRequest {
|
||||
type Response = ReadProcessMemoryResponse;
|
||||
|
||||
const ID: Command = CMD_READPROCESSMEMORY;
|
||||
|
||||
fn read(buf: &mut dyn Buf) -> Self {
|
||||
Self {
|
||||
handle: buf.get_u32_le(),
|
||||
address: buf.get_u64_le(),
|
||||
size: buf.get_u32_le(),
|
||||
compress: buf.get_u8() != 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WriteProcessMemoryRequest {
|
||||
pub handle: u32,
|
||||
pub address: u64,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl CERequest for WriteProcessMemoryRequest {
|
||||
type Response = WriteProcessMemoryResponse;
|
||||
|
||||
const ID: Command = CMD_WRITEPROCESSMEMORY;
|
||||
|
||||
fn read(buf: &mut dyn Buf) -> Self {
|
||||
Self {
|
||||
handle: buf.get_u32_le(),
|
||||
address: buf.get_u64_le(),
|
||||
data: {
|
||||
let len = buf.get_u32_le();
|
||||
Vec::from(buf.take(len as usize).bytes())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,28 @@ pub struct GetSymbolListFromFileResponse; // TODO implement
|
|||
impl CEResponse for GetSymbolListFromFileResponse {
|
||||
fn serialize(self, writer: &mut dyn BufMut) {
|
||||
// writing 0 for now
|
||||
writer.put_i32(0);
|
||||
writer.put_i32_le(0);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReadProcessMemoryResponse {
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl CEResponse for ReadProcessMemoryResponse {
|
||||
fn serialize(self, writer: &mut dyn BufMut) {
|
||||
writer.put_slice(&self.data[..]);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WriteProcessMemoryResponse {
|
||||
pub written: u32,
|
||||
}
|
||||
|
||||
impl CEResponse for WriteProcessMemoryResponse {
|
||||
fn serialize(self, writer: &mut dyn BufMut) {
|
||||
writer.put_u32_le(self.written);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ pub trait FullHandler:
|
|||
+ Handler<GetArchitectureRequest>
|
||||
+ Handler<OpenProcessRequest>
|
||||
+ Handler<GetSymbolListFromFileRequest>
|
||||
+ Handler<ReadProcessMemoryRequest>
|
||||
+ Handler<WriteProcessMemoryRequest>
|
||||
{
|
||||
fn create() -> Self;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use crate::server::{ce_common::*, commands_request::*, commands_response::*, handler::*};
|
||||
use log::warn;
|
||||
use winapi::{
|
||||
shared::minwindef::FALSE,
|
||||
shared::minwindef::{FALSE, LPCVOID, LPVOID},
|
||||
um::{
|
||||
handleapi::CloseHandle,
|
||||
memoryapi::ReadProcessMemory,
|
||||
memoryapi::WriteProcessMemory,
|
||||
processthreadsapi::OpenProcess,
|
||||
tlhelp32::{
|
||||
CreateToolhelp32Snapshot, Module32First, Module32Next, Process32First, Process32Next,
|
||||
|
@ -50,7 +52,7 @@ where
|
|||
F: FnOnce(HANDLE, LPPROCESSENTRY32) -> i32,
|
||||
{
|
||||
let mut entry = std::mem::MaybeUninit::uninit().assume_init();
|
||||
let response = func(std::mem::transmute(handle), &mut entry);
|
||||
let response = func(handle as HANDLE, &mut entry);
|
||||
|
||||
if response != 0 {
|
||||
Process32Response {
|
||||
|
@ -81,7 +83,7 @@ where
|
|||
F: FnOnce(HANDLE, LPMODULEENTRY32) -> i32,
|
||||
{
|
||||
let mut entry = std::mem::MaybeUninit::uninit().assume_init();
|
||||
let response = func(std::mem::transmute(handle), &mut entry);
|
||||
let response = func(handle as HANDLE, &mut entry);
|
||||
|
||||
if response != 0 {
|
||||
Module32Response {
|
||||
|
@ -99,7 +101,7 @@ where
|
|||
impl Handler<CloseHandleRequest> for WindowsHandler {
|
||||
fn handle(&self, req: CloseHandleRequest) -> I32Response {
|
||||
unsafe {
|
||||
let response = CloseHandle(std::mem::transmute(req.handle));
|
||||
let response = CloseHandle(req.handle as HANDLE);
|
||||
|
||||
I32Response { response }
|
||||
}
|
||||
|
@ -133,3 +135,54 @@ impl Handler<GetSymbolListFromFileRequest> for WindowsHandler {
|
|||
GetSymbolListFromFileResponse
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<ReadProcessMemoryRequest> for WindowsHandler {
|
||||
fn handle(&self, req: ReadProcessMemoryRequest) -> ReadProcessMemoryResponse {
|
||||
let mut buffer = vec![0u8; req.size as usize];
|
||||
let mut bytes_read = 0;
|
||||
let _resp = unsafe {
|
||||
ReadProcessMemory(
|
||||
req.handle as HANDLE,
|
||||
req.address as LPVOID,
|
||||
buffer.as_mut_ptr() as LPVOID,
|
||||
req.size as usize,
|
||||
&mut bytes_read,
|
||||
)
|
||||
};
|
||||
if req.compress {
|
||||
todo!()
|
||||
} else {
|
||||
ReadProcessMemoryResponse { data: buffer }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<WriteProcessMemoryRequest> for WindowsHandler {
|
||||
fn handle(&self, req: WriteProcessMemoryRequest) -> WriteProcessMemoryResponse {
|
||||
unsafe {
|
||||
let mut written = 0usize;
|
||||
let mut data = req.data;
|
||||
let success = WriteProcessMemory(
|
||||
req.handle as HANDLE,
|
||||
req.address as LPVOID,
|
||||
data.as_mut_ptr() as LPCVOID,
|
||||
data.len(),
|
||||
&mut written,
|
||||
);
|
||||
|
||||
if success == 0 {
|
||||
warn!("Writing memory failed");
|
||||
} else if written != data.len() {
|
||||
warn!(
|
||||
"Expected to write {} bytes but wrote {}",
|
||||
data.len(),
|
||||
written
|
||||
);
|
||||
}
|
||||
|
||||
WriteProcessMemoryResponse {
|
||||
written: written as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,6 +94,8 @@ impl CheatEngineConnection {
|
|||
GetArchitectureRequest,
|
||||
OpenProcessRequest,
|
||||
GetSymbolListFromFileRequest,
|
||||
ReadProcessMemoryRequest,
|
||||
WriteProcessMemoryRequest,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче