use std::ffi::{CStr, CString}; use std::io; use std::os::raw::c_char; use std::ptr; use winapi; use winapi::shared::minwindef::{BOOL, DWORD, HINSTANCE, LPVOID}; use winapi::um::consoleapi::AllocConsole; macro_rules! export_var { ($($name:ident: $v:ty = $val:expr),*) => { $(#[no_mangle] pub static mut $name: $v = $val;)* } } /// Export variables for interfacing with the ASM code using the macro of above. /// (basically I wanted a no_mangle scoped) export_var!{ array_start: usize = std::usize::MIN, _end: usize = 0, new_value: f64 = 0., my_arr: [f64; 120] = [0f64; 120] } extern "C" { static get_values: u8; } /// Replaces an array of bytes for a jmp f /// in order to hook our own code. fn hook_fun(dest: usize, f: *const u8, len: usize) { let nops = vec![0x90; len]; let mut _t: DWORD = 0; unsafe { let result = winapi::um::memoryapi::VirtualProtect( dest as LPVOID, len, winapi::um::winnt::PAGE_EXECUTE_READWRITE, &mut _t ); } println!("{:?}", std::io::Error::last_os_error()); let mut ptr = dest as *mut u8; // nop the stuff unsafe { for n in nops { *ptr = n; } } let _f: isize = (f as isize); let _dest: isize = dest as isize; let r_addr: DWORD = (_f - _dest) as DWORD - 5; let mut ptr = dest as *mut u8; unsafe { *ptr = 0xE9; // jmp opcode let ptr = (dest + 1) as *mut DWORD; // target address *ptr = r_addr; } } #[no_mangle] pub unsafe extern "system" fn intercept_input(_: LPVOID) -> DWORD { use winapi::um; // AllocConsole(); let _name = CString::new("CHARTV.dll").unwrap(); let mba = um::libloaderapi::GetModuleHandleA(_name.as_ptr()) as usize; // specific offset which may not work for every taskmgr.exe let target_addr = mba + 0x312E; let mut _b = String::new(); unsafe { // _end is used by the asm injection to jmp back from our // injection to their own code. _end = target_addr + 5; hook_fun(target_addr, &get_values as *const u8, 5); } let _t = CString::new("Enjoy the waves!").unwrap(); winapi::um::winuser::MessageBoxA(std::ptr::null_mut(), _t.as_ptr(), _t.as_ptr(), 0); println!("Enjoy the waves!"); // dirty math to create sinusoidal chart let mut t = 0f64; loop { for i in 0..my_arr.len() { let _i = (i as f64)/10f64; my_arr[i] = 50f64*(1f64 + (t + _i).sin()) } t += 1e-5; if t > 2.*3.14 { t = 0f64; } } // winapi::um::wincon::FreeConsole(); return 1; } #[no_mangle] #[allow(non_snake_case)] pub extern "system" fn DllMain(_: HINSTANCE, reason: DWORD, _: LPVOID) -> BOOL { unsafe { match reason { winapi::um::winnt::DLL_PROCESS_ATTACH => { winapi::um::processthreadsapi::CreateThread( ptr::null_mut(), 0, Some(intercept_input), ptr::null_mut(), 0, ptr::null_mut(), ); } _ => (), }; } return true as BOOL; }