#![allow(non_camel_case_types)]
#![allow(unused)]
#![allow(non_snake_case)]
use crate::DWORD;
pub type LPVOID = *mut std::os::raw::c_void;
pub type SIZE_T = usize;
pub type BOOL = bool;
pub type HANDLE = *const std::os::raw::c_void;
pub type LPCSTR = *const u8;
pub type HMODULE = *const std::os::raw::c_void;
pub mod AllocationType {
use crate::DWORD;
pub const MEM_COMMIT: DWORD = 0x00001000;
pub const MEM_RESERVE: DWORD = 0x00002000;
pub const MEM_RESET: DWORD = 0x00080000;
pub const MEM_RESET_UNDO: DWORD = 0x1000000;
pub const MEM_LARGE_PAGES: DWORD = 0x20000000;
pub const MEM_PHYSICAL: DWORD = 0x00400000;
pub const MEM_TOP_DOWN: DWORD = 0x00100000;
pub const MEM_WRITE_WATCH: DWORD = 0x00200000;
}
pub mod Protect {
use crate::DWORD;
pub const PAGE_EXECUTE: DWORD = 0x10;
pub const PAGE_EXECUTE_READ: DWORD = 0x20;
pub const PAGE_EXECUTE_READWRITE: DWORD = 0x40;
pub const PAGE_EXECUTE_WRITECOPY: DWORD = 0x80;
pub const PAGE_NOACCESS: DWORD = 0x01;
pub const PAGE_READONLY: DWORD = 0x02;
pub const PAGE_READWRITE: DWORD = 0x04;
pub const PAGE_WRITECOPY: DWORD = 0x08;
pub const PAGE_TARGETS_INVALID: DWORD = 0x40000000;
pub const PAGE_TARGETS_NO_UPDATE: DWORD = 0x40000000;
pub const PAGE_GUARD: DWORD = 0x100;
pub const PAGE_NOCACHE: DWORD = 0x200;
pub const PAGE_WRITECOMBINE: DWORD = 0x400;
}
pub mod FreeType {
use crate::DWORD;
pub const MEM_DECOMMIT: DWORD = 0x00004000;
pub const MEM_RELEASE: DWORD = 0x00008000;
pub const MEM_COALESCE_PLACEHOLDERS: DWORD = 0x00000001;
pub const MEM_PRESERVE_PLACEHOLDER: DWORD = 0x00000002;
}
#[link(name = "Kernel32", kind = "dylib")]
extern "system" {
pub fn GetLastError() -> DWORD;
pub fn VirtualAlloc(
lpAddress: LPVOID,
dwSize: usize,
flAllocationType: DWORD,
flProtect: DWORD,
) -> LPVOID;
pub fn VirtualFree(lpAddress: LPVOID, dw_size: SIZE_T, dwFreeType: DWORD) -> BOOL;
pub fn VirtualAllocEx(
hProcess: HANDLE,
lpAddress: LPVOID,
dwSize: SIZE_T,
flAllocationType: DWORD,
flProtect: DWORD,
) -> LPVOID;
pub fn VirtualFreeEx(
hProcess: HANDLE,
lpAddress: LPVOID,
dwSize: SIZE_T,
dwFreeType: DWORD,
) -> LPVOID;
pub fn LoadLibraryA(lpLibFileName: LPCSTR) -> HMODULE;
pub fn FreeLibrary(hLibModule: HMODULE) -> BOOL;
pub fn GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE;
pub fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_library() {
unsafe {
let hModule = LoadLibraryA("User32.dll\0".as_ptr());
assert!(!hModule.is_null());
let hModule = GetModuleHandleA("User32.dll\0".as_ptr());
assert!(!hModule.is_null());
let MessageBoxA = GetProcAddress(hModule, "MessageBoxA\0".as_ptr());
assert!(!MessageBoxA.is_null());
let MessageBoxA: extern "C" fn(LPVOID, LPCSTR, LPCSTR, u32) =
std::mem::transmute(MessageBoxA);
MessageBoxA(std::ptr::null_mut(), "Test\0".as_ptr(), "aaa\0".as_ptr(), 1);
FreeLibrary(hModule);
assert_eq!(0, GetLastError());
}
}
#[test]
fn test_ffi() {
unsafe {
let ptr = VirtualAlloc(
std::ptr::null_mut(),
1024,
AllocationType::MEM_COMMIT,
Protect::PAGE_READWRITE,
);
assert!(!ptr.is_null());
let arr = ptr as *mut DWORD;
*arr = 10;
let arr = std::slice::from_raw_parts_mut(arr, 10);
println!("{:?}", arr);
assert!(VirtualFree(ptr, 0, FreeType::MEM_RELEASE));
}
}
}