diff --git a/Cargo.lock b/Cargo.lock index 7e2ab6e..002c22a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.79" @@ -63,6 +72,25 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "cc" version = "1.0.83" @@ -110,6 +138,25 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "cstr" version = "0.2.11" @@ -130,6 +177,37 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dll-syringe" version = "0.15.2" @@ -175,13 +253,20 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "gdke" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "dll-syringe", "poggers", + "rust-embed", "windows", ] @@ -204,12 +289,36 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "goblin" version = "0.6.1" @@ -312,6 +421,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall", +] + [[package]] name = "libudis86-sys" version = "0.2.1" @@ -418,6 +538,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "path-absolutize" version = "3.1.1" @@ -513,12 +639,34 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] @@ -556,6 +704,42 @@ dependencies = [ "slice-pool2", ] +[[package]] +name = "rust-embed" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82c0bbc10308ed323529fd3c1dce8badda635aa319a5ff0e6466f33b8101e3f" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6227c01b1783cdfee1bcf844eb44594cd16ec71c35305bf1c9fb5aade2735e16" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "shellexpand", + "syn 2.0.48", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb0a25bfbb2d4b4402179c2cf030387d9990857ce08a32592c6238db9fa8665" +dependencies = [ + "globset", + "sha2", + "walkdir", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -624,6 +808,26 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + [[package]] name = "shlex" version = "1.2.0" @@ -761,6 +965,22 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "which" version = "4.4.2" diff --git a/Cargo.toml b/Cargo.toml index 65f36f3..5dd8ce6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ workspace = { members = ["gdkeinj"] } [package] name = "gdke" -version = "0.1.0" +version = "0.2.0" edition = "2021" [profile.release] @@ -19,6 +19,10 @@ strip = false # members = ["gdke-gui"] [dependencies] +rust-embed = { version = "*", features = [ + "include-exclude", + "interpolate-folder-path", +] } anyhow = "*" windows = { features = [ "Win32_Foundation", diff --git a/gdkeinj/src/lib.rs b/gdkeinj/src/lib.rs index 031afc7..4c195c8 100644 --- a/gdkeinj/src/lib.rs +++ b/gdkeinj/src/lib.rs @@ -23,21 +23,20 @@ pub fn main() { ("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"); let proc = Process::this_process(); let modd = proc.get_base_module().unwrap(); println!("sending data, waiting for sig ver"); - sock.send(&buf); + let buf = [1; 1]; + sock.send(&buf).ok(); let mut sig_type = [0; 4]; - sock.recv(&mut sig_type); + sock.recv(&mut sig_type).unwrap(); 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 addr = modd.scan(sig.0).unwrap().unwrap() 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) }; @@ -50,16 +49,17 @@ pub fn main() { unsafe { let open_and_parse = std::mem::transmute::(fn_ptr as isize); let opp = OpenAndParse - .initialize(open_and_parse, move |this, base, key, mode| { + .initialize(open_and_parse, move |_, _, key, _| { let mut read_key = [0u8; 32]; let ptr_to_key = (key as usize + 8) as *const *const u8; std::ptr::copy(*ptr_to_key, read_key.as_mut_ptr(), 32); - sock2.send(read_key.as_slice()); + sock2.send(read_key.as_slice()).unwrap(); + std::thread::sleep(Duration::from_secs(1000)) // panic!("good ridance.") }) .unwrap(); - opp.enable(); + opp.enable().expect("failed to enable detour"); println!("detour enabled {}", opp.is_enabled()); } - sock.send(&[]); + sock.send(&[]).ok(); } diff --git a/src/lib.rs b/src/lib.rs index 06c5159..a8af0de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,26 +1,23 @@ pub mod versioning; use std::{ - error::Error, ffi::{c_void, CStr, CString}, - io::Read, + io::Write, mem::{size_of, transmute}, net::UdpSocket, path::Path, - ptr::{addr_of, null, null_mut}, - time::Duration, }; use dll_syringe::{process::OwnedProcess, Syringe}; -use poggers::{structures::process::Process, traits::Mem}; +use poggers::{exports::HANDLE, structures::process::Process, traits::Mem}; +use rust_embed::RustEmbed; use windows::{ core::{PCSTR, PSTR}, Win32::{ - Foundation::{BOOL, HINSTANCE}, + Foundation::BOOL, System::{ - ProcessStatus::{K32GetModuleInformation, MODULEINFO}, SystemServices::IMAGE_DOS_HEADER, Threading::{ - CreateProcessA, TerminateProcess, CREATE_SUSPENDED, PEB, PROCESS_BASIC_INFORMATION, + CreateProcessA, TerminateProcess, CREATE_SUSPENDED, PROCESS_BASIC_INFORMATION, PROCESS_INFORMATION, STARTUPINFOA, }, }, @@ -28,23 +25,33 @@ use windows::{ }; use windows::{ Wdk::System::Threading::{NtQueryInformationProcess, ProcessBasicInformation}, - Win32::System::{ - Diagnostics::Debug::{GetThreadContext, CONTEXT, IMAGE_NT_HEADERS64}, - Threading::{ResumeThread, SuspendThread}, - }, + Win32::System::{Diagnostics::Debug::IMAGE_NT_HEADERS64, Threading::ResumeThread}, }; fn create_pstr(c_str: &CStr) -> PSTR { PSTR::from_raw(c_str.as_ptr() as *mut u8) } +#[derive(RustEmbed)] +#[folder = "$CARGO_MANIFEST_DIR/target/release"] +#[include = "gdkeinj.dll"] +struct GdkeInj; -pub unsafe fn spawn_and_inject(proc: &str) { +struct ProcKiller(HANDLE); +impl Drop for ProcKiller { + fn drop(&mut self) { + unsafe { + TerminateProcess(self.0, 0).ok(); + } + } +} +pub unsafe fn spawn_and_inject(proc: &str) -> anyhow::Result<[u8; 32]> { let pth = Path::new(proc); if !pth.is_file() { panic!("file does not exist"); } let cmd_line_c = CString::new(proc).expect("invalid cstr"); let start_up_info = STARTUPINFOA { + wShowWindow: 0, ..Default::default() }; let mut proc_info = PROCESS_INFORMATION { @@ -62,23 +69,24 @@ pub unsafe fn spawn_and_inject(proc: &str) { mod_name, &start_up_info, &mut proc_info, - ); + )?; // patch entry point... let mut ptr_to_pbi: PROCESS_BASIC_INFORMATION = std::mem::zeroed(); - let stat = NtQueryInformationProcess( + NtQueryInformationProcess( proc_info.hProcess, ProcessBasicInformation, &mut ptr_to_pbi as *mut _ as *mut c_void, size_of::() as u32, &mut 0, ); + let _pkr = ProcKiller(proc_info.hProcess); let proc = Process::find_pid(proc_info.dwProcessId).unwrap(); 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); + 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 @@ -92,7 +100,7 @@ pub unsafe fn spawn_and_inject(proc: &str) { .read(code_entry as usize) .expect("failed to read entry"); let pay_load: [u8; 2] = [0xEB, 0xFE]; - proc.write(code_entry as usize, &pay_load); + proc.write(code_entry as usize, &pay_load)?; // // resume the thread ResumeThread(proc_info.hThread); @@ -101,33 +109,35 @@ pub unsafe fn spawn_and_inject(proc: &str) { { let target = OwnedProcess::from_pid(proc.get_pid()).unwrap(); let syrnge = Syringe::for_process(target); - let injmod = syrnge - .inject(format!( - "./target/{}/gdkeinj.dll", - if cfg!(debug_assertions) { - "debug" - } else { - "release" - } + let dll_loc = if cfg!(debug_assertions) { + String::from(concat!( + env!("CARGO_MANIFEST_DIR"), + "/target/debug/gdkeinj.dll" )) - .unwrap(); + } else { + let gdke_inj_dll = + GdkeInj::get("gdkeinj.dll").expect("failed to get dll from embeded resources"); + let tmp = std::env::temp_dir(); + let loc = tmp.join("gdkeinj.dll"); + let mut file = std::fs::File::create(&loc).unwrap(); + file.write_all(&gdke_inj_dll.data).unwrap(); + loc.to_str().map(|x| x.to_string()).unwrap() + }; + println!("injecting dll ({})", dll_loc); + syrnge.inject(dll_loc).unwrap(); println!("waiting until udp is ok "); let (_, addr) = sock.recv_from(&mut [0]).unwrap(); sock.send_to(&1_u32.to_ne_bytes(), addr).unwrap(); - let _ = sock.recv(&mut []); + sock.recv(&mut [])?; } // we're done. let's kill the process. println!("done, running code",); - proc.write(code_entry as usize, &entry_insts); + proc.write(code_entry as usize, &entry_insts)?; println!("waiting for call."); let mut key = [0; 32]; - let _ = sock.recv(&mut key); - println!("recieved key: "); - for val in key { - print!("{:x}", val); - } - println!("\ncomplete."); - TerminateProcess(proc_info.hProcess, 1); + sock.recv(&mut key)?; + println!("recieved key, term"); + Ok(key) } diff --git a/src/main.rs b/src/main.rs index 571e71b..0329f95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,13 @@ use gdke::spawn_and_inject; fn main() { unsafe { - spawn_and_inject(&std::env::args().nth(1).unwrap()); + let key = + spawn_and_inject(&std::env::args().nth(1).unwrap()).expect("failed to resolve key"); + print!("key: "); + for val in key { + print!("{:x}", val); + } + println!("\npress enter to close"); + let _ = std::io::stdin().read_line(&mut String::new()); } } diff --git a/src/versioning.rs b/src/versioning.rs index 7c6df70..a1df36a 100644 --- a/src/versioning.rs +++ b/src/versioning.rs @@ -1,5 +1,5 @@ use std::{ - io::{BufRead, BufReader, Cursor, Stdin, Stdout}, + io::{BufRead, Cursor}, path::Path, process::{Command, Stdio}, };