From d7c82e5b18479d2aa684ca6ba650e020a4ed0ef5 Mon Sep 17 00:00:00 2001 From: Matt Bilker Date: Fri, 1 Jun 2018 13:47:56 +0000 Subject: [PATCH] Decoding now fully implemented --- src/bin/kbinxml.rs | 2 +- src/lib.rs | 84 ++++++++++++++++++++++++---------------------- src/node_types.rs | 11 +++--- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/src/bin/kbinxml.rs b/src/bin/kbinxml.rs index 49edee6..2a55969 100644 --- a/src/bin/kbinxml.rs +++ b/src/bin/kbinxml.rs @@ -13,7 +13,7 @@ fn main() -> std::io::Result<()> { pretty_env_logger::init(); if let Some(file_name) = env::args().skip(1).next() { - println!("file_name: {}", file_name); + eprintln!("file_name: {}", file_name); let mut file = File::open(file_name)?; let mut contents = Vec::new(); diff --git a/src/lib.rs b/src/lib.rs index b014c66..86031cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,10 +53,10 @@ impl KbinXml { } fn data_buf_read(&mut self, data_buf: &mut Cursor<&[u8]>) -> Vec { - let size = data_buf.read_i32::().expect("Unable to read data size"); + let size = data_buf.read_u32::().expect("Unable to read data size"); let mut data = vec![0; size as usize]; data_buf.read_exact(&mut data).expect("Unable to read data"); - println!("data_buf_read => size: {}, data: 0x{:02x?}", data.len(), data); + trace!("data_buf_read => size: {}, data: 0x{:02x?}", data.len(), data); self.data_buf_realign(data_buf, None); @@ -72,9 +72,8 @@ impl KbinXml { index -= 1; } data.truncate(index + 1); - println!("data_buf_read_str => size: {}, data: 0x{:02x?}", data.len(), data); + trace!("data_buf_read_str => size: {}, data: 0x{:02x?}", data.len(), data); - //String::from_utf8(data).expect("Unable to interpret string node as UTF-8") encoding.decode_bytes(data) } @@ -95,7 +94,7 @@ impl KbinXml { let old_pos = self.data_buf_offset(data_buf); let size = data_type.size() * data_type.count(); - println!("data_buf_get_aligned => old_pos: {}, size: {}", old_pos, size); + trace!("data_buf_get_aligned => old_pos: {}, size: {}", old_pos, size); let (check_old, data) = match size { 1 => { data_buf.seek(SeekFrom::Start(self.offset_1)).expect("Unable to seek data buffer"); @@ -128,7 +127,7 @@ impl KbinXml { data_buf.seek(SeekFrom::Start(old_pos)).expect("Unable to seek data buffer"); let trailing = max(self.offset_1, self.offset_2); - println!("old_pos: {}, trailing: {}", old_pos, trailing); + trace!("data_buf_get_aligned => old_pos: {}, trailing: {}", old_pos, trailing); if old_pos < trailing { data_buf.seek(SeekFrom::Start(trailing)).expect("Unable to seek data buffer"); self.data_buf_realign(data_buf, None); @@ -140,12 +139,12 @@ impl KbinXml { fn data_buf_realign(&mut self, data_buf: &mut Cursor<&[u8]>, size: Option) { let size = size.unwrap_or(4); - println!("data_buf_realign => position: {}, size: {}", data_buf.position(), size); + trace!("data_buf_realign => position: {}, size: {}", data_buf.position(), size); while data_buf.position() % size > 0 { data_buf.seek(SeekFrom::Current(1)).expect("Unable to seek data buffer"); } - println!("data_buf_realign => realigned to: {}", data_buf.position()); + trace!("data_buf_realign => realigned to: {}", data_buf.position()); } fn from_binary_internal(&mut self, input: &[u8]) -> Element { @@ -163,17 +162,16 @@ impl KbinXml { let compressed = Compression::from_byte(compress_byte).expect("Unknown compression value"); let encoding_byte = node_buf.read_u8().expect("Unable to read encoding byte"); - let encoding = EncodingType::from_byte(encoding_byte).expect("Unknown encoding"); - let encoding_negation = node_buf.read_u8().expect("Unable to read encoding negation byte"); + let encoding = EncodingType::from_byte(encoding_byte).expect("Unknown encoding"); assert_eq!(encoding_negation, 0xFF ^ encoding_byte); - println!("signature: 0x{:x}", signature); - println!("compression: 0x{:x} ({:?})", compress_byte, compressed); - println!("encoding: 0x{:x} ({:?})", encoding_byte, encoding); + info!("signature: 0x{:x}", signature); + info!("compression: 0x{:x} ({:?})", compress_byte, compressed); + info!("encoding: 0x{:x} ({:?})", encoding_byte, encoding); let len_node = node_buf.read_u32::().expect("Unable to read len_node"); - println!("len_node: {} (0x{:x})", len_node, len_node); + info!("len_node: {} (0x{:x})", len_node, len_node); // We have read 8 bytes so far, so offset the start of the data buffer from // our current position. @@ -184,11 +182,11 @@ impl KbinXml { let pos = data_buf.position(); self.offset_1 = pos; self.offset_2 = pos; - println!("offset_1: {}, offset_2: {}", self.offset_1, self.offset_2); + trace!("offset_1: {}, offset_2: {}", self.offset_1, self.offset_2); } let len_data = data_buf.read_u32::().expect("Unable to read len_data"); - println!("len_data: {} (0x{:x})", len_data, len_data); + info!("len_data: {} (0x{:x})", len_data, len_data); let mut stack: Vec = Vec::new(); { @@ -199,31 +197,28 @@ impl KbinXml { let node_type = raw_node_type & !64; let xml_type = KbinType::from_u8(node_type); - println!("raw_node_type: {}, node_type: {:?} ({}), is_array: {}", raw_node_type, xml_type, node_type, is_array); + debug!("raw_node_type: {}, node_type: {:?} ({}), is_array: {}", raw_node_type, xml_type, node_type, is_array); match xml_type { - KbinType::NodeEnd => { + KbinType::NodeEnd | KbinType::FileEnd => { if stack.len() > 1 { let node = stack.pop().expect("Stack must have last node"); if let Some(to) = stack.last_mut() { to.append_child(node); } } - continue; - }, - KbinType::FileEnd => { - if stack.len() > 1 { - let node = stack.pop().expect("Stack must have last node"); - if let Some(to) = stack.last_mut() { - to.append_child(node); - } + + if xml_type == KbinType::NodeEnd { + continue; + } else if xml_type == KbinType::FileEnd { + break; } - break; }, _ => {}, }; let name = unpack_sixbit(&mut node_buf); + if xml_type == KbinType::NodeStart { stack.push(Element::bare(name)); } else { @@ -234,16 +229,26 @@ impl KbinXml { match xml_type { KbinType::Attribute => { let val = self.data_buf_read_str(&mut data_buf, encoding); - println!("attr name: {}, val: {}", name, val); + debug!("attr name: {}, val: {}", name, val); to.set_attr(name, val); }, + // Removing null bytes is *so much* fun. + // + // Handle String nodes separately to use the string reading logic + // which automatically removes trailing null bytes. + KbinType::String => { + to.set_attr("__type", xml_type.name()); + + let val = self.data_buf_read_str(&mut data_buf, encoding); + debug!("name: {}, val: {}", name, val); + to.append_text_node(val); + }, _ => { to.set_attr("__type", xml_type.name()); let type_size = xml_type.size(); let type_count = xml_type.count(); - let (is_array, size) = if xml_type.count() == -1 { - println!("xml_type.count() == -1"); + let (is_array, size) = if type_count == -1 { (true, data_buf.read_u32::().expect("Unable to read binary/string byte length")) } else if is_array { let node_size = type_size * type_count; @@ -256,7 +261,7 @@ impl KbinXml { (false, 1) }; - println!("type: {:?}, type_size: {}, type_count: {}, is_array: {}, size: {}", + debug!("type: {:?}, type_size: {}, type_count: {}, is_array: {}, size: {}", xml_type, type_size, type_count, @@ -271,22 +276,21 @@ impl KbinXml { } else { self.data_buf_get_aligned(&mut data_buf, xml_type) }; - println!("data: 0x{:02x?}", data); - if xml_type == KbinType::String { - let val = encoding.decode_bytes(data); - println!("name: {}, string: {}", name, val); - to.append_text_node(val); - } else if xml_type == KbinType::Binary { + + debug!("data: 0x{:02x?}", data); + if xml_type == KbinType::Binary { + to.set_attr("__size", data.len()); + let len = data.len() * 2; let val = data.into_iter().fold(String::with_capacity(len), |mut val, x| { write!(val, "{:02x}", x).expect("Failed to append hex char"); val }); - println!("name: {}, string: {}", name, val); + debug!("name: {}, string: {}", name, val); to.append_text_node(val); } else { let inner_value = xml_type.parse_bytes(&data); - println!("name: {}, string: {}", name, inner_value); + debug!("name: {}, string: {}", name, inner_value); to.append_text_node(inner_value); } }, @@ -296,7 +300,7 @@ impl KbinXml { } } if stack.len() > 1 { - println!("stack: {:#?}", stack); + warn!("stack: {:#?}", stack); } stack.truncate(1); stack.pop().expect("Stack must have root node") diff --git a/src/node_types.rs b/src/node_types.rs index d97d838..65b73ae 100644 --- a/src/node_types.rs +++ b/src/node_types.rs @@ -9,7 +9,7 @@ macro_rules! number_impl { $( impl KbinWrapperType<$inner_type> for $inner_type { fn from_kbin_bytes(output: &mut String, input: &[u8]) { - println!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input); + trace!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input); let mut data = [0; ::std::mem::size_of::<$inner_type>()]; data.clone_from_slice(input); @@ -23,7 +23,7 @@ macro_rules! number_impl { $( impl KbinWrapperType<$inner_type> for $inner_type { fn from_kbin_bytes(output: &mut String, input: &[u8]) { - println!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input); + trace!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input); let mut data = [0; ::std::mem::size_of::<$inner_type>()]; data.clone_from_slice(input); @@ -42,8 +42,7 @@ number_impl!(float; u32 => f32, u64 => f64); impl KbinWrapperType for bool { fn from_kbin_bytes(output: &mut String, input: &[u8]) { - println!("KbinWrapperType => input: {:02x?}", input); - //String::from("bool") + trace!("KbinWrapperType => input: {:02x?}", input); let value = match input[0] { 0x00 => "0", @@ -57,7 +56,7 @@ impl KbinWrapperType for bool { struct Ip4; impl KbinWrapperType for Ip4 { fn from_kbin_bytes(output: &mut String, input: &[u8]) { - println!("KbinWrapperType => input: {:02x?}", input); + trace!("KbinWrapperType => input: {:02x?}", input); if input.len() < 4 { panic!("Ip4 type requires 4 bytes of data, input: {:02x?}", input); @@ -159,7 +158,7 @@ macro_rules! construct_types { { let type_size = (size as usize) * (count as usize); let arr_count = input.len() / type_size; - println!("parse_bytes({}) => size: {}, count: {}, input_len: {}, arr_count: {}", name, size, count, input.len(), arr_count); + debug!("parse_bytes({}) => size: {}, count: {}, input_len: {}, arr_count: {}", name, size, count, input.len(), arr_count); let mut result = String::new();