Skip to content

Commit

Permalink
Make process opening resiliant to case issues
Browse files Browse the repository at this point in the history
  • Loading branch information
gmjosack committed Sep 29, 2022
1 parent 18bc65b commit 9cf556f
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 9 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"libs/cat_labels",
"libs/mem_reader",
"libs/wad_wix",
"libs/show_procs",
]

[profile.release]
Expand Down
1 change: 1 addition & 0 deletions libs/mem_reader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ winapi = {version = "0.3.9", features = [
"tlhelp32",
"winnt",
"wow64apiset",
"synchapi",
]}
4 changes: 0 additions & 4 deletions libs/mem_reader/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions libs/mem_reader/src/process/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -17,7 +17,6 @@ impl Process {
pub fn new() -> Result<Self, OpenProcessError> {
// 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,
Expand Down
21 changes: 18 additions & 3 deletions libs/mem_reader/src/process/win.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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];
Expand All @@ -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;
}

Expand Down Expand Up @@ -415,6 +421,15 @@ impl Drop for Process {
}
}

fn win_bytes_to_string(bytes: &[i8]) -> String {
let process_bytes: Vec<u8> = 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<usize, InjectDllError> {
let mut wow64_path = [0; MAX_PATH];
let result = unsafe { GetSystemWow64DirectoryW(wow64_path.as_mut_ptr(), MAX_PATH as u32) };
Expand Down
19 changes: 19 additions & 0 deletions libs/show_procs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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",
]}
77 changes: 77 additions & 0 deletions libs/show_procs/src/main.rs
Original file line number Diff line number Diff line change
@@ -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<Vec<String>, 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::<PROCESSENTRY32>()
.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<u8> = 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));
}
}

0 comments on commit 9cf556f

Please sign in to comment.