Skip to main content

Crate imping_runtime

Crate imping_runtime 

Source
Expand description

Runtime support for code generated by imping.

Generated bindings depend on this crate alone. Module, Global and the string types also work without generated code.

use imping_runtime::{Build, Global, Module};

static TARGET: Module = Module::new(
    "target.exe",
    &[Build { timestamp: 0x64b8f2a1, image_size: 0xa2b000 }],
);
static GRAVITY: Global<f32> = Global::new(&TARGET, 0x3a1200);

fn main() -> imping_runtime::Result<()> {
    // SAFETY: this build of `target.exe` keeps an `f32` at RVA 0x3a1200.
    unsafe { TARGET.init() }?;
    GRAVITY.write(4.9);
    Ok(())
}

§Main items

  • Module: a module’s expected identity; Module::init checks the loaded build and resolves addresses against its base.
  • Global: a typed global variable, read and written safely when it is Plain.
  • Hook: the guard a generated function’s hook returns.
  • CStrPtr, WStrPtr, CStrBuf, WStrBuf and WString: char and wchar_t strings in the target’s memory.
  • Inherits and Upcast: base classes and pointer upcasts.
  • Error: everything that can go wrong.

§What stays unsafe

Module::init is the one promise that the bindings match the running build. After it, plain globals, hooks, forwarding a hooked call and functions marked safe need no unsafe. Still unsafe, as only the caller knows the target’s state: dereferencing a pointer from the target, reading a string through one, and calling a function not marked safe.

Dereference once per block rather than once per access:

// SAFETY: `player` is null or points to a live entity owned by the target.
if let Some(player) = unsafe { player.as_mut() } {
    player.health = 100.0;
    player.armor = 50.0;
}

§Unloading

Hooks jump into the mod’s code, so drop or disable every Hook before the mod is unloaded. After Hook::leak, the mod must never be unloaded.

§Platforms

Windows only. Elsewhere the crate compiles, but Module::init returns Error::UnsupportedPlatform.

Structs§

Build
One build of a module, identified by the timestamp and image size in its image header.
CStrBuf
A fixed-size narrow string buffer inside a struct (char name[N]), holding a string up to the first NUL.
CStrPtr
A pointer to a NUL-terminated narrow string (char*), possibly null.
Global
A global variable of type T at an address in a Module.
Hook
A hook on a function, returned disabled by a generated function’s hook.
Mismatch
Why a function wasn’t where the bindings expect, and why nothing else found it: the details of Error::VerificationFailed.
Module
A module (executable or DLL) of the target process, as the bindings expect it: its file name and the builds they accept.
WStrBuf
A fixed-size UTF-16 string buffer inside a struct (wchar_t name[N]), holding a string up to the first NUL.
WStrPtr
A pointer to a NUL-terminated UTF-16 string (wchar_t* on Windows), possibly null.
WString
An owned, NUL-terminated UTF-16 string, to pass to the target as a wchar_t*.

Enums§

Error
Everything that can go wrong finding a module or hooking a function.
VtableMiss
Why a function couldn’t be found through its class’s vtable.

Traits§

Inherits
Marks Self as deriving from B, so a pointer to a Self is also a valid pointer to its B.
Plain
A type for which every bit pattern of its size is a valid value, so it can be read from and written to the target’s memory without checks.
Upcast
Converts a raw pointer to a class into a pointer to one of its base classes, keeping it *mut or *const.

Type Aliases§

Result
The result type of this crate’s fallible functions.