use core::{ptr, mem};
use core::ffi::c_void;
use crate::sys::*;
use crate::utils::{self, Result};
pub fn open(pid: u32, access_rights: u32) -> Result<HANDLE> {
let result = unsafe {OpenProcess(access_rights, 0, pid) };
if result.is_null() {
return Err(utils::get_last_error());
}
Ok(result)
}
pub fn close(process: HANDLE) -> Result<()> {
let result = unsafe {CloseHandle(process) };
if result == 0 {
return Err(utils::get_last_error());
}
Ok(())
}
pub fn read_memory(process: HANDLE, base_addr: usize, storage: &mut [u8]) -> Result<()> {
let read_size = storage.len();
let ret_val = unsafe {ReadProcessMemory(process,
base_addr as *const c_void,
storage.as_mut_ptr() as *mut c_void,
read_size as SIZE_T,
ptr::null_mut())};
if ret_val == 0 {
Err(utils::get_last_error())
}
else {
Ok(())
}
}
pub fn write_memory(process: HANDLE, base_addr: usize, data: &[u8]) -> Result<()> {
let ret_val = unsafe {WriteProcessMemory(process,
base_addr as *mut c_void,
data.as_ptr() as *const c_void,
data.len() as SIZE_T,
ptr::null_mut())};
if ret_val == 0 {
return Err(utils::get_last_error());
}
Ok(())
}
pub fn get_exe_path(process: HANDLE) -> Result<String> {
let mut buf_len = MAX_PATH as u32;
let mut result: Vec<u16> = vec![0; buf_len as usize];
let text_ptr = result.as_mut_ptr() as LPWSTR;
unsafe {
if QueryFullProcessImageNameW(process, 0, text_ptr, &mut buf_len as *mut u32) == 0 {
return Err(utils::get_last_error());
}
}
Ok(String::from_utf16_lossy(&result[..buf_len as usize]))
}
#[inline]
pub fn get_id(process: HANDLE) -> c_ulong {
unsafe { GetProcessId(process) }
}
#[inline]
pub fn get_current_handle() -> HANDLE {
unsafe { GetCurrentProcess() }
}
pub fn terminate(process: HANDLE, code: c_uint) -> Result<()> {
if unsafe { TerminateProcess(process, code) } != 0 {
Ok(())
}
else {
Err(utils::get_last_error())
}
}
pub fn is_self_elevated() -> bool {
is_elevated(unsafe { GetCurrentProcess() })
}
pub fn is_elevated(process: HANDLE) -> bool {
let mut token: HANDLE = ptr::null_mut();
unsafe {
if OpenProcessToken(process, TOKEN_QUERY, &mut token as *mut HANDLE) == 0 {
return false;
}
}
let mut evalutation: TOKEN_ELEVATION = unsafe { mem::zeroed() };
let eval_ptr = &mut evalutation as *mut TOKEN_ELEVATION as *mut c_void;
let mut len = mem::size_of::<TOKEN_ELEVATION>() as DWORD;
let result = match unsafe { GetTokenInformation(token, TOKEN_INFORMATION_CLASS::TokenElevation, eval_ptr, len, &mut len as *mut _) } {
0 => false,
_ => evalutation.TokenIsElevated != 0,
};
unsafe {
CloseHandle(token);
}
result
}