96 lines
3.0 KiB
Rust
96 lines
3.0 KiB
Rust
use memflow::{mem::MemoryView, types::Address, os::ModuleInfo};
|
|
use crate::pattern::pattern_scan;
|
|
|
|
const BUF_SIZE: usize = 3;
|
|
|
|
pub struct MoneyReveal {
|
|
pub is_enabled: bool,
|
|
pub address: Option<Address>,
|
|
original_bytes: Option<[u8; BUF_SIZE]>,
|
|
}
|
|
|
|
impl MoneyReveal {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
is_enabled: false,
|
|
address: None,
|
|
original_bytes: None,
|
|
}
|
|
}
|
|
|
|
pub fn init(&mut self, mem: &mut impl MemoryView, client_module: &ModuleInfo) -> anyhow::Result<()> {
|
|
self.address = self.find_function(mem, client_module)?;
|
|
log::info!("Money reveal function found at: {:?}", self.address);
|
|
Ok(())
|
|
}
|
|
|
|
pub fn toggle(&mut self, mem: &mut impl MemoryView) -> anyhow::Result<bool> {
|
|
if let Some(addr) = self.address {
|
|
if self.is_enabled {
|
|
if let Some(original) = self.original_bytes {
|
|
self.restore(mem, addr, original)?;
|
|
self.original_bytes = None;
|
|
self.is_enabled = false;
|
|
}
|
|
} else {
|
|
let original = self.patch(mem, addr)?;
|
|
self.original_bytes = Some(original);
|
|
self.is_enabled = true;
|
|
}
|
|
Ok(self.is_enabled)
|
|
} else {
|
|
Err(anyhow::anyhow!("Money reveal not initialized"))
|
|
}
|
|
}
|
|
|
|
pub fn ensure_disabled(&mut self, mem: &mut impl MemoryView) -> anyhow::Result<()> {
|
|
if self.is_enabled {
|
|
if let Some(addr) = self.address {
|
|
if let Some(original) = self.original_bytes {
|
|
self.restore(mem, addr, original)?;
|
|
self.is_enabled = false;
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn find_function(&self, mem: &mut impl MemoryView, module: &ModuleInfo) -> anyhow::Result<Option<Address>> {
|
|
let is_hltv = pattern_scan(
|
|
mem,
|
|
module,
|
|
"48 83 EC 28 48 8B 0D ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 84 C0 75 0D"
|
|
)?;
|
|
|
|
if is_hltv.is_none() {
|
|
Ok(pattern_scan(
|
|
mem,
|
|
module,
|
|
"B0 01 C3 28 48 8B 0D ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 84 C0 75 0D"
|
|
)?)
|
|
} else {
|
|
Ok(is_hltv)
|
|
}
|
|
}
|
|
|
|
fn patch(&self, mem: &mut impl MemoryView, location: Address) -> anyhow::Result<[u8; BUF_SIZE]> {
|
|
let mut original_buf = [0u8; BUF_SIZE];
|
|
mem.read_into(location, &mut original_buf)?;
|
|
|
|
let new_buf: [u8; BUF_SIZE] = [
|
|
0xB0, 0x01, // MOV AL,1
|
|
0xC3 // RET
|
|
];
|
|
|
|
log::debug!("Patching memory for money reveal");
|
|
mem.write(location, &new_buf)?;
|
|
|
|
Ok(original_buf)
|
|
}
|
|
|
|
fn restore(&self, mem: &mut impl MemoryView, location: Address, original: [u8; BUF_SIZE]) -> anyhow::Result<()> {
|
|
log::debug!("Restoring memory for money reveal");
|
|
mem.write(location, &original)?;
|
|
Ok(())
|
|
}
|
|
} |