fix: re-encode hijacked responses the same way as the originals

This commit is contained in:
Adamaq01 2023-07-16 08:30:16 +02:00
parent b06551e338
commit 8042e303ac
2 changed files with 28 additions and 19 deletions

View File

@ -5,7 +5,7 @@ use crate::{helpers, TACHI_PBS_URL};
use anyhow::Result; use anyhow::Result;
use dynfmt::Format; use dynfmt::Format;
use ext::HashMapExt; use ext::HashMapExt;
use kbinxml::{CompressionType, EncodingType, Node, Options, Value, ValueArray}; use kbinxml::{Node, Value, ValueArray};
use log::info; use log::info;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::HashMap; use std::collections::HashMap;
@ -20,7 +20,7 @@ fn build_response_base(scores: Vec<Node>) -> Node {
) )
} }
pub fn process_pbs(user: &str, music: &Node, encoding: EncodingType) -> Result<Vec<u8>> { pub fn process_pbs(user: &str, music: &Node) -> Result<Node> {
let url = dynfmt::SimpleCurlyFormat.format(TACHI_PBS_URL.as_str(), [user])?; let url = dynfmt::SimpleCurlyFormat.format(TACHI_PBS_URL.as_str(), [user])?;
let response: serde_json::Value = helpers::request_tachi("GET", url, None::<()>)?; let response: serde_json::Value = helpers::request_tachi("GET", url, None::<()>)?;
let body = response["body"].as_object().ok_or(anyhow::anyhow!( let body = response["body"].as_object().ok_or(anyhow::anyhow!(
@ -120,11 +120,7 @@ pub fn process_pbs(user: &str, music: &Node, encoding: EncodingType) -> Result<V
} }
let response = build_response_base(scores.to_properties()); let response = build_response_base(scores.to_properties());
let bytes = kbinxml::to_binary_with_options(
Options::new(CompressionType::Uncompressed, encoding),
&response,
)?;
info!("Successfully injected Tachi PBs as Cloud scores"); info!("Successfully injected Tachi PBs as Cloud scores");
Ok(bytes) Ok(response)
} }

View File

@ -3,7 +3,7 @@ use std::sync::RwLock;
use anyhow::Result; use anyhow::Result;
use bytes::Bytes; use bytes::Bytes;
use kbinxml::{CompressionType, Node, Options, Value}; use kbinxml::{CompressionType, EncodingType, Node, Options, Value};
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use crate::handlers::save::process_save; use crate::handlers::save::process_save;
@ -132,14 +132,32 @@ pub unsafe fn property_mem_read_hook(
} }
} }
fn build_response(
original_signature: &[u8],
response: Node,
encoding: EncodingType,
) -> Result<Vec<u8>> {
if kbinxml::is_binary_xml(original_signature) {
let bytes = kbinxml::to_binary_with_options(
Options::new(CompressionType::from_byte(original_signature[1])?, encoding),
&response,
)?;
Ok(bytes)
} else {
let bytes = kbinxml::to_text_xml(&response)?;
Ok(bytes)
}
}
#[allow(clippy::manual_map)] #[allow(clippy::manual_map)]
pub unsafe fn property_mem_read_hook_wrapped( pub unsafe fn property_mem_read_hook_wrapped(
response: Vec<u8>, original: Vec<u8>,
load: bool, load: bool,
load_m: bool, load_m: bool,
common: bool, common: bool,
) -> Option<Result<Vec<u8>>> { ) -> Option<Result<Vec<u8>>> {
let (mut root, encoding) = kbinxml::from_bytes(Bytes::from(response)) let original_signature = original[..2].to_vec();
let (mut root, encoding) = kbinxml::from_bytes(Bytes::from(original))
.and_then(|(node, encoding)| node.as_node().map(|node| (node, encoding))) .and_then(|(node, encoding)| node.as_node().map(|node| (node, encoding)))
.ok()?; .ok()?;
@ -170,10 +188,7 @@ pub unsafe fn property_mem_read_hook_wrapped(
Value::String("CLOUD_LINK_ENABLE".to_string()), Value::String("CLOUD_LINK_ENABLE".to_string()),
)], )],
)); ));
let response = kbinxml::to_binary_with_options( let response = build_response(&original_signature, root, encoding)?;
Options::new(CompressionType::Uncompressed, encoding),
&root,
)?;
COMMON.store(false, Ordering::Relaxed); COMMON.store(false, Ordering::Relaxed);
Ok(response) Ok(response)
@ -194,10 +209,7 @@ pub unsafe fn property_mem_read_hook_wrapped(
"cloud", "cloud",
vec![Node::with_value("relation", Value::S8(1))], vec![Node::with_value("relation", Value::S8(1))],
)); ));
let response = kbinxml::to_binary_with_options( let response = build_response(&original_signature, root, encoding)?;
Options::new(CompressionType::Uncompressed, encoding),
&root,
)?;
LOAD.store(false, Ordering::Relaxed); LOAD.store(false, Ordering::Relaxed);
Ok(response) Ok(response)
@ -205,7 +217,8 @@ pub unsafe fn property_mem_read_hook_wrapped(
} else if let Some(music) = load_m.then(|| root.pointer(&["game", "music"])).flatten() { } else if let Some(music) = load_m.then(|| root.pointer(&["game", "music"])).flatten() {
Some((|| { Some((|| {
let user = USER.load(Ordering::SeqCst).to_string(); let user = USER.load(Ordering::SeqCst).to_string();
let response = crate::cloudlink::process_pbs(user.as_str(), music, encoding)?; let response = crate::cloudlink::process_pbs(user.as_str(), music)?;
let response = build_response(&original_signature, response, encoding)?;
LOAD_M.store(false, Ordering::Relaxed); LOAD_M.store(false, Ordering::Relaxed);
Ok(response) Ok(response)