From 9cf556ff0328d871397ada0d3c13e8561c47ca0f Mon Sep 17 00:00:00 2001 From: garebear Date: Thu, 29 Sep 2022 09:56:56 -0700 Subject: [PATCH] Make process opening resiliant to case issues --- Cargo.lock | 9 ++++ Cargo.toml | 1 + libs/mem_reader/Cargo.toml | 1 + libs/mem_reader/src/constants.rs | 4 -- libs/mem_reader/src/process/mock.rs | 3 +- libs/mem_reader/src/process/win.rs | 21 ++++++-- libs/show_procs/Cargo.toml | 19 +++++++ libs/show_procs/src/main.rs | 77 +++++++++++++++++++++++++++++ 8 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 libs/show_procs/Cargo.toml create mode 100644 libs/show_procs/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index d7897bd..d58e285 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2760,6 +2760,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "show_procs" +version = "0.0.0" +dependencies = [ + "anyhow", + "hdt_mem_reader", + "winapi", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 4126ef8..8d93c87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "libs/cat_labels", "libs/mem_reader", "libs/wad_wix", + "libs/show_procs", ] [profile.release] diff --git a/libs/mem_reader/Cargo.toml b/libs/mem_reader/Cargo.toml index 3a4d997..6bb0eed 100644 --- a/libs/mem_reader/Cargo.toml +++ b/libs/mem_reader/Cargo.toml @@ -28,4 +28,5 @@ winapi = {version = "0.3.9", features = [ "tlhelp32", "winnt", "wow64apiset", + "synchapi", ]} diff --git a/libs/mem_reader/src/constants.rs b/libs/mem_reader/src/constants.rs index 99bb330..4055de8 100644 --- a/libs/mem_reader/src/constants.rs +++ b/libs/mem_reader/src/constants.rs @@ -17,10 +17,6 @@ pub(crate) static SPELUNKY_1_4_OFFSETS: Offsets = Offsets { pub(crate) static KALI_ACCEPTS: &'static [u8; 26] = &[ 75, 0, 65, 0, 76, 0, 73, 0, 95, 0, 65, 0, 67, 0, 67, 0, 69, 0, 80, 0, 84, 0, 83, 0, 0, 0, ]; -pub(crate) static EXE_NAME: &'static [i8; 13] = &[ - 'S' as i8, 'p' as i8, 'e' as i8, 'l' as i8, 'u' as i8, 'n' as i8, 'k' as i8, 'y' as i8, - '.' as i8, 'e' as i8, 'x' as i8, 'e' as i8, '\0' as i8, -]; pub struct Offsets { pub kali_accepts: usize, diff --git a/libs/mem_reader/src/process/mock.rs b/libs/mem_reader/src/process/mock.rs index 0b31099..d1c5d28 100644 --- a/libs/mem_reader/src/process/mock.rs +++ b/libs/mem_reader/src/process/mock.rs @@ -5,7 +5,7 @@ use byteorder::LittleEndian; use super::Failure; use super::{OpenProcessError, ReadMemoryError, Version, WriteMemoryError}; -use crate::constants::{Offsets, EXE_NAME, KALI_ACCEPTS}; +use crate::constants::{Offsets, KALI_ACCEPTS}; pub struct Process { pub base_addr: usize, @@ -17,7 +17,6 @@ impl Process { pub fn new() -> Result { // Shut up constants about not being used when not on windows. let _ = KALI_ACCEPTS; - let _ = EXE_NAME; return Ok(Process { base_addr: 0, version: Version::Spelunky147, diff --git a/libs/mem_reader/src/process/win.rs b/libs/mem_reader/src/process/win.rs index 565021c..33cc9c3 100644 --- a/libs/mem_reader/src/process/win.rs +++ b/libs/mem_reader/src/process/win.rs @@ -36,7 +36,7 @@ use winapi::um::winnt::PROCESS_VM_WRITE; use winapi::um::winnt::{PROCESS_QUERY_INFORMATION, PROCESS_VM_READ}; use winapi::um::wow64apiset::GetSystemWow64DirectoryW; -use crate::constants::{self, Offsets, EXE_NAME}; +use crate::constants::{self, Offsets}; use crate::process::{FindProcessError, OpenProcessError, ReadMemoryError, Version}; use super::Failure; @@ -198,7 +198,8 @@ impl Process { } loop { - if &process.szExeFile[..EXE_NAME.len()] == EXE_NAME { + let process_name = win_bytes_to_string(&process.szExeFile); + if process_name == "Spelunky.exe" { if pid.is_some() { unsafe { CloseHandle(process_snap) }; return Err(FindProcessError::MultipleProcessesFound); @@ -236,6 +237,8 @@ impl Process { "Failed to get process module name...".into(), )); } + let process_image_string = win_bytes_to_string(&process_image_filename).to_lowercase(); + println!("Base Module Named: {:?}", process_image_string); // Get handles for all modules in process. let mut module_handles: [HMODULE; 1024] = [0 as HMODULE; 1024]; @@ -263,6 +266,7 @@ impl Process { let num_modules = bytes_written as usize / hmodule_size; + println!("Checking {:?} possible modules", num_modules); // Enumerate Modules to find handle for EXE module for idx in 0..num_modules { let mut module_filename = [0; MAX_PATH]; @@ -280,7 +284,9 @@ impl Process { continue; } - if module_filename != process_image_filename { + let module_string = win_bytes_to_string(&module_filename).to_lowercase(); + println!("Module Found: {}", module_string); + if module_string != process_image_string { continue; } @@ -415,6 +421,15 @@ impl Drop for Process { } } +fn win_bytes_to_string(bytes: &[i8]) -> String { + let process_bytes: Vec = bytes + .iter() + .map(|c| *c as u8) + .take_while(|c| *c != 0) + .collect(); + String::from_utf8_lossy(&process_bytes).into() +} + fn get_load_library_rva() -> Result { let mut wow64_path = [0; MAX_PATH]; let result = unsafe { GetSystemWow64DirectoryW(wow64_path.as_mut_ptr(), MAX_PATH as u32) }; diff --git a/libs/show_procs/Cargo.toml b/libs/show_procs/Cargo.toml new file mode 100644 index 0000000..fa71202 --- /dev/null +++ b/libs/show_procs/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["garebear"] +name = "show_procs" +version = "0.0.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1" +hdt_mem_reader = {path = "../mem_reader"} + + +[target.'cfg(target_os = "windows")'.dependencies] +winapi = {version = "0.3.9", features = [ + "handleapi", + "minwinbase", + "tlhelp32", +]} diff --git a/libs/show_procs/src/main.rs b/libs/show_procs/src/main.rs new file mode 100644 index 0000000..fbe29ef --- /dev/null +++ b/libs/show_procs/src/main.rs @@ -0,0 +1,77 @@ +use std::mem::size_of; + +use anyhow::anyhow; +use winapi::shared::minwindef::MAX_PATH; +use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE}; +use winapi::um::tlhelp32::{ + CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS, +}; + +fn get_lunky_procs() -> Result, anyhow::Error> { + let mut procs = vec![]; + + let process_snap = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) }; + + if process_snap == INVALID_HANDLE_VALUE { + return Err(anyhow!("Failed to get process snapshot.")); + } + + let process_entry_size: u32 = size_of::() + .try_into() + .map_err(|_| anyhow!("Failed to get size of ProcessEntry32"))?; + + let mut process: PROCESSENTRY32 = PROCESSENTRY32 { + dwSize: process_entry_size, + cntUsage: 0, + th32ProcessID: 0, + th32DefaultHeapID: 0, + th32ModuleID: 0, + cntThreads: 0, + th32ParentProcessID: 0, + pcPriClassBase: 0, + dwFlags: 0, + szExeFile: [0; MAX_PATH], + }; + + if unsafe { Process32First(process_snap, &mut process) } == 0 { + return Err(anyhow!("Failed to get first process...")); + } + + loop { + let process_bytes: Vec = process + .szExeFile + .map(|c| c as u8) + .iter() + .take_while(|c| **c != 0) + .cloned() + .collect(); + + let process_name: String = String::from_utf8_lossy(&process_bytes).into(); + + if process_name.to_lowercase().contains("spelunky") { + procs.push(process_name.into()); + } + + if unsafe { Process32Next(process_snap, &mut process) } == 0 { + break; + } + } + + unsafe { CloseHandle(process_snap) }; + + Ok(procs) +} + +fn main() { + loop { + match ::hdt_mem_reader::process::Process::new() { + Ok(process) => { + println!("Process opened!"); + drop(process); + } + Err(err) => eprintln!("Failed to open process: {}", err), + } + println!("=============="); + ::std::thread::sleep(std::time::Duration::from_secs(5)); + } +}