Remove `Address` struct

This commit is contained in:
a2x 2024-03-02 01:21:34 +10:00
parent 0bc7cf7b20
commit 7d5de35805
13 changed files with 67 additions and 225 deletions

View File

@ -8,7 +8,7 @@ use simplelog::{debug, info};
use super::{generate_files, Entries, Entry}; use super::{generate_files, Entries, Entry};
use crate::builder::FileBuilderEnum; use crate::builder::FileBuilderEnum;
use crate::os::{Address, Process}; use crate::os::Process;
#[derive(Debug)] #[derive(Debug)]
#[repr(C)] #[repr(C)]
@ -19,7 +19,7 @@ struct InterfaceNode {
} }
impl InterfaceNode { impl InterfaceNode {
fn instance(&self, process: &Process) -> Result<Address> { fn instance(&self, process: &Process) -> Result<usize> {
process process
.read_memory::<usize>( .read_memory::<usize>(
(self as *const _ as usize + offset_of!(InterfaceNode, create_fn)).into(), (self as *const _ as usize + offset_of!(InterfaceNode, create_fn)).into(),

View File

@ -52,11 +52,7 @@ pub fn dump_offsets(
let size = size.unwrap_or(8); let size = size.unwrap_or(8);
for _ in 0..times { for _ in 0..times {
process.read_memory_raw( process.read_memory_raw(address, &mut address as *mut _ as *mut _, size)?;
address,
&mut address.0 as *mut _ as *mut _,
size,
)?;
} }
} }
Jmp { offset, length } => { Jmp { offset, length } => {
@ -69,7 +65,7 @@ pub fn dump_offsets(
let mut result: usize = 0; let mut result: usize = 0;
process.read_memory_raw( process.read_memory_raw(
address.add(start), address + start,
&mut result as *mut _ as *mut _, &mut result as *mut _ as *mut _,
end - start, end - start,
)?; )?;
@ -86,17 +82,17 @@ pub fn dump_offsets(
signature.name, address signature.name, address
); );
(signature.name, address.0) (signature.name, address)
} else { } else {
debug!( debug!(
"Found <bright-yellow>{}</> @ <bright-magenta>{:#X}</> (<blue>{}</> + <bright-blue>{:#X}</>)", "Found <bright-yellow>{}</> @ <bright-magenta>{:#X}</> (<blue>{}</> + <bright-blue>{:#X}</>)",
signature.name, signature.name,
address, address,
signature.module, signature.module,
address.sub(module.base().0) address - module.base()
); );
(signature.name, address.sub(module.base().0).0) (signature.name, address - module.base())
}; };
if name == "dwBuildNumber" { if name == "dwBuildNumber" {

View File

@ -1,137 +0,0 @@
use std::fmt::{LowerHex, UpperHex};
use std::ops::{Add, AddAssign, Sub, SubAssign};
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Address(pub usize);
impl Address {
#[inline]
pub fn add(&self, value: usize) -> Self {
Self(self.0 + value)
}
#[inline]
pub fn is_zero(&self) -> bool {
self.0 == 0
}
#[inline]
pub fn sub(&self, value: usize) -> Self {
Self(self.0 - value)
}
#[inline]
pub fn as_ptr<T>(&self) -> *const T {
self.0 as *const T
}
#[inline]
pub fn as_mut_ptr<T>(&self) -> *mut T {
self.0 as *mut T
}
}
impl From<usize> for Address {
fn from(value: usize) -> Self {
Self(value)
}
}
impl From<*const u8> for Address {
fn from(value: *const u8) -> Self {
Self(value as usize)
}
}
impl From<*mut u8> for Address {
fn from(value: *mut u8) -> Self {
Self(value as usize)
}
}
impl From<Address> for usize {
fn from(value: Address) -> Self {
value.0
}
}
impl From<Address> for *const u8 {
fn from(value: Address) -> Self {
value.0 as *const u8
}
}
impl From<Address> for *mut u8 {
fn from(value: Address) -> Self {
value.0 as *mut u8
}
}
impl Add<usize> for Address {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs)
}
}
impl Add<Address> for Address {
type Output = Self;
fn add(self, rhs: Address) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl AddAssign<usize> for Address {
fn add_assign(&mut self, rhs: usize) {
self.0 += rhs;
}
}
impl AddAssign<Address> for Address {
fn add_assign(&mut self, rhs: Address) {
self.0 += rhs.0;
}
}
impl Sub<usize> for Address {
type Output = Self;
fn sub(self, rhs: usize) -> Self::Output {
Self(self.0 - rhs)
}
}
impl Sub<Address> for Address {
type Output = Self;
fn sub(self, rhs: Address) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl SubAssign<usize> for Address {
fn sub_assign(&mut self, rhs: usize) {
self.0 -= rhs;
}
}
impl SubAssign<Address> for Address {
fn sub_assign(&mut self, rhs: Address) {
self.0 -= rhs.0;
}
}
impl UpperHex for Address {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:#X}", self.0)
}
}
impl LowerHex for Address {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:#x}", self.0)
}
}

View File

@ -1,7 +1,5 @@
pub use address::Address;
pub use module::Module; pub use module::Module;
pub use process::Process; pub use process::Process;
pub mod address;
pub mod module; pub mod module;
pub mod process; pub mod process;

View File

@ -6,8 +6,6 @@ use goblin::pe::options::ParseOptions;
use goblin::pe::section_table::SectionTable; use goblin::pe::section_table::SectionTable;
use goblin::pe::PE; use goblin::pe::PE;
use super::Address;
pub struct Module<'a> { pub struct Module<'a> {
pub name: &'a str, pub name: &'a str,
pub data: &'a [u8], pub data: &'a [u8],
@ -28,8 +26,8 @@ impl<'a> Module<'a> {
} }
#[inline] #[inline]
pub fn base(&self) -> Address { pub fn base(&self) -> usize {
self.pe.image_base.into() self.pe.image_base
} }
#[inline] #[inline]
@ -43,21 +41,21 @@ impl<'a> Module<'a> {
} }
#[inline] #[inline]
pub fn export_by_name(&self, name: &str) -> Option<Address> { pub fn export_by_name(&self, name: &str) -> Option<usize> {
self.pe self.pe
.exports .exports
.iter() .iter()
.find(|e| e.name.unwrap() == name) .find(|e| e.name.unwrap() == name)
.map(|e| (self.pe.image_base + e.rva).into()) .map(|e| self.pe.image_base + e.rva)
} }
#[inline] #[inline]
pub fn import_by_name(&self, name: &str) -> Option<Address> { pub fn import_by_name(&self, name: &str) -> Option<usize> {
self.pe self.pe
.imports .imports
.iter() .iter()
.find(|i| i.name.to_string() == name) .find(|i| i.name.to_string() == name)
.map(|i| (self.pe.image_base + i.rva).into()) .map(|i| self.pe.image_base + i.rva)
} }
#[inline] #[inline]

View File

@ -10,7 +10,7 @@ use windows::Win32::System::Diagnostics::Debug::ReadProcessMemory;
use windows::Win32::System::Diagnostics::ToolHelp::*; use windows::Win32::System::Diagnostics::ToolHelp::*;
use windows::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS}; use windows::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS};
use super::{Address, Module}; use super::Module;
#[derive(Debug)] #[derive(Debug)]
pub struct Process { pub struct Process {
@ -36,7 +36,7 @@ impl Process {
Ok(process) Ok(process)
} }
pub fn find_pattern(&self, module_name: &str, pattern: &str) -> Option<Address> { pub fn find_pattern(&self, module_name: &str, pattern: &str) -> Option<usize> {
let module = self.get_module_by_name(module_name)?; let module = self.get_module_by_name(module_name)?;
let pattern_bytes = Self::pattern_to_bytes(pattern); let pattern_bytes = Self::pattern_to_bytes(pattern);
@ -70,7 +70,7 @@ impl Process {
Ok(modules) Ok(modules)
} }
pub fn read_memory<T>(&self, address: Address) -> Result<T> { pub fn read_memory<T>(&self, address: usize) -> Result<T> {
let mut buffer: T = unsafe { mem::zeroed() }; let mut buffer: T = unsafe { mem::zeroed() };
self.read_memory_raw( self.read_memory_raw(
@ -82,16 +82,11 @@ impl Process {
Ok(buffer) Ok(buffer)
} }
pub fn read_memory_raw( pub fn read_memory_raw(&self, address: usize, buffer: *mut c_void, size: usize) -> Result<()> {
&self,
address: Address,
buffer: *mut c_void,
size: usize,
) -> Result<()> {
unsafe { unsafe {
ReadProcessMemory( ReadProcessMemory(
self.handle, self.handle,
address.as_ptr(), address as *mut _,
buffer, buffer,
size, size,
Some(ptr::null_mut()), Some(ptr::null_mut()),
@ -100,7 +95,7 @@ impl Process {
.map_err(|e| e.into()) .map_err(|e| e.into())
} }
pub fn read_string(&self, address: Address) -> Result<String> { pub fn read_string(&self, address: usize) -> Result<String> {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
for i in 0.. { for i in 0.. {
@ -113,7 +108,7 @@ impl Process {
Ok(String::from_utf8(buffer)?) Ok(String::from_utf8(buffer)?)
} }
pub fn read_string_length(&self, address: Address, length: usize) -> Result<String> { pub fn read_string_length(&self, address: usize, length: usize) -> Result<String> {
let mut buffer = vec![0; length]; let mut buffer = vec![0; length];
self.read_memory_raw(address, buffer.as_mut_ptr() as *mut _, length)?; self.read_memory_raw(address, buffer.as_mut_ptr() as *mut _, length)?;
@ -127,30 +122,26 @@ impl Process {
pub fn resolve_jmp( pub fn resolve_jmp(
&self, &self,
address: Address, address: usize,
offset: Option<usize>, offset: Option<usize>,
length: Option<usize>, length: Option<usize>,
) -> Result<Address> { ) -> Result<usize> {
// The displacement value can be negative. // The displacement value can be negative.
let displacement = self.read_memory::<i32>(address.add(offset.unwrap_or(0x1)))?; let displacement = self.read_memory::<i32>(address + offset.unwrap_or(0x1))?;
Ok(address Ok((address + displacement as usize) + length.unwrap_or(0x5))
.add(length.unwrap_or(0x5))
.add(displacement as usize))
} }
pub fn resolve_rip( pub fn resolve_rip(
&self, &self,
address: Address, address: usize,
offset: Option<usize>, offset: Option<usize>,
length: Option<usize>, length: Option<usize>,
) -> Result<Address> { ) -> Result<usize> {
// The displacement value can be negative. // The displacement value can be negative.
let displacement = self.read_memory::<i32>(address.add(offset.unwrap_or(0x3)))?; let displacement = self.read_memory::<i32>(address + offset.unwrap_or(0x3))?;
Ok(address Ok((address + displacement as usize) + length.unwrap_or(0x7))
.add(length.unwrap_or(0x7))
.add(displacement as usize))
} }
fn get_process_id_by_name(process_name: &str) -> Result<u32> { fn get_process_id_by_name(process_name: &str) -> Result<u32> {
@ -193,7 +184,7 @@ impl Process {
let mut data = vec![0; entry.modBaseSize as usize]; let mut data = vec![0; entry.modBaseSize as usize];
if let Ok(_) = self.read_memory_raw( if let Ok(_) = self.read_memory_raw(
entry.modBaseAddr.into(), entry.modBaseAddr as _,
data.as_mut_ptr() as *mut _, data.as_mut_ptr() as *mut _,
data.len(), data.len(),
) { ) {

View File

@ -2,15 +2,15 @@ use anyhow::Result;
use super::SchemaType; use super::SchemaType;
use crate::os::{Address, Process}; use crate::os::Process;
pub struct SchemaClassFieldData<'a> { pub struct SchemaClassFieldData<'a> {
process: &'a Process, process: &'a Process,
address: Address, address: usize,
} }
impl<'a> SchemaClassFieldData<'a> { impl<'a> SchemaClassFieldData<'a> {
pub fn new(process: &'a Process, address: Address) -> Self { pub fn new(process: &'a Process, address: usize) -> Self {
Self { process, address } Self { process, address }
} }
@ -21,12 +21,9 @@ impl<'a> SchemaClassFieldData<'a> {
} }
pub fn r#type(&self) -> Result<SchemaType> { pub fn r#type(&self) -> Result<SchemaType> {
Ok(SchemaType::new( let address = self.process.read_memory::<usize>(self.address + 0x8)?;
self.process,
self.process Ok(SchemaType::new(self.process, address))
.read_memory::<usize>(self.address + 0x8)?
.into(),
))
} }
pub fn offset(&self) -> Result<u16> { pub fn offset(&self) -> Result<u16> {

View File

@ -2,26 +2,26 @@ use anyhow::Result;
use super::SchemaClassFieldData; use super::SchemaClassFieldData;
use crate::os::{Address, Process}; use crate::os::Process;
pub struct SchemaClassInfo<'a> { pub struct SchemaClassInfo<'a> {
process: &'a Process, process: &'a Process,
address: Address, address: usize,
class_name: String, name: String,
} }
impl<'a> SchemaClassInfo<'a> { impl<'a> SchemaClassInfo<'a> {
pub fn new(process: &'a Process, address: Address, class_name: &str) -> Self { pub fn new(process: &'a Process, address: usize, name: &str) -> Self {
Self { Self {
process, process,
address, address,
class_name: class_name.to_string(), name: name.to_string(),
} }
} }
#[inline] #[inline]
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
&self.class_name &self.name
} }
pub fn fields(&self) -> Result<Vec<SchemaClassFieldData>> { pub fn fields(&self) -> Result<Vec<SchemaClassFieldData>> {
@ -46,14 +46,13 @@ impl<'a> SchemaClassInfo<'a> {
} }
pub fn parent(&self) -> Result<Option<SchemaClassInfo>> { pub fn parent(&self) -> Result<Option<SchemaClassInfo>> {
let address = Address::from(self.process.read_memory::<usize>(self.address + 0x38)?); let address = self.process.read_memory::<usize>(self.address + 0x38)?;
if address.is_zero() { if address == 0 {
return Ok(None); return Ok(None);
} }
let parent = Address::from(self.process.read_memory::<usize>(address + 0x8)?); let parent = self.process.read_memory::<usize>(address + 0x8)?;
let name_ptr = self.process.read_memory::<usize>(parent + 0x8)?; let name_ptr = self.process.read_memory::<usize>(parent + 0x8)?;
let name = self.process.read_string(name_ptr.into())?; let name = self.process.read_string(name_ptr.into())?;

View File

@ -4,11 +4,11 @@ use anyhow::{bail, Result};
use super::SchemaSystemTypeScope; use super::SchemaSystemTypeScope;
use crate::os::{Address, Process}; use crate::os::Process;
pub struct SchemaSystem<'a> { pub struct SchemaSystem<'a> {
process: &'a Process, process: &'a Process,
address: Address, address: usize,
} }
impl<'a> SchemaSystem<'a> { impl<'a> SchemaSystem<'a> {
@ -16,7 +16,7 @@ impl<'a> SchemaSystem<'a> {
let mut address = process.find_pattern( let mut address = process.find_pattern(
"schemasystem.dll", "schemasystem.dll",
"48 8D 0D ? ? ? ? E9 ? ? ? ? CC CC CC CC 48 8D 0D ? ? ? ? E9 ? ? ? ? CC CC CC CC 48 83 EC 28" "48 8D 0D ? ? ? ? E9 ? ? ? ? CC CC CC CC 48 8D 0D ? ? ? ? E9 ? ? ? ? CC CC CC CC 48 83 EC 28"
).expect("Failed to find pattern for SchemaSystem"); ).expect("unable to find schema system pattern");
address = process.resolve_rip(address, None, None)?; address = process.resolve_rip(address, None, None)?;
@ -27,7 +27,7 @@ impl<'a> SchemaSystem<'a> {
let size = self.process.read_memory::<u32>(self.address + 0x190)?; let size = self.process.read_memory::<u32>(self.address + 0x190)?;
if size == 0 { if size == 0 {
bail!("Type scopes size is 0"); bail!("no type scopes found");
} }
let data = self.process.read_memory::<usize>(self.address + 0x198)?; let data = self.process.read_memory::<usize>(self.address + 0x198)?;
@ -42,7 +42,7 @@ impl<'a> SchemaSystem<'a> {
let type_scopes: Vec<SchemaSystemTypeScope> = addresses let type_scopes: Vec<SchemaSystemTypeScope> = addresses
.iter() .iter()
.map(|&address| SchemaSystemTypeScope::new(self.process, address.into())) .map(|&address| SchemaSystemTypeScope::new(self.process, address))
.collect(); .collect();
Ok(type_scopes) Ok(type_scopes)

View File

@ -2,15 +2,15 @@ use anyhow::Result;
use super::{SchemaClassInfo, SchemaTypeDeclaredClass, UtlTsHash}; use super::{SchemaClassInfo, SchemaTypeDeclaredClass, UtlTsHash};
use crate::os::{Address, Process}; use crate::os::Process;
pub struct SchemaSystemTypeScope<'a> { pub struct SchemaSystemTypeScope<'a> {
process: &'a Process, process: &'a Process,
address: Address, address: usize,
} }
impl<'a> SchemaSystemTypeScope<'a> { impl<'a> SchemaSystemTypeScope<'a> {
pub fn new(process: &'a Process, address: Address) -> Self { pub fn new(process: &'a Process, address: usize) -> Self {
Self { process, address } Self { process, address }
} }
@ -22,8 +22,8 @@ impl<'a> SchemaSystemTypeScope<'a> {
let classes: Vec<SchemaClassInfo> = declared_classes let classes: Vec<SchemaClassInfo> = declared_classes
.elements(self.process)? .elements(self.process)?
.iter() .iter()
.filter_map(|&a| { .filter_map(|&class_ptr| {
let address = Address::from(a as usize); let address = class_ptr as usize;
let declared_class = SchemaTypeDeclaredClass::new(self.process, address); let declared_class = SchemaTypeDeclaredClass::new(self.process, address);

View File

@ -6,7 +6,7 @@ use lazy_static::lazy_static;
use regex::Regex; use regex::Regex;
use crate::os::{Address, Process}; use crate::os::Process;
const TYPE_MAP: &[(&'static str, &'static str)] = &[ const TYPE_MAP: &[(&'static str, &'static str)] = &[
("uint8", "uint8_t"), ("uint8", "uint8_t"),
@ -35,11 +35,11 @@ lazy_static! {
pub struct SchemaType<'a> { pub struct SchemaType<'a> {
process: &'a Process, process: &'a Process,
address: Address, address: usize,
} }
impl<'a> SchemaType<'a> { impl<'a> SchemaType<'a> {
pub fn new(process: &'a Process, address: Address) -> Self { pub fn new(process: &'a Process, address: usize) -> Self {
Self { process, address } Self { process, address }
} }

View File

@ -1,20 +1,20 @@
use anyhow::Result; use anyhow::Result;
use crate::os::{Address, Process}; use crate::os::Process;
pub struct SchemaTypeDeclaredClass<'a> { pub struct SchemaTypeDeclaredClass<'a> {
process: &'a Process, process: &'a Process,
address: Address, address: usize,
} }
impl<'a> SchemaTypeDeclaredClass<'a> { impl<'a> SchemaTypeDeclaredClass<'a> {
pub fn new(process: &'a Process, address: Address) -> Self { pub fn new(process: &'a Process, address: usize) -> Self {
Self { process, address } Self { process, address }
} }
pub fn name(&self) -> Result<String> { pub fn name(&self) -> Result<String> {
let name_ptr = self.process.read_memory::<usize>(self.address + 0x8)?; let name_ptr = self.process.read_memory::<usize>(self.address + 0x8)?;
self.process.read_string_length(name_ptr.into(), 64) self.process.read_string_length(name_ptr, 64)
} }
} }

View File

@ -15,7 +15,7 @@ struct HashFixedDataInternal<T, K> {
impl<T, K> HashFixedDataInternal<T, K> { impl<T, K> HashFixedDataInternal<T, K> {
fn next(&self, process: &Process) -> Result<*mut HashFixedDataInternal<T, K>> { fn next(&self, process: &Process) -> Result<*mut HashFixedDataInternal<T, K>> {
process.read_memory::<*mut HashFixedDataInternal<T, K>>( process.read_memory::<*mut HashFixedDataInternal<T, K>>(
(self as *const _ as usize + offset_of!(HashFixedDataInternal<T, K>, next)).into(), (self as *const _ as usize + offset_of!(HashFixedDataInternal<T, K>, next)) as _,
) )
} }
} }
@ -31,7 +31,7 @@ struct HashBucketDataInternal<T, K> {
impl<T, K> HashBucketDataInternal<T, K> { impl<T, K> HashBucketDataInternal<T, K> {
fn next(&self, process: &Process) -> Result<*mut HashFixedDataInternal<T, K>> { fn next(&self, process: &Process) -> Result<*mut HashFixedDataInternal<T, K>> {
process.read_memory::<*mut HashFixedDataInternal<T, K>>( process.read_memory::<*mut HashFixedDataInternal<T, K>>(
(self as *const _ as usize + offset_of!(HashBucketDataInternal<T, K>, next)).into(), (self as *const _ as usize + offset_of!(HashBucketDataInternal<T, K>, next)) as _,
) )
} }
} }
@ -46,7 +46,7 @@ pub struct HashAllocatedData<T, K> {
impl<T, K> HashAllocatedData<T, K> { impl<T, K> HashAllocatedData<T, K> {
fn list(&self, process: &Process) -> Result<[HashFixedDataInternal<T, K>; 128]> { fn list(&self, process: &Process) -> Result<[HashFixedDataInternal<T, K>; 128]> {
process.read_memory::<[HashFixedDataInternal<T, K>; 128]>( process.read_memory::<[HashFixedDataInternal<T, K>; 128]>(
(self as *const _ as usize + offset_of!(HashAllocatedData<T, K>, list)).into(), (self as *const _ as usize + offset_of!(HashAllocatedData<T, K>, list)) as _,
) )
} }
} }
@ -64,19 +64,19 @@ struct HashUnallocatedData<T, K> {
impl<T, K> HashUnallocatedData<T, K> { impl<T, K> HashUnallocatedData<T, K> {
fn next(&self, process: &Process) -> Result<*mut HashUnallocatedData<T, K>> { fn next(&self, process: &Process) -> Result<*mut HashUnallocatedData<T, K>> {
process.read_memory::<*mut HashUnallocatedData<T, K>>( process.read_memory::<*mut HashUnallocatedData<T, K>>(
(self as *const _ as usize + offset_of!(HashUnallocatedData<T, K>, next)).into(), (self as *const _ as usize + offset_of!(HashUnallocatedData<T, K>, next)) as _,
) )
} }
fn ui_key(&self, process: &Process) -> Result<K> { fn ui_key(&self, process: &Process) -> Result<K> {
process.read_memory::<K>( process.read_memory::<K>(
(self as *const _ as usize + offset_of!(HashUnallocatedData<T, K>, ui_key)).into(), (self as *const _ as usize + offset_of!(HashUnallocatedData<T, K>, ui_key)) as _,
) )
} }
fn block_list(&self, process: &Process) -> Result<[HashBucketDataInternal<T, K>; 256]> { fn block_list(&self, process: &Process) -> Result<[HashBucketDataInternal<T, K>; 256]> {
process.read_memory::<[HashBucketDataInternal<T, K>; 256]>( process.read_memory::<[HashBucketDataInternal<T, K>; 256]>(
(self as *const _ as usize + offset_of!(HashUnallocatedData<T, K>, block_list)).into(), (self as *const _ as usize + offset_of!(HashUnallocatedData<T, K>, block_list)) as _,
) )
} }
} }