From aaf92cd109f22c182f8c78bc17b6964c877ef150 Mon Sep 17 00:00:00 2001 From: pozm <44528100+pozm@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:24:48 +0000 Subject: [PATCH] now just need to get data from the vector... --- Cargo.lock | 97 +++++++++++++++++++++++++++++++++++++++++----- Cargo.toml | 1 - gdkeinj/Cargo.toml | 1 + gdkeinj/src/lib.rs | 56 ++++++++++++++++++++++++-- src/lib.rs | 59 +++++++++++++++++----------- src/main.rs | 1 - src/versioning.rs | 11 ++++-- 7 files changed, 186 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d219bf9..63d727a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,15 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cexpr" version = "0.6.0" @@ -247,7 +256,6 @@ dependencies = [ "crossbeam", "dll-syringe", "poggers", - "semver", "windows", ] @@ -257,6 +265,17 @@ version = "0.1.0" dependencies = [ "poggers", "poggers-derive", + "retour", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", ] [[package]] @@ -367,6 +386,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "libudis86-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139bbf9ddb1bfc90c1ac64dd2923d9c957cd433cee7315c018125d72ab08a6b0" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -416,6 +445,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "mmap-fixed-fixed" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0681853891801e4763dc252e843672faf32bcfee27a0aa3b19733902af450acc" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "nom" version = "7.1.1" @@ -457,9 +496,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "path-absolutize" @@ -569,6 +608,34 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "region" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach", + "winapi", +] + +[[package]] +name = "retour" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9af44d40e2400b44d491bfaf8eae111b09f23ac4de6e92728e79d93e699c527" +dependencies = [ + "cfg-if", + "generic-array", + "libc", + "libudis86-sys", + "mmap-fixed-fixed", + "once_cell", + "region", + "slice-pool2", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -623,12 +690,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "semver" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" - [[package]] name = "serde" version = "1.0.196" @@ -668,6 +729,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "slice-pool2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3d689654af89bdfeba29a914ab6ac0236d382eb3b764f7454dde052f2821f8" + [[package]] name = "stopwatch2" version = "2.0.0" @@ -747,6 +814,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "typewit" version = "1.9.0" @@ -768,6 +841,12 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "which" version = "4.4.2" diff --git a/Cargo.toml b/Cargo.toml index 4ae859c..849a346 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ strip = false # members = ["gdke-gui"] [dependencies] -semver = "*" anyhow = "*" windows = { features = [ "Win32_Foundation", diff --git a/gdkeinj/Cargo.toml b/gdkeinj/Cargo.toml index 1b31410..887129d 100644 --- a/gdkeinj/Cargo.toml +++ b/gdkeinj/Cargo.toml @@ -10,3 +10,4 @@ crate-type = ["cdylib"] [dependencies] poggers = { path = "../../poggers" } poggers-derive = { path = "../../poggers/poggers-derive/" } +retour = { version = "0.3.1", features = ["static-detour", "thiscall-abi"] } diff --git a/gdkeinj/src/lib.rs b/gdkeinj/src/lib.rs index 3207107..90aaa1c 100644 --- a/gdkeinj/src/lib.rs +++ b/gdkeinj/src/lib.rs @@ -1,9 +1,26 @@ -use std::{net::UdpSocket, time::Duration}; +use std::{ + collections::HashMap, ffi::c_void, mem::size_of, net::UdpSocket, ptr::null, time::Duration, +}; -use poggers::structures::process::{implement::utils::ProcessUtils, Process}; +use poggers::{ + structures::process::{implement::utils::ProcessUtils, Process}, + traits::Mem, +}; +use retour::static_detour; -#[poggers_derive::create_entry(no_console)] +// *const i32, *const i32, *const i32, bool +type open_and_parse_t = unsafe extern "fastcall" fn(*const i32, *const i32, *const i32, bool) -> (); +static_detour! { + pub static OpenAndParse: unsafe extern "fastcall" fn(*const i32, *const i32, *const i32, bool) -> (); +} + +#[poggers_derive::create_entry(no_free)] pub fn main() { + let mut sigs = HashMap::::new(); + sigs.insert( + 1, + ("E8 ? ? ? ? 85 C0 0F 84 ? ? ? ? 49 8B 8C 24 ? ? ? ?", -0x3c), + ); let sock = UdpSocket::bind("127.0.0.1:29849").unwrap(); let mut buf = [1; 1]; sock.connect("127.0.0.1:28713").expect("uanble to connect"); @@ -11,7 +28,38 @@ pub fn main() { let proc = Process::this_process(); let modd = proc.get_base_module().unwrap(); - println!("sending data"); + println!("sending data, waiting for sig ver"); std::thread::sleep(Duration::from_secs(2)); sock.send(&buf); + + let mut sig_type = [0; 4]; + sock.recv(&mut sig_type); + let int_sig = u32::from_ne_bytes(sig_type); + let sig = sigs.get(&int_sig).expect("sig type match not compatible"); + let mut addr = modd.scan(sig.0).unwrap().unwrap() as isize; //+ sig.1 as isize; + // addr += sig.1 as isize; + let ptr_to_fn = (addr as usize + size_of::()) as *const u8; + let mut addr_offset = [0; 4]; + unsafe { std::ptr::copy(ptr_to_fn, addr_offset.as_mut_ptr(), 4) }; + let by = i32::from_ne_bytes(addr_offset); + println!("addr offset = {:x?}", addr_offset); + let fn_ptr = (addr + by as isize + 5) as *const c_void; + println!("fnptr = {:x?}", fn_ptr); + + println!("sig found: {:x} {:p}", addr, ptr_to_fn); + let sock2 = sock.try_clone().unwrap(); + unsafe { + let open_and_parse = std::mem::transmute::(fn_ptr as isize); + let opp = OpenAndParse + .initialize(open_and_parse, move |this, base, key, mode| { + println!("open and parse called {key:?}"); + let mut key: *const u8 = std::ptr::null(); + // std::arch::asm!("mov {}, r8", out(reg) key); + // println!("key = {:?}", key); + }) + .unwrap(); + opp.enable(); + println!("detour enabled {}", opp.is_enabled()); + } + sock.send(&[]); } diff --git a/src/lib.rs b/src/lib.rs index 5e45ce0..9d6d9b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,9 @@ -#![feature(offset_of)] +#![feature(offset_of_nested)] pub mod versioning; use std::{ error::Error, ffi::{c_void, CStr, CString}, + io::Read, mem::{size_of, transmute}, net::UdpSocket, ptr::{addr_of, null, null_mut}, @@ -69,40 +70,54 @@ pub unsafe fn spawn_and_inject(proc: &str) { &mut 0, ); let proc = Process::find_pid(proc_info.dwProcessId).unwrap(); - let pebby: PEB = proc.read(ptr_to_pbi.PebBaseAddress as usize).expect("the"); - let pImage = pebby.Reserved3[1] as usize; - let e_lf: u32 = proc - .read(pImage + std::mem::offset_of!(IMAGE_DOS_HEADER, e_lfanew)) - .expect("bruh"); - let entry: u32 = proc - .read( - pImage - + e_lf as usize - + std::mem::offset_of!(IMAGE_NT_HEADERS64, OptionalHeader.AddressOfEntryPoint), - ) - .expect("bruh"); - let entry = pImage + entry as usize; - println!("entry = {:x}", entry); - let entry_insts: [u8; 2] = proc.read(entry).expect("failed to read entry"); + let image_base_addr: *const c_void = proc + .read(ptr_to_pbi.PebBaseAddress as usize + 0x10) + .expect("the"); + let mut headers = [0; 4096]; + proc.raw_read(image_base_addr as usize, headers.as_mut_ptr(), 4096); + let dos_hdr = transmute::<*const u8, *const IMAGE_DOS_HEADER>(headers.as_ptr()); + let nt_hdrs = transmute::<*const u8, *const IMAGE_NT_HEADERS64>( + headers + .as_ptr() + .wrapping_add((*dos_hdr).e_lfanew.try_into().unwrap()), + ); + let code_entry = + image_base_addr.wrapping_add((*nt_hdrs).OptionalHeader.AddressOfEntryPoint as usize); + println!( + "entry = {:p} B = {:X} C = {:p}", + code_entry, + (*nt_hdrs).OptionalHeader.AddressOfEntryPoint, + image_base_addr + ); + let entry_insts: [u8; 2] = proc + .read(code_entry as usize) + .expect("failed to read entry"); let pay_load: [u8; 2] = [0xEB, 0xFE]; - proc.write(entry, &pay_load); + proc.write(code_entry as usize, &pay_load); // // resume the thread ResumeThread(proc_info.hThread); + // ResumeThread(proc_info.hThread); // wait until trapped... and inject + let sock = UdpSocket::bind("127.0.0.1:28713").expect("failed to bind socket"); { - let sock = UdpSocket::bind("127.0.0.1:28713").expect("failed to bind socket"); - let target = OwnedProcess::from_pid(proc.get_pid()).unwrap(); let syrnge = Syringe::for_process(target); let injmod = syrnge.inject("./target/debug/gdkeinj.dll").unwrap(); println!("waiting until udp is ok "); - sock.recv(&mut [0]); + let (_, addr) = sock.recv_from(&mut [0]).unwrap(); + sock.send_to(&1_u32.to_ne_bytes(), addr).unwrap(); + let _ = sock.recv(&mut []); } // we're done. let's kill the process. - println!("done, restoring..",); - proc.write(entry, &entry_insts); + println!("done, running code after enter..",); + let mut inp = String::new(); + std::io::stdin().read_line(&mut inp); + proc.write(code_entry as usize, &entry_insts); + println!("waiting for call."); + let _ = sock.recv(&mut []); + println!("complete."); TerminateProcess(proc_info.hProcess, 1); } diff --git a/src/main.rs b/src/main.rs index 35c4a80..612d2d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,5 +4,4 @@ fn main() { unsafe { spawn_and_inject("./z421.exe"); } - println!("hi"); } diff --git a/src/versioning.rs b/src/versioning.rs index c544bea..7c6df70 100644 --- a/src/versioning.rs +++ b/src/versioning.rs @@ -1,9 +1,9 @@ use std::{ - io::{Stdin, Stdout}, + io::{BufRead, BufReader, Cursor, Stdin, Stdout}, path::Path, process::{Command, Stdio}, }; -fn check_gd_ver(exe: Path) -> anyhow::Result { +fn check_gd_ver(exe: &Path) -> anyhow::Result { assert!(exe.exists()); let stdo = Command::new(exe) .arg("-V") @@ -11,5 +11,10 @@ fn check_gd_ver(exe: Path) -> anyhow::Result { .arg("random-no-way-a-game-has-this-btw") .stdout(Stdio::null()) .output()?; - stdo.stdout + let bufr = Cursor::new(stdo.stdout); + + Ok(bufr + .lines() + .next() + .ok_or(anyhow::anyhow!("unable to read version"))??) }