Crate game_mem_utils

Source
Expand description

§Game Memory Utils

A Rust library for reading and writing process memory on Linux, designed for easy trainer creation!

§Features

  • Process Memory Access: Read and write to any process memory using /proc/pid/mem
  • Pattern Scanning: Advanced byte pattern matching with wildcard support
  • Module Management: Find and work with loaded modules/libraries
  • Safe Memory Operations: Type-safe memory operations with comprehensive error handling
  • Ptrace Integration: Automatic process attachment and detachment
  • Debug Support: Optional debug output for troubleshooting memory operations

§Quick Start

use game_mem_utils::{GameMemUtils, hex};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Attach to a process by name (debug mode disabled)
    let mut mem = GameMemUtils::new("my_game", false)?;
     
    // Read a u32 value at absolute address
    let gold: u32 = mem.read_at(hex!("8320b84"))?;
    println!("Current gold: {gold}");
     
    // Write a new value
    mem.write_at(hex!("8320b84"), 999999u32)?;
     
    // Pattern scanning across all process memory
    if let Some(addr) = mem.pattern_scan_all_process_memory("48 89 ?? ?? ?? C3")? {
        println!("Pattern found at: 0x{:x}", addr);
    }
     
    Ok(())
}

§Memory Operations

§Reading Memory

let mut mem = GameMemUtils::new("game_process", false)?;

// Read at absolute address
let value: u32 = mem.read_at(0x12345678)?;

// Read at offset from base address
let value: u32 = mem.read(0x1000)?;

// Read using hex string offset
let value: u32 = mem.read_hex("1000")?;

// Read raw bytes
let bytes = mem.read_bytes(0x12345678, 16)?;

// Read null-terminated string
let text = mem.read_string(0x12345678, 64)?;

// Read little-endian integers
let val_u32 = mem.read_u32_le(0x12345678)?;
let val_u64 = mem.read_u64_le(0x12345678)?;

§Writing Memory

let mut mem = GameMemUtils::new("game_process", false)?;

// Write at absolute address
mem.write_at(0x12345678, 42u32)?;

// Write at offset from base address
mem.write(0x1000, 100i32)?;

// Write using hex string offset
mem.write_hex("1000", 200u32)?;

// Write raw bytes
mem.write_bytes(0x12345678, &[0x41, 0x42, 0x43])?;

// Write little-endian integers
mem.write_u32_le(0x12345678, 12345)?;
mem.write_u64_le(0x12345678, 9876543210)?;

§Pattern Scanning

Pattern scanning allows you to find specific byte sequences in memory with support for wildcards:

let mut mem = GameMemUtils::new("game_process", false)?;

// Scan all readable+executable memory regions
if let Some(addr) = mem.pattern_scan_all_process_memory("48 89 ?? ?? ?? C3")? {
    println!("Pattern found at: 0x{:x}", addr);
}

// Scan specific module
if let Some(addr) = mem.pattern_scan_module("game.exe", "89 46 08 ?? C0")? {
    println!("Pattern found in module at: 0x{:x}", addr);
}

§Pattern Syntax

  • "48 89 E5" - Exact bytes (hex values separated by spaces)
  • "48 ?? E5" - Wildcard in middle (use ?? or ? for wildcards)
  • "?? 89 ?? ?? ?? C3" - Multiple wildcards

§Module Management

let mut mem = GameMemUtils::new("game_process", false)?;

// Get process info
let pid = mem.pid();
let base_addr = mem.base_address();

// Find module base address
let module_base = mem.find_module_base("libgame.so")?;

// List all loaded modules
let modules = mem.find_loaded_modules()?;
for (name, base, end, permissions) in &modules {
    println!("{}: 0x{:x}-0x{:x} ({})", name, base, end, permissions);
}

// Filter modules by regex
let filtered = mem.filter_modules_by_regex(&modules, r".*\.so$")?;

§Error Handling

The library provides comprehensive error handling through the MemoryError enum:

use game_mem_utils::{GameMemUtils, MemoryError};

match GameMemUtils::new("nonexistent_process", false) {
    Ok(mem) => {
        // Use mem...
    }
    Err(MemoryError::ProcessNotFound(name)) => {
        eprintln!("Process '{}' not found", name);
    }
    Err(MemoryError::InsufficientPermissions) => {
        eprintln!("Need sudo or appropriate permissions");
    }
    Err(e) => eprintln!("Other error: {}", e),
}

§Debug Mode

Enable debug output to troubleshoot memory operations:

// Enable debug mode (second parameter = true)
let mut mem = GameMemUtils::new("my_game", true)?;

// Debug output will show:
// - Memory region scanning details
// - Pattern matching progress
// - Ptrace operation results
// - Module loading information

§Requirements

  • Linux: This library is Linux-specific and uses /proc/pid/mem and ptrace
  • Permissions: May require sudo or appropriate capabilities to attach to processes
  • Target Process: The target process should be running and accessible

§Safety Notes

  • This library directly manipulates process memory, which can cause crashes if used incorrectly
  • Always validate addresses and data before writing
  • The target process will be temporarily stopped during attachment
  • Automatic cleanup ensures processes are properly detached when GameMemUtils is dropped

§Platform Support

  • Linux (x86_64, ARM64, and other architectures supported by Rust)
  • Wine/Proton games (with some limitations on module detection)

Macros§

hex
Macro for converting hex strings to u64 values at compile time

Structs§

GameMemUtils
Main struct for game memory manipulation utilities using ptrace and /proc/pid/mem

Enums§

MemoryError
Error types for memory operations