From f876cd4b7e1e717b87ef44edafafa22ee3015ff0 Mon Sep 17 00:00:00 2001 From: Atorizil <42285104+Atorizil@users.noreply.github.com> Date: Wed, 23 Aug 2023 21:17:23 +0100 Subject: [PATCH] feat: Merge version string & image size into struct --- src/find_process.rs | 11 ++-- src/main.rs | 4 +- src/process_details.rs | 114 +++++++++++++++++++++++++++-------------- 3 files changed, 84 insertions(+), 45 deletions(-) diff --git a/src/find_process.rs b/src/find_process.rs index c5199dc..0189027 100644 --- a/src/find_process.rs +++ b/src/find_process.rs @@ -13,15 +13,16 @@ pub fn find_process( let handle = pid.try_into_process_handle().ok()?; let base_addr = get_base_address(pid) as *const _ as usize; - if force_version == Some(details.version.clone()) { + if force_version == Some(details.version.version.clone()) { println!( "Warning: Forcing version to {}, some functions may not work as expected!", - details.version + details.version.version ); return Some((pid, handle, base_addr, details.clone())); } - if let Some(image_size) = details.image_size { + // Try using the image size first, then the version string + if let Some(image_size) = details.version.image_size { let a = get_image_size(handle, base_addr).ok()?; if image_size != a { return None; @@ -34,11 +35,11 @@ pub fn find_process( handle, details.address_offsets.get(&AddressType::Version)?.clone(), base_addr, - details.version.len(), + details.version.version.len(), ) .ok()?; - if version_in_memory != details.version { + if version_in_memory != details.version.version { None } else { Some((pid, handle, base_addr, details.clone())) diff --git a/src/main.rs b/src/main.rs index 9c88c71..1092d91 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,7 +49,7 @@ fn connect( base_addr: usize, details: ProcessDetails ) { - println!("Connecting to {} {} with PID {}", details.name, details.version, pid); + println!("Connecting to {} {} with PID {}", details.name, details.version.version, pid); let mut handlers: Vec> = vec![]; @@ -126,7 +126,7 @@ fn connect( loop { if !find_process::is_process_running(pid) { - println!("Disconnected from {} {} with PID {}", details.name, details.version, pid); + println!("Disconnected from {} {} with PID {}", details.name, details.version.version, pid); return; } diff --git a/src/process_details.rs b/src/process_details.rs index 134523c..ebf9e52 100644 --- a/src/process_details.rs +++ b/src/process_details.rs @@ -6,9 +6,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Tomb Raider 2013", "TombRaider.exe", - "v1.01.748.0", + VersionIdentifier { + version: String::from("v1.01.748.0"), + image_size: None, + }, Architecture::Arch32Bit, - None, vec![ (AddressType::Version, vec![0x01_0E_65_98]), (AddressType::XPosition, vec![0x00_F3_9E_18, 0x00]), @@ -24,9 +26,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Tomb Raider 2013", "TombRaider.exe", - "v1.1 build 838.0_32", + VersionIdentifier { + version: String::from("v1.1 build 838.0_32"), + image_size: None, + }, Architecture::Arch32Bit, - None, vec![ (AddressType::Version, vec![0x01_DD_BB_F4, 0xF0]), (AddressType::XPosition, vec![0x00_A7_88_F0, 0x00]), @@ -42,9 +46,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Tomb Raider 2013", "TombRaider.exe", - "(Steam) v1.01.0.0", + VersionIdentifier { + version: String::from("(Steam) v1.01.0.0"), + image_size: Some(38543360), + }, Architecture::Arch32Bit, - Some(38543360), vec![ (AddressType::Version, vec![0x01_07_C8_98]), (AddressType::XPosition, vec![0x00_A7_88_F0, 0x00]), @@ -60,9 +66,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Tomb Raider 2013", "TombRaider.exe", - "(Epic Games) v1.01.0.0", + VersionIdentifier { + version: String::from("(Epic Games) v1.01.0.0"), + image_size: Some(38535168), + }, Architecture::Arch32Bit, - Some(38535168), vec![ (AddressType::Version, vec![0x01_07_B3_D8]), (AddressType::XPosition, vec![0x00_A7_76_60, 0x00]), @@ -78,9 +86,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Rise of the Tomb Raider", "ROTTR.exe", - "v1.0 build 820.0_64", + VersionIdentifier { + version: String::from("v1.0 build 820.0_64"), + image_size: None, + }, Architecture::Arch64Bit, - None, vec![ (AddressType::Version, vec![0x01_06_6B_80, 0x90, 0x0238, 0x0]), (AddressType::XPosition, vec![0x01_08_2A_B8, 0x10]), @@ -99,9 +109,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Rise of the Tomb Raider", "ROTTR.exe", - "v1.0 build 1027.0_64", + VersionIdentifier { + version: String::from("v1.0 build 1027.0_64"), + image_size: None, + }, Architecture::Arch64Bit, - None, vec![ (AddressType::Version, vec![0x02_E7_85_F8, 0x1E0]), (AddressType::XPosition, vec![0x01_0F_C8_C8, 0x10]), @@ -117,9 +129,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Rise of the Tomb Raider", "ROTTR.exe", - "(Steam) v1.0 build 0.0_64", + VersionIdentifier { + version: String::from("(Steam) v1.0 build 0.0_64"), + image_size: Some(58654720), + }, Architecture::Arch64Bit, - Some(58654720), vec![ (AddressType::Version, vec![0x02_E7_76_58, 0x1E0]), (AddressType::XPosition, vec![0x01_0F_B8_C8, 0x10]), @@ -135,9 +149,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Rise of the Tomb Raider", "ROTTR.exe", - "(Epic Games) v1.0 build 1027.0_64", + VersionIdentifier { + version: String::from("(Epic Games) v1.0 build 1027.0_64"), + image_size: Some(57122816), + }, Architecture::Arch64Bit, - Some(57122816), vec![ (AddressType::Version, vec![0x02_CF_88_E8, 0x1F8]), (AddressType::XPosition, vec![0x01_0E_6D_D8, 0x10]), @@ -153,9 +169,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Shadow of the Tomb Raider", "SOTTR.exe", - "v1.0 build 234.1_64", + VersionIdentifier { + version: String::from("v1.0 build 234.1_64"), + image_size: None, + }, Architecture::Arch64Bit, - None, vec![ (AddressType::Version, vec![0x03_62_1B_00, 0xD8, 0x0B70]), (AddressType::XPosition, vec![0x01_3D_5F_B8, 0x10]), @@ -185,9 +203,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Shadow of the Tomb Raider", "SOTTR.exe", - "v1.0 build 298.0_64", + VersionIdentifier { + version: String::from("v1.0 build 298.0_64"), + image_size: None, + }, Architecture::Arch64Bit, - None, vec![ (AddressType::Version, vec![0x03_6B_7B_B0, 0xD8, 0x0B60]), (AddressType::XPosition, vec![0x02_FF_34_70]), @@ -212,9 +232,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Shadow of the Tomb Raider", "SOTTR.exe", - "v1.0 build 458.0_64", + VersionIdentifier { + version: String::from("v1.0 build 458.0_64"), + image_size: None, + }, Architecture::Arch64Bit, - None, vec![ (AddressType::Version, vec![0x03_6C_1B_60, 0x108, 0x30, 0x30]), (AddressType::XPosition, vec![0x01_46_90_B8, 0x10]), @@ -238,9 +260,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Shadow of the Tomb Raider", "SOTTR.exe", - "v1.0 build 489.0_64", + VersionIdentifier { + version: String::from("v1.0 build 489.0_64"), + image_size: None, + }, Architecture::Arch64Bit, - None, vec![ (AddressType::Version, vec![0x03_6C_5B_40, 0x108, 0x258, 0x0]), (AddressType::XPosition, vec![0x01_46_D0_B8, 0x10]), @@ -264,9 +288,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Shadow of the Tomb Raider", "SOTTR.exe", - "(Epic Games) v1.0 build 492.0_64", + VersionIdentifier { + version: String::from("(Epic Games) v1.0 build 492.0_64"), + image_size: Some(72794112), + }, Architecture::Arch64Bit, - Some(72794112), vec![ (AddressType::Version, vec![0x03_51_79_A0, 0x108, 0x258, 0x0]), (AddressType::XPosition, vec![0x01_45_1F_78, 0x10]), @@ -276,7 +302,10 @@ pub fn known_process_details() -> Vec { (AddressType::CutsceneStatus, vec![0x01_49_7A_C0, 0x129]), (AddressType::CutsceneTimeline, vec![0x01_49_7A_C0, 0x60]), (AddressType::CutsceneLength, vec![0x01_49_7A_A0, 0x00, 0x20]), - (AddressType::CutsceneId, vec![0x03_50_3F_78, 0x0, 0xB78, 0x574],), + ( + AddressType::CutsceneId, + vec![0x03_50_3F_78, 0x0, 0xB78, 0x574], + ), ] .iter() .cloned() @@ -285,9 +314,11 @@ pub fn known_process_details() -> Vec { ProcessDetails::new( "Shadow of the Tomb Raider", "SOTTR.exe", - "(Steam) v1.0 build 492.0_64", + VersionIdentifier { + version: String::from("(Steam) v1.0 build 492.0_64"), + image_size: Some(73662464), + }, Architecture::Arch64Bit, - Some(73662464), vec![ (AddressType::Version, vec![0x03_6C_5B_40, 0x108, 0x258, 0x0]), (AddressType::XPosition, vec![0x01_46_D0_B8, 0x10]), @@ -297,7 +328,10 @@ pub fn known_process_details() -> Vec { (AddressType::CutsceneStatus, vec![0x01_4B_31_40, 0x129]), (AddressType::CutsceneTimeline, vec![0x01_4B_31_40, 0x60]), (AddressType::CutsceneLength, vec![0x01_4B_31_20, 0x00, 0x20]), - (AddressType::CutsceneId, vec![0x03_6B_21_18, 0x0, 0xB78, 0x574]), + ( + AddressType::CutsceneId, + vec![0x03_6B_21_18, 0x0, 0xB78, 0x574], + ), ] .iter() .cloned() @@ -330,15 +364,21 @@ pub enum AddressType { pub type AddressOffsets = HashMap>; +#[derive(Debug, Clone)] +pub struct VersionIdentifier { + // Version string + pub version: String, + // Size of the image in memory. Used to differentiate between Steam and Epic Games versions since they share the same version string + // https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-windows-specific-fields-image-only + pub image_size: Option, +} + #[derive(Debug, Clone)] pub struct ProcessDetails { pub name: String, pub executable_name: String, - pub version: String, + pub version: VersionIdentifier, pub arch: Architecture, - // Size of the image in memory. Used to differentiate between Steam and Epic Games versions since they share the same version - // https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-windows-specific-fields-image-only - pub image_size: Option, pub address_offsets: AddressOffsets, } @@ -346,17 +386,15 @@ impl ProcessDetails { fn new( name: &str, executable_name: &str, - version: &str, + version: VersionIdentifier, arch: Architecture, - image_size: Option, address_offsets: AddressOffsets, ) -> ProcessDetails { ProcessDetails { name: String::from(name), executable_name: String::from(executable_name), - version: String::from(version), + version, arch, - image_size, address_offsets, } }