..

mosaic-rs

Features

Examples

Modular API Hashing

// https://github.com/HindrikStegenga/const-fnv1a-hash
pub struct FNV1A64;
impl const Digest for FNV1A64 {
    const OUTPUT_LEN: usize = 8;
    fn digest(data: &[u8]) -> [u8; Self::OUTPUT_LEN] {
        const FNV_OFFSET_BASIS_64: u64 = 0xcbf29ce484222325;
        const FNV_PRIME_64: u64 = 0x00000100000001B3;

        let mut hash = FNV_OFFSET_BASIS_64;
        let mut i = 0;
        while i < data.len() {
            hash ^= data[i] as u64;
            hash = hash.wrapping_mul(FNV_PRIME_64);
            i += 1;
        }
        hash.to_be_bytes()
    }
}

fn message_box() {
    type MessageBoxA =
        unsafe extern "system" fn(hwnd: isize, lptext: *const u8, *const u8, u32) -> i32;

    let library = Library::load("User32.dll").expect("Could not load User32.dll");
    let _message_box = library
        .get_proc::<FNV1A64, MessageBoxA>(FNV1A64::digest(b"MessageBoxA"))
        .expect("Could not get MessageBoxA");

    // drop(library);

    // unsafe {
    //     _message_box.call(0, "Hello, World!\0".as_ptr(), "Hello, World!\0".as_ptr(), 0);
    // }
}

Resolving and Invoking Syscalls

type NtAllocateVirtualMemory = unsafe extern "system" fn(
    ProcessHandle: HANDLE,
    BaseAddress: *mut PVOID,
    ZeroBits: ULONG_PTR,
    RegionSize: PSIZE_T,
    AllocationType: ULONG,
    Protect: ULONG,
) -> NtResult;

let ssn = Ntdll::new()
    .get_ssn::<NtAllocateVirtualMemory>(HashFunction::digest(b"NtAllocateVirtualMemory"))
    .unwrap();

let mut addr: *mut core::ffi::c_void = 0 as _;
let mut region_size = 100;

let nt_result = unsafe {
    ssn.call(
        GetCurrentProcess(),
        &mut addr,
        0,
        &mut region_size,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_READWRITE,
    )
};

if let NtResult::Err(nt_status) = nt_result {
    println!(
        "NtAllocateVirtualMemory failed with {:#X} ({})",
        nt_status.code(),
        nt_status.as_error().message()
    );
}