feat: add RSA patch for AccountRSAKey

This commit is contained in:
amizing25
2025-03-16 15:14:45 +07:00
parent bc651397e6
commit 3f6933c096
9 changed files with 64 additions and 9 deletions

View File

@@ -1,4 +1,7 @@
redirect HTTP requests & remove censorship! features:
- redirect HTTP requests
- remove censorship
- replace AccountRSAKey into custom public key (by default, compatible with [hoyo-sdk by xeondev](https://git.xeondev.com/reversedrooms/hoyo-sdk))
currently, this has only been tested on CNBETAWin3.1.53 and may require an update for future versions. currently, this has only been tested on CNBETAWin3.1.53 and may require an update for future versions.

1
hkrpg/sdk_public_key.xml Normal file
View File

@@ -0,0 +1 @@
<RSAKeyValue><Exponent>AQAB</Exponent><Modulus>hEegnKISgDas5VTuRBUlixB+bvmPvXKa3kVO22UEZjPGMUFLmIl3DhH+dsZo7qJn/GfJCUkP1FA0MJ5Bj8PX8IatLJKIJ9dMCNdnAlkXTlMg86QQAhHZN83vP4swj5ILcrGNKl3YAZ49fvzo7nheuTt0/40f0HkHdNa1dUHECBs=</Modulus></RSAKeyValue>

View File

@@ -10,6 +10,7 @@ const SET_ELEVATION_DITHER: &str = "E9 ? ? ? ? 0F 28 74 24 ? 48 83 C4 ? 5B 5F 5E
const SET_DISTANCE_DITHER: &str = "E8 ? ? ? ? 49 8B 46 ? 48 85 C0 0F 84 ? ? ? ? 48 8B 4D"; // TODO const SET_DISTANCE_DITHER: &str = "E8 ? ? ? ? 49 8B 46 ? 48 85 C0 0F 84 ? ? ? ? 48 8B 4D"; // TODO
const SET_DITHER_ALPHA: &str = "56 57 48 83 EC ? 0F 29 74 24 ? 44 89 C6 0F 28 F1 48 89 CF 80 3D ? ? ? ? ? 75 ? 80 7F"; // TODO const SET_DITHER_ALPHA: &str = "56 57 48 83 EC ? 0F 29 74 24 ? 44 89 C6 0F 28 F1 48 89 CF 80 3D ? ? ? ? ? 75 ? 80 7F"; // TODO
const SET_DITHER_ALPHA_ANIM: &str = "56 57 55 53 48 83 EC ? 44 0F 29 44 24 ? 0F 29 7C 24 ? 0F 29 74 24 ? 44 0F 28 C3 0F 28 F2 0F 28 F9"; // TODO const SET_DITHER_ALPHA_ANIM: &str = "56 57 55 53 48 83 EC ? 44 0F 29 44 24 ? 0F 29 7C 24 ? 0F 29 74 24 ? 44 0F 28 C3 0F 28 F2 0F 28 F9"; // TODO
const SDK_PUBLIC_KEY_LITERAL: &str = "48 8B 0D ? ? ? ? 4C 89 FA E8 ? ? ? ? 48 89 C1 E8 ? ? ? ? 48 8B 15 ? ? ? ? 48 89 F1";
// const HK_CHECK1: &str = "55 41 56 56 57 53 48 81 EC 00 01 00 00 48 8D AC 24 80 00 00 00 C7 45 7C 00 00 00 00"; // const HK_CHECK1: &str = "55 41 56 56 57 53 48 81 EC 00 01 00 00 48 8D AC 24 80 00 00 00 C7 45 7C 00 00 00 00";
// const HK_CHECK2: &str = "55 41 57 41 56 41 55 41 54 56 57 53 48 81 EC B8 02 00 00"; // const HK_CHECK2: &str = "55 41 57 41 56 41 55 41 54 56 57 53 48 81 EC B8 02 00 00";
@@ -23,6 +24,7 @@ pub struct RVAConfig {
pub set_dither_alpha_anim: usize, pub set_dither_alpha_anim: usize,
pub hk_check1: usize, pub hk_check1: usize,
pub hk_check2: usize, pub hk_check2: usize,
pub sdk_public_key: usize,
} }
#[allow(static_mut_refs)] #[allow(static_mut_refs)]
@@ -120,6 +122,16 @@ pub unsafe fn init_rvas() {
0x0 0x0
); );
// sdk_public_key_literal
set_rva!(
GAME_ASSEMBLY_BASE,
config,
sdk_public_key,
scan_il2cpp_section,
SDK_PUBLIC_KEY_LITERAL,
0x0
)
// set_rva!( // set_rva!(
// UNITY_PLAYER_BASE, // UNITY_PLAYER_BASE,
// config, // config,

View File

@@ -3,7 +3,8 @@
use std::{thread, time::Duration}; use std::{thread, time::Duration};
use modules::{ use modules::{
HkrpgModuleManager, censorship_patch::CensorshipPatch, hk_check::HkCheck, network::Network, HkrpgModuleManager, censorship_patch::CensorshipPatch, crypto::Crypto, hk_check::HkCheck,
network::Network,
}; };
use windows::{ use windows::{
Win32::System::{Console, LibraryLoader::GetModuleHandleA}, Win32::System::{Console, LibraryLoader::GetModuleHandleA},
@@ -31,6 +32,7 @@ pub fn main() {
let mut module_manager = HkrpgModuleManager::default(); let mut module_manager = HkrpgModuleManager::default();
module_manager.add::<HkCheck>(); module_manager.add::<HkCheck>();
module_manager.add::<Network>(); module_manager.add::<Network>();
module_manager.add::<Crypto>();
module_manager.add::<CensorshipPatch>(); module_manager.add::<CensorshipPatch>();
module_manager module_manager
.init() .init()

View File

@@ -0,0 +1,26 @@
use crate::{
addr::{GAME_ASSEMBLY_BASE, rva_config},
il2cpp_string::Il2cppString,
};
use super::{HkrpgModule, HkrpgModuleContext};
pub struct Crypto;
const ACCOUNT_RSA_KEY_REPLACEMENT: &str = include_str!("../../sdk_public_key.xml");
impl HkrpgModule for HkrpgModuleContext<Crypto> {
unsafe fn init(&mut self) -> Result<(), ilhook::HookError> {
let config = rva_config();
if config.sdk_public_key != 0 {
unsafe {
*(GAME_ASSEMBLY_BASE.wrapping_add(config.sdk_public_key) as *mut Il2cppString) =
Il2cppString::new(ACCOUNT_RSA_KEY_REPLACEMENT)
}
println!("[crypto::init] AccountRSAKey replaced")
} else {
println!("[crypto::init] pattern is outdated! disabling AccountRSAKey replacement")
}
Ok(())
}
}

View File

@@ -18,6 +18,7 @@ impl HkrpgModule for HkrpgModuleContext<HkCheck> {
self.base.wrapping_add(config.hk_check2), self.base.wrapping_add(config.hk_check2),
HkCheck::replacement, HkCheck::replacement,
)?; )?;
println!("[hk_check::init] hk_check bypassed")
} }
Ok(()) Ok(())
} }

View File

@@ -3,6 +3,7 @@ use std::marker::PhantomData;
use crate::{addr, interceptor::Interceptor}; use crate::{addr, interceptor::Interceptor};
pub mod censorship_patch; pub mod censorship_patch;
pub mod crypto;
pub mod hk_check; pub mod hk_check;
pub mod network; pub mod network;

View File

@@ -14,6 +14,7 @@ impl HkrpgModule for HkrpgModuleContext<Network> {
self.base.wrapping_add(config.make_initial_url), self.base.wrapping_add(config.make_initial_url),
Network::on_make_initial_url, Network::on_make_initial_url,
)?; )?;
println!("[network::init] network patch enabled")
} else { } else {
println!("[network::init] pattern is outdated! disabling http redirection") println!("[network::init] pattern is outdated! disabling http redirection")
} }

View File

@@ -42,14 +42,22 @@ pub unsafe fn scan_il2cpp_section(pat: &str) -> Option<usize> {
let mut slice = unsafe { game_assembly_slice() }; let mut slice = unsafe { game_assembly_slice() };
scan_first_match(&mut slice, pat).unwrap().map(|address| { scan_first_match(&mut slice, pat).unwrap().map(|address| {
let slice = unsafe { game_assembly_slice() }; let slice = unsafe { game_assembly_slice() };
let instruction = &slice[address..address + 1][0]; match slice.get(address) {
if *instruction == 0xE8 { // jmp sub_xxxxxxx
let offset = Some(&0xE8) => {
i32::from_le_bytes((&slice[address + 1..address + 1 + 4]).try_into().unwrap()); let offset = i32::from_le_bytes(slice[address + 1..address + 5].try_into().unwrap());
let pointer = offset as usize + 5 + address; GAME_ASSEMBLY_BASE.wrapping_add(address + 5 + offset as usize)
return GAME_ASSEMBLY_BASE.wrapping_add(pointer); }
// mov rcx, [rip + offset] (0x48 0x8B 0x0D XXXXXXXX)
Some(&0x48)
if slice.get(address + 1) == Some(&0x8B)
&& slice.get(address + 2) == Some(&0x0D) =>
{
let offset = i32::from_le_bytes(slice[address + 3..address + 7].try_into().unwrap());
GAME_ASSEMBLY_BASE.wrapping_add(address + 7 + offset as usize)
}
_ => GAME_ASSEMBLY_BASE.wrapping_add(address),
} }
GAME_ASSEMBLY_BASE.wrapping_add(address)
}) })
} }