mirror of https://github.com/pozm/gdke.git
some work on older versions
This commit is contained in:
parent
c8606ec99b
commit
1569ca2dae
|
@ -267,6 +267,7 @@ dependencies = [
|
|||
"dll-syringe",
|
||||
"poggers",
|
||||
"rust-embed",
|
||||
"thiserror",
|
||||
"windows",
|
||||
]
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ rust-embed = { version = "*", features = [
|
|||
"interpolate-folder-path",
|
||||
] }
|
||||
anyhow = "*"
|
||||
thiserror = "*"
|
||||
windows = { features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_System",
|
||||
|
|
|
@ -14,37 +14,62 @@ static_detour! {
|
|||
pub static OpenAndParse: unsafe extern "fastcall" fn(*const i32, *const i32, *const u8, bool) -> ();
|
||||
}
|
||||
|
||||
#[cfg_attr(debug_assertions, poggers_derive::create_entry)]
|
||||
#[cfg_attr(not(debug_assertions), poggers_derive::create_entry(no_console))]
|
||||
pub fn main() {
|
||||
let mut sigs = HashMap::<u32, (&'static str, i32)>::new();
|
||||
sigs.insert(
|
||||
1,
|
||||
("E8 ? ? ? ? 85 C0 0F 84 ? ? ? ? 49 8B 8C 24 ? ? ? ?", -0x3c),
|
||||
);
|
||||
let sock = UdpSocket::bind("127.0.0.1:29849").unwrap();
|
||||
sock.connect("127.0.0.1:28713").expect("uanble to connect");
|
||||
|
||||
const SIGS: [&str; 2] = [
|
||||
// call into open_and_parse
|
||||
"E8 ? ? ? ? 85 C0 0F 84 ? ? ? ? 49 8B 8C 24 ? ? ? ?", // 4.x (4.2.1)
|
||||
"E8 ? ? ? ? 8B D8 85 C0 0F 84 ? ? ? ? 49 8B 04 24", // 3.x
|
||||
];
|
||||
#[repr(u8)]
|
||||
#[derive(Debug)]
|
||||
enum SigErrors {
|
||||
NotFound,
|
||||
}
|
||||
fn find_sig_addr(sig_type: usize) -> Result<*const c_void, SigErrors> {
|
||||
let proc = Process::this_process();
|
||||
let modd = proc.get_base_module().unwrap();
|
||||
|
||||
println!("sending data, waiting for sig ver");
|
||||
let buf = [1; 1];
|
||||
sock.send(&buf).ok();
|
||||
|
||||
let mut sig_type = [0; 4];
|
||||
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 addr = modd.scan(sig.0).unwrap().unwrap() as isize;
|
||||
let sig = SIGS
|
||||
.get(sig_type as usize)
|
||||
.ok_or_else(|| SigErrors::NotFound)?;
|
||||
let addr = modd
|
||||
.scan(sig)
|
||||
.map_err(|_| SigErrors::NotFound)?
|
||||
.ok_or_else(|| SigErrors::NotFound)? as isize;
|
||||
println!("sig found: {:x} ", addr);
|
||||
let ptr_to_fn = (addr as usize + size_of::<u8>()) 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);
|
||||
let fn_ptr = (addr + by as isize + 5) as *const c_void;
|
||||
println!("fnptr = {:x?}", fn_ptr);
|
||||
println!("fnptr = {:x?} B = ${addr_offset:?}, ${by:?}", fn_ptr);
|
||||
|
||||
Ok(fn_ptr)
|
||||
}
|
||||
#[cfg_attr(debug_assertions, poggers_derive::create_entry(no_free))]
|
||||
#[cfg_attr(not(debug_assertions), poggers_derive::create_entry(no_console))]
|
||||
pub fn main() {
|
||||
let sock = UdpSocket::bind("127.0.0.1:29849").unwrap();
|
||||
sock.connect("127.0.0.1:28713").expect("uanble to connect");
|
||||
|
||||
println!("sending data, waiting for sig ver");
|
||||
let buf = [];
|
||||
sock.send(&buf).ok();
|
||||
|
||||
let mut sig_type = [0; 4];
|
||||
sock.recv(&mut sig_type).unwrap();
|
||||
let int_sig = u32::from_ne_bytes(sig_type);
|
||||
let fn_ptr = find_sig_addr(int_sig as usize);
|
||||
let fn_ptr = match fn_ptr {
|
||||
Ok(x) => x,
|
||||
Err(err) => {
|
||||
println!("err {err:?}");
|
||||
|
||||
std::thread::sleep(Duration::from_secs(100));
|
||||
sock.send(&[err as u8]).ok();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("sig found: {:x} ", addr);
|
||||
let sock2 = sock.try_clone().unwrap();
|
||||
unsafe {
|
||||
let open_and_parse = std::mem::transmute::<isize, open_and_parse_t>(fn_ptr as isize);
|
||||
|
@ -61,5 +86,5 @@ pub fn main() {
|
|||
opp.enable().expect("failed to enable detour");
|
||||
println!("detour enabled {}", opp.is_enabled());
|
||||
}
|
||||
sock.send(&[]).ok();
|
||||
sock.send(&(400195u32.to_ne_bytes())).ok();
|
||||
}
|
||||
|
|
54
src/lib.rs
54
src/lib.rs
|
@ -10,6 +10,7 @@ use std::{
|
|||
use dll_syringe::{process::OwnedProcess, Syringe};
|
||||
use poggers::{exports::HANDLE, structures::process::Process, traits::Mem};
|
||||
use rust_embed::RustEmbed;
|
||||
use thiserror::Error;
|
||||
use windows::{
|
||||
core::{PCSTR, PSTR},
|
||||
Win32::{
|
||||
|
@ -28,6 +29,22 @@ use windows::{
|
|||
Win32::System::{Diagnostics::Debug::IMAGE_NT_HEADERS64, Threading::ResumeThread},
|
||||
};
|
||||
|
||||
use crate::versioning::check_gd_ver;
|
||||
#[repr(u8)]
|
||||
#[derive(Error, Debug)]
|
||||
enum SigErrors {
|
||||
#[error("Signature not found")]
|
||||
NotFound,
|
||||
}
|
||||
impl From<u8> for SigErrors {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
0 => Self::NotFound,
|
||||
default => Self::NotFound,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_pstr(c_str: &CStr) -> PSTR {
|
||||
PSTR::from_raw(c_str.as_ptr() as *mut u8)
|
||||
}
|
||||
|
@ -106,7 +123,7 @@ pub unsafe fn spawn_and_inject(proc: &str) -> anyhow::Result<[u8; 32]> {
|
|||
ResumeThread(proc_info.hThread);
|
||||
// wait until trapped... and inject
|
||||
let sock = UdpSocket::bind("127.0.0.1:28713").expect("failed to bind socket");
|
||||
{
|
||||
let res: anyhow::Result<()> = {
|
||||
let target = OwnedProcess::from_pid(proc.get_pid()).unwrap();
|
||||
let syrnge = Syringe::for_process(target);
|
||||
let dll_loc = if cfg!(debug_assertions) {
|
||||
|
@ -123,21 +140,50 @@ pub unsafe fn spawn_and_inject(proc: &str) -> anyhow::Result<[u8; 32]> {
|
|||
file.write_all(&gdke_inj_dll.data).unwrap();
|
||||
loc.to_str().map(|x| x.to_string()).unwrap()
|
||||
};
|
||||
let game_ver = check_gd_ver(pth)?;
|
||||
println!("gamever = {game_ver}");
|
||||
let sig_id = match game_ver
|
||||
.chars()
|
||||
.next()
|
||||
.ok_or(anyhow::anyhow!("unable to check gd version"))?
|
||||
{
|
||||
'4' => 0u32,
|
||||
'3' => 1u32,
|
||||
_ => return Err(anyhow::anyhow!("invalid godot version")),
|
||||
};
|
||||
|
||||
println!("injecting dll ({})", dll_loc);
|
||||
syrnge.inject(dll_loc).unwrap();
|
||||
syrnge.inject(dll_loc)?;
|
||||
|
||||
println!("waiting until udp is ok ");
|
||||
|
||||
let (_, addr) = sock.recv_from(&mut [0]).unwrap();
|
||||
sock.send_to(&1_u32.to_ne_bytes(), addr).unwrap();
|
||||
sock.recv(&mut [])?;
|
||||
println!("using sig id {sig_id}");
|
||||
sock.send_to(&sig_id.to_ne_bytes(), addr).unwrap();
|
||||
let mut error = [0u8; 4];
|
||||
sock.recv(&mut error)?;
|
||||
println!("errors -> {error:?}");
|
||||
if error.is_empty() {
|
||||
return Err(SigErrors::from(error[0]).into());
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
res?;
|
||||
// we're done. let's kill the process.
|
||||
println!("done, running code",);
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
println!("[debug] waiting for input");
|
||||
std::io::stdin().read_line(&mut String::new());
|
||||
}
|
||||
proc.write(code_entry as usize, &entry_insts)?;
|
||||
println!("waiting for call.");
|
||||
let mut key = [0; 32];
|
||||
sock.recv(&mut key)?;
|
||||
if key.len() == 1 {
|
||||
eprintln!("recieved err");
|
||||
return Err(SigErrors::from(key[0]).into());
|
||||
}
|
||||
println!("recieved key, term");
|
||||
Ok(key)
|
||||
}
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
use std::{
|
||||
io::{BufRead, Cursor},
|
||||
io::{BufRead, Cursor, Read},
|
||||
path::Path,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
fn check_gd_ver(exe: &Path) -> anyhow::Result<String> {
|
||||
pub fn check_gd_ver(exe: &Path) -> anyhow::Result<String> {
|
||||
assert!(exe.exists());
|
||||
let stdo = Command::new(exe)
|
||||
.arg("-V")
|
||||
.arg("-s")
|
||||
.arg("random-no-way-a-game-has-this-btw")
|
||||
.stdout(Stdio::null())
|
||||
.arg("--version")
|
||||
// .stderr(Stdio::null())
|
||||
.output()?;
|
||||
let bufr = Cursor::new(stdo.stdout);
|
||||
let mut bufr = Cursor::new(stdo.stdout);
|
||||
|
||||
Ok(bufr
|
||||
.lines()
|
||||
.next()
|
||||
.ok_or(anyhow::anyhow!("unable to read version"))??)
|
||||
let mut out = String::new();
|
||||
bufr.read_to_string(&mut out)
|
||||
.map_err(|_| anyhow::anyhow!("unable to read version"))?;
|
||||
Ok(out.trim().to_string())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue