The Modern Standard Stack for Android Memory Instrumentation in Rust.
android-mem-kit is a robust, type-safe wrapper around the battle-tested C/C++ libraries used in Android game modding and security research. It bridges the gap between low-level memory manipulation and Rust's safety, allowing you to write high-performance tools for rooted devices.
| Feature | Powered By | Description |
|---|---|---|
| Hooking | Dobby | Near-branch trampoline hooking support for ARM64/ARM. |
| Patching | KittyMemory | Runtime memory patching with hex string support & restore capability. |
| Bypass | xdl | Bypasses Android 7+ linker restrictions (dlopen/dlsym restrictions). |
| Il2Cpp | Built-in | Helper macros to resolve Il2Cpp exports dynamically without header files. |
| Security | obfstr | Compile-time string obfuscation included by default. |
Since this crate compiles C++ code natively for Android, you need the Android NDK.
-
Install Android NDK (r25b or newer recommended).
-
Set Environment Variable before compiling:
export ANDROID_NDK_HOME=/path/to/your/android-ndk-r29
Add this to your Cargo.toml:
[dependencies]
android-mem-kit = "0.1.0"
ctor = "0.2" # Recommended for library initialization
log = "0.4"
android_logger = "0.13"Here is a complete example of a mod menu backend or instrumentation tool.
use android_mem_kit::{
hooking,
memory::{self, MemoryPatch},
il2cpp_call, // Macro for easy API calls
obfstr::obfstr // String encryption
};
use ctor::ctor;
use std::ffi::c_void;
// 1. Setup Entry Point
#[ctor]
fn init() {
android_logger::init_once(
android_logger::Config::default().with_tag("MyMod"),
);
// Run in a separate thread to avoid blocking main thread
std::thread::spawn(|| {
log::info!("Library Loaded! Starting instrumentation...");
start_mod();
});
}
fn start_mod() {
// 2. Locate Library Base
// 'xdl' is used internally to bypass linker restrictions
let lib_name = obfstr!("libil2cpp.so");
let base = memory::get_lib_base(lib_name);
if base == 0 {
log::error!("Library not found!");
return;
}
log::info!("{} base: {:#X}", lib_name, base);
// 3. Memory Patching (Hex)
// Example: Patching an integrity check at offset 0x123456
let patch_offset = base + 0x123456;
if let Ok(patch) = MemoryPatch::from_hex(patch_offset, "00 00 A0 E3") { // MOV R0, #0
patch.apply();
log::info!("Integrity check bypassed!");
// You can restore it later:
// patch.restore();
}
// 4. Function Hooking
unsafe {
let target_func = base + 0xABCDE;
if let Ok(original) = hooking::attach(target_func, my_custom_hook as usize) {
log::info!("Function hooked! Trampoline at: {:#X}", original);
}
}
// 5. Il2Cpp API Call (Zero boilerplate)
// Calls il2cpp_thread_attach(il2cpp_domain_get()) safely
unsafe {
let domain = il2cpp_call!("il2cpp_domain_get", usize, ).unwrap_or(0);
if domain != 0 {
il2cpp_call!("il2cpp_thread_attach", void, domain);
log::info!("Attached to Il2Cpp thread!");
}
}
}
// Custom Hook Handler
unsafe extern "C" fn my_custom_hook(args: *mut c_void) {
log::info!("Target function called with args: {:?}", args);
// Call original function if needed...
}Use cargo-ndk or standard cargo with target specification:
cargo build --target aarch64-linux-android --releaseNote: Ensure your build.rs can find the NDK toolchain.
This project wouldn't be possible without the open-source community. Huge thanks to the authors of the underlying C/C++ libraries:
- Dobby by jmpews - Lightweight, multi-platform hooking framework.
- KittyMemory by MJx0 - Memory manipulation library for Android/iOS.
- xdl by hexhacking - The ultimate solution for Android linker restrictions.
This project is licensed under the MIT License - see the LICENSE file for details.