Skip to content

QuestPackageManager/quest-hook-rs

 
 

Repository files navigation

quest_hook

A library for writing (mostly) memory safe mods for Unity il2cpp games

Docs Tests

Platform support

Despite its name and initial target and scope, this library supports modding most il2cpp games, as long as you have a way to load the mods.

il2cpp versions

Feature flag il2cpp version
il2cpp_v31 Unity 2021+
il2cpp_v29 Unity 2019–2020
il2cpp_v24 Unity 2018
unity2018 Unity 2018 (legacy alias)

Exactly one version feature must be enabled. The default is il2cpp_v31.

Unity versions

  • Unity 2019
  • Unity 2018

Targets

Platform Architecture
Android AArch64 (ARMv8)
Android ARMv7
Windows x86_64 / x86
Linux x86_64 / x86
macOS x86_64

Quick start

Add quest_hook as a dependency and set your crate type to a C dynamic library. A nightly Rust toolchain is required.

# Cargo.toml
[lib]
crate-type = ["cdylib"]

[dependencies]
quest_hook = { git = "https://github.com/StackDoubleFlow/quest-hook-rs.git" }

The default feature set (il2cpp_v31 + util + cache + inline_hook) is a sensible starting point. To target an older game, disable the default il2cpp version and enable the correct one:

[dependencies]
quest_hook = { git = "https://github.com/StackDoubleFlow/quest-hook-rs.git", default-features = false, features = ["il2cpp_v29", "util", "cache", "inline_hook"] }

A nightly toolchain can be pinned project-wide with a rust-toolchain.toml:

# rust-toolchain.toml
[toolchain]
channel = "nightly"

Example

use quest_hook::hook;
use quest_hook::libil2cpp::{Il2CppObject, Il2CppString};
use tracing::debug;

#[hook("UnityEngine.SceneManagement", "SceneManager", "SetActiveScene")]
fn set_active_scene(scene: &mut Il2CppObject) -> bool {
    let name: &Il2CppString = scene.invoke("get_name", ()).unwrap();
    debug!("Hello, {}!", name);

    set_active_scene.original(scene)
}

#[no_mangle]
pub extern "C" fn setup() {
    quest_hook::setup("hello world");
}

#[no_mangle]
pub extern "C" fn load() {
    set_active_scene.install().unwrap();
}

See the examples/ directory for more complete examples including custom il2cpp types.

Cargo features

Feature Default Description
il2cpp_v31 Target il2cpp from Unity 2021+
il2cpp_v29 Target il2cpp from Unity 2019–2020
il2cpp_v24 Target il2cpp from Unity 2018
unity2018 Unity 2018 legacy alias for il2cpp_v24
util setup() helper — logging + panic handler via tracing
cache Cache class/method lookups for faster repeated access
inline_hook Function hooking via inline_hook / flamingo
flamingo Use the Flamingo native hooking library on Android
bindgen Generate il2cpp bindings at build time via bindgen
serde Serialize/Deserialize for il2cpp types
trace tracing instrumentation inside the library internals

Workspace crates

Crate Description
libil2cpp Safe wrappers and raw bindings for Unity's libil2cpp
inline_hook Cross-platform inline function hooking
flamingo Rust bindings for the Flamingo Android hooking library
proc_macros The #[hook] macro and other derive helpers
quest_build_helper Build-script utilities for Quest mod projects

Contributing

Contributions are welcome, especially to the documentation and examples. Most of the discussions regarding the development of this library happen in the #quest-mod-dev channel of the BSMG Discord server.

Everything that can reasonably be done in Rust should be done in Rust. This library is, by nature, extremely unsafe and contains a lot of unsafe code — the goal is a Rust-friendly API surface, not the elimination of unsafety.

A decent understanding of both Rust and C++ is required for most contributions. The main reference is the libil2cpp source. Another useful reference is beatsaber-hook.

License

quest_hook is licensed under the MIT License.

Credits

This library wouldn't exist without the invaluable help, feedback, and previous work from Sc2ad.

About

A Rust library for making mods for Oculus Quest games compiled using il2cpp

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Rust 100.0%