From e2a8ef41306f3878ac44ee66c0ad733091a409ac Mon Sep 17 00:00:00 2001 From: xavo95 Date: Sat, 2 Nov 2024 01:40:31 +0100 Subject: [PATCH] Support mods --- Cargo.lock | 9 +++++++ Cargo.toml | 7 ++++-- build.bat | 30 ++++++++++++++-------- src/extras.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++ src/interceptor.rs | 50 ------------------------------------ src/lib.rs | 59 +++++-------------------------------------- src/offsets.rs | 19 ++++++++------ src/replacer.rs | 1 + 8 files changed, 116 insertions(+), 122 deletions(-) create mode 100644 src/extras.rs delete mode 100644 src/interceptor.rs diff --git a/Cargo.lock b/Cargo.lock index fe9f8cb..daef179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,14 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "interceptor-rs" +version = "0.1.0" +source = "git+https://git.xeondev.com/xavo95/interceptor-rs.git#282da6f98b8e4a4e9844422343d4ce11606c9de6" +dependencies = [ + "ilhook", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -148,6 +156,7 @@ name = "wicked-waifus-win-patch" version = "0.1.0" dependencies = [ "ilhook", + "interceptor-rs", "regex", "widestring", "windows", diff --git a/Cargo.toml b/Cargo.toml index 52c9152..d7e9871 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,11 +13,14 @@ cn_beta_1_3_0 = [] cn_live_1_3_0 = [] os_live_1_3_0 = [] enable-sdk = [] +only-sig-bypass = [] +regular = ["dep:regex", "dep:widestring"] [dependencies] ilhook = "2.1.1" -regex = "1.11.1" -widestring = "1.1.0" +interceptor-rs = { git = "https://git.xeondev.com/xavo95/interceptor-rs.git" } +regex = {version = "1.11.1", optional = true} +widestring = {version = "1.1.0", optional = true} windows = { version = "0.58.0", features = [ "Win32_Foundation", "Win32_System_LibraryLoader", diff --git a/build.bat b/build.bat index f943c00..a37619e 100644 --- a/build.bat +++ b/build.bat @@ -4,24 +4,34 @@ GOTO:MAIN SETLOCAL ENABLEDELAYEDEXPANSION cargo clean cargo build --release --no-default-features -F %~1 - set features=%~1:,=-% - COPY target\release\wicked_waifus_win.dll build\wicked-waifus-win-%~1.dll + set features=%~1 + set cleaned_features=%features:,=-% + COPY target\release\wicked_waifus_win.dll build\%~2\wicked-waifus-win-%cleaned_features%.dll cargo clean ENDLOCAL EXIT /B 0 +:buildAllVariants + SETLOCAL ENABLEDELAYEDEXPANSION + : Build for cn_beta_1_4_0 + call:cargoReleaseBuild "cn_beta_1_4_0,%~1" %~1 + : Build for cn_beta_1_3_0 + call:cargoReleaseBuild "cn_beta_1_3_0,%~1" %~1 + : Build for cn_live_1_3_0 + call:cargoReleaseBuild "cn_live_1_3_0,%~1" %~1 + : Build for os_live_1_3_0 + call:cargoReleaseBuild "os_live_1_3_0,%~1" %~1 + ENDLOCAL +EXIT /B 0 + :MAIN if exist "build" rd /q /s "build" mkdir build +mkdir build\regular +mkdir build\only-sig-bypass cargo clean -: Build for cn_beta_1_4_0 -call:cargoReleaseBuild cn_beta_1_4_0 -: Build for cn_beta_1_3_0 -call:cargoReleaseBuild cn_beta_1_3_0 -: Build for cn_live_1_3_0 -call:cargoReleaseBuild cn_live_1_3_0 -: Build for os_live_1_3_0 -call:cargoReleaseBuild os_live_1_3_0 +call:buildAllVariants regular +call:buildAllVariants only-sig-bypass tar -acvf wicked-waifus-win-patch-win64.zip -C build . \ No newline at end of file diff --git a/src/extras.rs b/src/extras.rs new file mode 100644 index 0000000..0e3c030 --- /dev/null +++ b/src/extras.rs @@ -0,0 +1,63 @@ +#![cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] +use std::sync::OnceLock; +use std::thread; +use std::time::Duration; + +use ilhook::x64::Registers; +use windows::core::{PCSTR, PCWSTR}; +use windows::Win32::System::LibraryLoader::GetModuleHandleA; + +use crate::offsets::CONFIG; +use crate::replacer::{GenericReplacer, Replacer}; + +static CFG_SERVER_REPLACER: OnceLock = OnceLock::new(); + +pub(crate) fn configure_extras(interceptor: &mut interceptor_rs::Interceptor) { + let module = unsafe { GetModuleHandleA(PCSTR::null()) }.unwrap(); + println!("Game base: {:X}", module.0 as usize); + + interceptor + .attach((module.0 as usize) + CONFIG.kuro_http_get, on_kurohttp_get) + .unwrap(); + + let krsdk_ex = loop { + match unsafe { GetModuleHandleA(CONFIG.disable_sdk.sdk_dll) } { + Ok(handle) => break handle, + Err(_) => thread::sleep(Duration::from_millis(1)), + } + }; + + interceptor + .replace((krsdk_ex.0 as usize) + CONFIG.disable_sdk.eula_accept, dummy) + .unwrap(); + + interceptor + .replace((krsdk_ex.0 as usize) + CONFIG.disable_sdk.sdk_go_away, dummy) + .unwrap(); +} + +unsafe extern "win64" fn on_kurohttp_get(reg: *mut Registers, _: usize) { + let wstr = *((*reg).rcx as *const usize) as *mut u16; + let url = PCWSTR::from_raw(wstr).to_string().unwrap(); + println!("HTTP GET: {url}"); + + let replacer = CFG_SERVER_REPLACER.get_or_init(|| { + GenericReplacer { + regex: regex::Regex::new(r#"^(?:https|http)://.*/([a-zA-Z0-9]{32}/index\.json)$"#).unwrap(), + replacement: std::env::var("CFG_SERVER_URL").unwrap_or("127.0.0.1:10001".to_string()), + scheme: std::env::var("CFG_SERVER_SCHEME").unwrap_or("http".to_string()), + } + }); + + if let Some(result) = replacer.replace(url.as_str()) { + println!("Redirecting to: {result}"); + // TODO: Track https://doc.rust-lang.org/nightly/unstable-book/library-features/str-from-utf16-endian.html to replace widestring when stabilized + let new_url = widestring::U16String::from_str(result.as_str()); + let new_wstr = PCWSTR::from_raw(new_url.as_ptr()); + std::ptr::copy_nonoverlapping(new_wstr.as_ptr(), wstr, new_wstr.as_wide().len() + 2); + }; +} + +unsafe extern "win64" fn dummy(_: *mut Registers, _: usize, _: usize) -> usize { + 1 +} \ No newline at end of file diff --git a/src/interceptor.rs b/src/interceptor.rs deleted file mode 100644 index 81209e7..0000000 --- a/src/interceptor.rs +++ /dev/null @@ -1,50 +0,0 @@ -use ilhook::x64::{ - CallbackOption, Hooker, HookFlags, HookPoint, HookType, JmpBackRoutine, RetnRoutine, -}; - -pub struct Interceptor { - pub hooks: Vec, -} - -impl Interceptor { - pub const fn new() -> Self { - Self { hooks: Vec::new() } - } - - #[allow(dead_code)] - pub fn attach( - &mut self, - addr: usize, - routine: JmpBackRoutine, - ) -> Result<(), ilhook::HookError> { - let hooker = Hooker::new( - addr, - HookType::JmpBack(routine), - CallbackOption::None, - 0, - HookFlags::empty(), - ); - - let hook_point = unsafe { hooker.hook() }?; - self.hooks.push(hook_point); - Ok(()) - } - - pub fn replace( - &mut self, - addr: usize, - routine: RetnRoutine, - ) -> Result<(), ilhook::HookError> { - let hooker = Hooker::new( - addr, - HookType::Retn(routine), - CallbackOption::None, - 0, - HookFlags::empty(), - ); - - let hook_point = unsafe { hooker.hook() }?; - self.hooks.push(hook_point); - Ok(()) - } -} diff --git a/src/lib.rs b/src/lib.rs index caae7d5..e13a8e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,24 +1,21 @@ -use std::sync::OnceLock; use std::thread; use std::time::Duration; use ilhook::x64::Registers; +use interceptor_rs::Interceptor; use windows::core::{PCSTR, PCWSTR}; use windows::Win32::Foundation::HINSTANCE; use windows::Win32::System::Console; use windows::Win32::System::LibraryLoader::GetModuleHandleA; use windows::Win32::System::SystemServices::DLL_PROCESS_ATTACH; -use interceptor::Interceptor; use offsets::CONFIG; -use crate::replacer::{GenericReplacer, Replacer}; - -mod interceptor; mod offsets; +#[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] mod replacer; - -static CFG_SERVER_REPLACER: OnceLock = OnceLock::new(); +#[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] +mod extras; fn thread_func() { unsafe { Console::AllocConsole() }.unwrap(); @@ -41,54 +38,14 @@ fn thread_func() { .replace((module.0 as usize) + CONFIG.f_pak_file_check, fpakfile_check_replacement) .unwrap(); - let module = unsafe { GetModuleHandleA(PCSTR::null()) }.unwrap(); - println!("Game base: {:X}", module.0 as usize); + #[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] + extras::configure_extras(&mut interceptor); - interceptor - .attach((module.0 as usize) + CONFIG.kuro_http_get, on_kurohttp_get) - .unwrap(); - - let krsdk_ex = loop { - match unsafe { GetModuleHandleA(CONFIG.disable_sdk.sdk_dll) } { - Ok(handle) => break handle, - Err(_) => thread::sleep(Duration::from_millis(1)), - } - }; - - interceptor - .replace((krsdk_ex.0 as usize) + CONFIG.disable_sdk.eula_accept, dummy) - .unwrap(); - - interceptor - .replace((krsdk_ex.0 as usize) + CONFIG.disable_sdk.sdk_go_away, dummy) - .unwrap(); println!("Successfully initialized!"); thread::sleep(Duration::from_secs(u64::MAX)); } -unsafe extern "win64" fn on_kurohttp_get(reg: *mut Registers, _: usize) { - let wstr = *((*reg).rcx as *const usize) as *mut u16; - let url = PCWSTR::from_raw(wstr).to_string().unwrap(); - println!("HTTP GET: {url}"); - - let replacer = CFG_SERVER_REPLACER.get_or_init(|| { - GenericReplacer { - regex: regex::Regex::new(r#"^(?:https|http)://.*/([a-zA-Z0-9]{32}/index\.json)$"#).unwrap(), - replacement: std::env::var("CFG_SERVER_URL").unwrap_or("127.0.0.1:10001".to_string()), - scheme: std::env::var("CFG_SERVER_SCHEME").unwrap_or("http".to_string()), - } - }); - - if let Some(result) = replacer.replace(url.as_str()) { - println!("Redirecting to: {result}"); - // TODO: Track https://doc.rust-lang.org/nightly/unstable-book/library-features/str-from-utf16-endian.html to replace widestring when stabilized - let new_url = widestring::U16String::from_str(result.as_str()); - let new_wstr = PCWSTR::from_raw(new_url.as_ptr()); - std::ptr::copy_nonoverlapping(new_wstr.as_ptr(), wstr, new_wstr.as_wide().len() + 2); - }; -} - unsafe extern "win64" fn fpakfile_check_replacement( reg: *mut Registers, _: usize, @@ -101,10 +58,6 @@ unsafe extern "win64" fn fpakfile_check_replacement( 1 } -unsafe extern "win64" fn dummy(_: *mut Registers, _: usize, _: usize) -> usize { - 1 -} - #[no_mangle] unsafe extern "system" fn DllMain(_: HINSTANCE, call_reason: u32, _: *mut ()) -> bool { if call_reason == DLL_PROCESS_ATTACH { diff --git a/src/offsets.rs b/src/offsets.rs index b06c1c8..1d71333 100644 --- a/src/offsets.rs +++ b/src/offsets.rs @@ -1,7 +1,7 @@ -#[cfg(not(feature = "enable-sdk"))] +#[cfg(all(not(feature = "enable-sdk"), not(feature = "only-sig-bypass"), feature = "regular"))] use windows::core::{PCSTR, s}; -#[cfg(not(feature = "enable-sdk"))] +#[cfg(all(not(feature = "enable-sdk"), not(feature = "only-sig-bypass"), feature = "regular"))] pub(crate) struct DisableSdkConfiguration { pub(crate) sdk_dll: PCSTR, pub(crate) eula_accept: usize, @@ -11,8 +11,9 @@ pub(crate) struct DisableSdkConfiguration { pub(crate) struct InjectConfiguration { pub(crate) f_pak_file_check: usize, pub(crate) f_pak_file_check_preamble: u64, + #[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] pub(crate) kuro_http_get: usize, - #[cfg(not(feature = "enable-sdk"))] + #[cfg(all(not(feature = "enable-sdk"), not(feature = "only-sig-bypass"), feature = "regular"))] pub(crate) disable_sdk: DisableSdkConfiguration, } @@ -20,8 +21,9 @@ pub(crate) struct InjectConfiguration { pub(crate) const CONFIG: InjectConfiguration = InjectConfiguration { f_pak_file_check: 0x3E37D90, // 0x3E37D90 f_pak_file_check_preamble: 0x8148574157565340, + #[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] kuro_http_get: 0xFE9E00, - #[cfg(not(feature = "enable-sdk"))] + #[cfg(all(not(feature = "enable-sdk"), not(feature = "only-sig-bypass"), feature = "regular"))] disable_sdk: DisableSdkConfiguration{ sdk_dll: s!("KRSDKEx.dll"), eula_accept: 0x4A6D0, @@ -33,8 +35,9 @@ pub(crate) const CONFIG: InjectConfiguration = InjectConfiguration { pub(crate) const CONFIG: InjectConfiguration = InjectConfiguration { f_pak_file_check: 0x3D2F460, f_pak_file_check_preamble: 0x8148574157565340, + #[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] kuro_http_get: 0xFC8CF0, - #[cfg(not(feature = "enable-sdk"))] + #[cfg(all(not(feature = "enable-sdk"), not(feature = "only-sig-bypass"), feature = "regular"))] disable_sdk: DisableSdkConfiguration{ sdk_dll: s!("KRSDKEx.dll"), eula_accept: 0x4A690, @@ -46,8 +49,9 @@ pub(crate) const CONFIG: InjectConfiguration = InjectConfiguration { pub(crate) const CONFIG: InjectConfiguration = InjectConfiguration { f_pak_file_check: 0x3D35DF0, f_pak_file_check_preamble: 0x8148574157565340, + #[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] kuro_http_get: 0xFC9900, - #[cfg(not(feature = "enable-sdk"))] + #[cfg(all(not(feature = "enable-sdk"), not(feature = "only-sig-bypass"), feature = "regular"))] disable_sdk: DisableSdkConfiguration{ sdk_dll: s!("KRSDKEx.dll"), eula_accept: 0x4A690, @@ -59,8 +63,9 @@ pub(crate) const CONFIG: InjectConfiguration = InjectConfiguration { pub(crate) const CONFIG: InjectConfiguration = InjectConfiguration { f_pak_file_check: 0x3CDC430, f_pak_file_check_preamble: 0x8148574157565340, + #[cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] kuro_http_get: 0xFC6C20, - #[cfg(not(feature = "enable-sdk"))] + #[cfg(all(not(feature = "enable-sdk"), not(feature = "only-sig-bypass"), feature = "regular"))] disable_sdk: DisableSdkConfiguration{ sdk_dll: s!("KRSDK.dll"), eula_accept: 0x95440, diff --git a/src/replacer.rs b/src/replacer.rs index 68a8e44..d760a9a 100644 --- a/src/replacer.rs +++ b/src/replacer.rs @@ -1,3 +1,4 @@ +#![cfg(all(not(feature = "only-sig-bypass"), feature = "regular"))] pub(crate) trait Replacer { fn replace(&self, original: &str) -> Option; }