From c46faa1b18ad2bd553e85b07ecad9e621f3f4396 Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Thu, 25 Jan 2024 15:51:25 +0100 Subject: [PATCH] fix code serialization --- androscalpel_serializer/src/items/code.rs | 116 ++++++++++++++++++++-- 1 file changed, 110 insertions(+), 6 deletions(-) diff --git a/androscalpel_serializer/src/items/code.rs b/androscalpel_serializer/src/items/code.rs index 3e9ffae..763a11f 100644 --- a/androscalpel_serializer/src/items/code.rs +++ b/androscalpel_serializer/src/items/code.rs @@ -152,6 +152,7 @@ impl Serializable for CodeItem { self.outs_size.serialize(output)?; self.tries_size_field().serialize(output)?; self.debug_info_off.serialize(output)?; + (self.insns.iter().map(|i| i.size() as u32).sum::() / 2).serialize(output)?; for insn in &self.insns { insn.serialize(output)?; } @@ -179,6 +180,18 @@ impl Serializable for CodeItem { let mut serialized_insns_size = 0; while serialized_insns_size < insns_size { let ins = Instruction::deserialize(input).map_err(|err| { + println!( + "{:#?}", + Self { + registers_size, + ins_size, + outs_size, + debug_info_off, + insns: insns.clone(), + tries: vec![], + handlers: None + } + ); Error::DeserializationError(format!( "Failed to deserialize instruction at 0x{serialized_insns_size:x}: {err}" )) @@ -401,6 +414,7 @@ pub struct EncodedTypeAddrPair { #[cfg(test)] mod test { use super::*; + use crate::instructions::Instruction::*; const CODE_ITEM_RAW_1: &[u8] = &[ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x3d, 0x25, 0x4f, 0x00, 0x15, 0x00, 0x00, @@ -465,6 +479,21 @@ mod test { 0x02, 0xd9, 0x09, 0x87, 0x02, 0x01, 0xc7, 0x08, 0xee, 0x01, ]; + fn insns_from_bin(raw: &[u16]) -> Vec { + let mut insns = vec![]; + let raw: Vec = raw + .iter() + .map(|w| w.to_le_bytes().into_iter()) + .flatten() + .collect(); + let len = raw.len() as u64; + let mut buffer = std::io::Cursor::new(raw); + while buffer.position() < len { + insns.push(Instruction::deserialize(&mut buffer).unwrap()); + } + insns + } + #[test] fn test_deserialize_code_item() { assert_eq!( @@ -474,10 +503,10 @@ mod test { ins_size: 1, outs_size: 2, debug_info_off: 5186877, - insns: vec![ + insns: insns_from_bin(&[ 0x3054, 0x16c, 0x1071, 0xcb1, 0x0, 0xe28, 0xd, 0x106e, 0x8526, 0x0, 0x10c, 0x21a, 0x15cb, 0x2071, 0x5e3, 0x21, 0x10a, 0x138, 0x3, 0xe, 0x27 - ], + ]), tries: vec![TryItem { start_addr: 0, insn_count: 5, @@ -501,7 +530,7 @@ mod test { ins_size: 4, outs_size: 3, debug_info_off: 5187799, - insns: vec![ + insns: insns_from_bin(&[ 0x1070, 0x848b, 0x0005, 0x0022, 0x242d, 0x1070, 0x8751, 0x0000, 0x505b, 0x0654, 0x575b, 0x0658, 0x0022, 0x0584, 0x1070, 0x1c09, 0x0000, 0x505b, 0x0656, 0x7754, 0x09cc, 0x2071, 0x18ed, 0x0076, 0x070c, 0x575b, 0x0655, 0x1071, 0x17b9, 0x0006, @@ -531,7 +560,7 @@ mod test { 0x1884, 0x0067, 0x0727, 0x060d, 0x0722, 0x051e, 0x2070, 0x1ac2, 0x0067, 0x0727, 0x060d, 0x0722, 0x051e, 0x1071, 0x48ff, 0x0006, 0x060c, 0x2070, 0x1ac2, 0x0067, 0x0727, - ], + ]), tries: vec![ TryItem { start_addr: 33, @@ -1109,6 +1138,81 @@ mod test { 0x20, 0xc2, 0x1a, 0x67, 0x00, 0x27, 0x07, ]; - //#[test] - //fn test_insn_parsing() {} + #[test] + fn test_code() { + let code = CodeItem { + registers_size: 3, + ins_size: 1, + outs_size: 2, + debug_info_off: 1205, + insns: vec![ + Format35C { + a: 1, + vg: 0, + op: 112, + b: 2, + vf: 0, + ve: 0, + vd: 0, + vc: 2, + }, + Format21C { + va: 0, + op: 34, + b: 2, + }, + Format35C { + a: 1, + vg: 0, + op: 112, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 0, + }, + Format22C { + vb: 2, + va: 0, + op: 91, + c: 1, + }, + Format21C { + va: 1, + op: 26, + b: 18, + }, + Format35C { + a: 2, + vg: 0, + op: 110, + b: 1, + vf: 0, + ve: 0, + vd: 1, + vc: 0, + }, + Format10X { op: 14 }, + ], + tries: vec![], + handlers: None, + }; + let raw = vec![ + 0x03, 0x00, // registers_size + 0x01, 0x00, // ins_size + 0x02, 0x00, // outs_size + 0x00, 0x00, // tries_size + 0xb5, 0x04, 0x00, 0x00, // debug_info_off + 0x10, 0x00, 0x00, 0x00, // insns_size + 0x70, 0x10, 0x02, 0x00, 0x02, 0x00, // Format35C + 0x22, 0x00, 0x02, 0x00, // Format21C + 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, // Format35C + 0x5b, 0x20, 0x01, 0x00, // Format22C + 0x1a, 0x01, 0x12, 0x00, // Format21C + 0x6e, 0x20, 0x01, 0x00, 0x10, 0x00, // Format35C + 0x0e, 0x00, // Format10X + ]; + assert_eq!(code.serialize_to_vec().unwrap(), raw); + assert_eq!(code, CodeItem::deserialize_from_slice(&raw).unwrap()); + } }