1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-04-22 15:27:44 +00:00

Parse the encryption initialization packet

This commit is contained in:
Joshua Goins 2025-03-08 14:38:31 -05:00
parent 1ef412b420
commit 0ec0ed34ec
3 changed files with 55 additions and 12 deletions

View file

@ -17,12 +17,11 @@ async fn main() {
tokio::spawn(async move {
let mut buf = [0; 2056];
loop {
let n = read
.read(&mut buf)
.await
.expect("Failed to read data!");
let n = read.read(&mut buf).await.expect("Failed to read data!");
parse_packet(&buf[..n]);
if n != 0 {
parse_packet(&buf[..n]);
}
}
});
}

View file

@ -3,8 +3,8 @@ use rand::Rng;
use rand::distributions::Alphanumeric;
pub mod config;
pub mod patchlist;
pub mod packet;
pub mod patchlist;
pub fn generate_sid() -> String {
let random_id: String = rand::thread_rng()

View file

@ -1,6 +1,6 @@
use std::{fs::write, io::Cursor};
use binrw::{binrw, BinRead};
use binrw::{BinRead, binrw, helpers::until_eof};
pub(crate) fn read_bool_from<T: std::convert::From<u8> + std::cmp::PartialEq>(x: T) -> bool {
x == T::from(1u8)
@ -10,6 +10,11 @@ pub(crate) fn write_bool_as<T: std::convert::From<u8>>(x: &bool) -> T {
if *x { T::from(1u8) } else { T::from(0u8) }
}
pub(crate) fn read_string(byte_stream: Vec<u8>) -> String {
let str = String::from_utf8(byte_stream).unwrap();
str.trim_matches(char::from(0)).to_string() // trim \0 from the end of strings
}
#[binrw]
#[brw(repr = u16)]
#[derive(Debug)]
@ -17,6 +22,22 @@ enum ConnectionType {
Lobby = 0x3,
}
#[binrw]
#[derive(Debug)]
enum SegmentType {
#[brw(magic = 0x9u32)]
InitializeEncryption {
#[br(pad_before = 36)] // empty
#[br(count = 64)]
#[br(map = read_string)]
#[bw(ignore)]
phrase: String,
#[br(pad_after = 512)] // empty
key: u32,
},
}
#[binrw]
#[derive(Debug)]
struct PacketHeader {
@ -25,12 +46,30 @@ struct PacketHeader {
timestamp: u64,
size: u32,
connection_type: ConnectionType,
count: u16,
segment_count: u16,
unk3: u8,
#[br(map = read_bool_from::<u8>)]
#[bw(map = write_bool_as::<u8>)]
compressed: bool,
unk4: u32,
unk4: u16,
unk5: u32, // iolite says the size after oodle decompression
}
#[binrw]
#[derive(Debug)]
struct PacketSegment {
size: u32,
source_actor: u32,
target_actor: u32,
segment_type: SegmentType,
}
#[binrw]
#[derive(Debug)]
struct Packet {
header: PacketHeader,
#[br(count = header.segment_count)]
segments: Vec<PacketSegment>,
}
fn dump(msg: &str, data: &[u8]) {
@ -41,12 +80,17 @@ fn dump(msg: &str, data: &[u8]) {
pub fn parse_packet(data: &[u8]) {
let mut cursor = Cursor::new(data);
if let Ok(packet) = PacketHeader::read_le(&mut cursor) {
if let Ok(packet) = Packet::read_le(&mut cursor) {
println!("{:#?}", packet);
if packet.size as usize != data.len() {
dump("Packet size mismatch between what we're given and the header!", data);
if packet.header.size as usize != data.len() {
dump(
"Packet size mismatch between what we're given and the header!",
data,
);
}
dump("nothing", data);
} else {
dump("Failed to parse packet!", data);
}