From 2e639fbcee794c869f60aceb0090adfecfd381ef Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Sat, 27 Jan 2024 01:05:49 +0100 Subject: [PATCH] fix code padding --- androscalpel_serializer/src/items/code.rs | 747 +++++++++++++++++++++- 1 file changed, 743 insertions(+), 4 deletions(-) diff --git a/androscalpel_serializer/src/items/code.rs b/androscalpel_serializer/src/items/code.rs index 0ecc398..8608561 100644 --- a/androscalpel_serializer/src/items/code.rs +++ b/androscalpel_serializer/src/items/code.rs @@ -152,16 +152,25 @@ 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)?; + let insns_size = self.insns.iter().map(|i| i.size() as u32).sum::() / 2; + insns_size.serialize(output)?; for insn in &self.insns { insn.serialize(output)?; } - if !self.tries.is_empty() && self.insns.len() % 2 == 1 { + if !self.tries.is_empty() && insns_size % 2 == 1 { + println!("padding"); 0u16.serialize(output)?; } for item in &self.tries { item.serialize(output)?; } + let mut tries = vec![]; + for item in &self.tries { + for c in item.serialize_to_vec().unwrap().into_iter() { + tries.push(c); + } + } + println!("tries: {tries:02x?}"); if let Some(ref handlers) = self.handlers { handlers.serialize(output)?; } @@ -200,6 +209,18 @@ impl Serializable for CodeItem { insns.push(ins); } if serialized_insns_size != insns_size { + println!( + "{:#?}", + Self { + registers_size, + ins_size, + outs_size, + debug_info_off, + insns, + tries: vec![], + handlers: None, + } + ); return Err(Error::DeserializationError(format!( "Failed to deserialize instructions, expected size of {insns_size} code \ units (16 bits), found at least {serialized_insns_size}" @@ -228,14 +249,15 @@ impl Serializable for CodeItem { }) } fn size(&self) -> usize { + let insns_size = self.insns.iter().map(|i| i.size() as u32).sum::() / 2; self.registers_size.size() + self.ins_size.size() + self.outs_size.size() + self.tries_size_field().size() + self.debug_info_off.size() - + 0u32.size() + + insns_size.size() + self.insns.iter().map(|val| val.size()).sum::() - + if !self.tries.is_empty() && self.insns.len() % 2 == 1 { + + if !self.tries.is_empty() && insns_size % 2 == 1 { 2 } else { 0 @@ -1217,4 +1239,721 @@ mod test { assert_eq!(code, CodeItem::deserialize_from_slice(&raw).unwrap()); assert_eq!(code.size(), raw.len()); } + + #[test] + fn test_code_with_handler() { + let code = CodeItem { + registers_size: 6, + ins_size: 0, + outs_size: 1, + debug_info_off: 27, + insns: vec![ + Format35C { + a: 0, + vg: 0, + op: 113, + b: 4, + vf: 0, + ve: 0, + vd: 0, + vc: 0, + }, + Format11X { va: 0, op: 12 }, + Format12X { + vb: 0, + va: 0, + op: 33, + }, + Format22C { + vb: 0, + va: 0, + op: 35, + c: 27, + }, + Format21C { + va: 0, + op: 105, + b: 10, + }, + Format11N { + b: 1, + va: 1, + op: 18, + }, + Format21C { + va: 2, + op: 98, + b: 11, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 3, + vf: 0, + ve: 0, + vd: 0, + vc: 2, + }, + Format11X { va: 2, op: 10 }, + Format23X { + va: 1, + op: 75, + vc: 2, + vb: 0, + }, + Format11N { + b: 2, + va: 0, + op: 18, + }, + Format21C { + va: 2, + op: 98, + b: 10, + }, + Format21C { + va: 3, + op: 98, + b: 14, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 3, + vf: 0, + ve: 0, + vd: 0, + vc: 3, + }, + Format11X { va: 3, op: 10 }, + Format23X { + va: 0, + op: 75, + vc: 3, + vb: 2, + }, + Format11N { + b: 3, + va: 2, + op: 18, + }, + Format21C { + va: 3, + op: 98, + b: 10, + }, + Format21C { + va: 4, + op: 98, + b: 13, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 3, + vf: 0, + ve: 0, + vd: 0, + vc: 4, + }, + Format11X { va: 4, op: 10 }, + Format23X { + va: 2, + op: 75, + vc: 4, + vb: 3, + }, + Format11N { + b: 4, + va: 3, + op: 18, + }, + Format21C { + va: 4, + op: 98, + b: 10, + }, + Format21C { + va: 5, + op: 98, + b: 12, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 3, + vf: 0, + ve: 0, + vd: 0, + vc: 5, + }, + Format11X { va: 5, op: 10 }, + Format23X { + va: 3, + op: 75, + vc: 5, + vb: 4, + }, + Format35C { + a: 0, + vg: 0, + op: 113, + b: 1, + vf: 0, + ve: 0, + vd: 0, + vc: 0, + }, + Format11X { va: 4, op: 12 }, + Format12X { + vb: 4, + va: 4, + op: 33, + }, + Format22C { + vb: 4, + va: 4, + op: 35, + c: 27, + }, + Format21C { + va: 4, + op: 105, + b: 9, + }, + Format21C { + va: 5, + op: 98, + b: 5, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 5, + }, + Format11X { va: 5, op: 10 }, + Format23X { + va: 1, + op: 75, + vc: 5, + vb: 4, + }, + Format21C { + va: 1, + op: 98, + b: 9, + }, + Format21C { + va: 4, + op: 98, + b: 8, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 4, + }, + Format11X { va: 4, op: 10 }, + Format23X { + va: 0, + op: 75, + vc: 4, + vb: 1, + }, + Format21C { + va: 0, + op: 98, + b: 9, + }, + Format21C { + va: 1, + op: 98, + b: 7, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 1, + }, + Format11X { va: 1, op: 10 }, + Format23X { + va: 2, + op: 75, + vc: 1, + vb: 0, + }, + Format21C { + va: 0, + op: 98, + b: 9, + }, + Format21C { + va: 1, + op: 98, + b: 1, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 1, + }, + Format11X { va: 1, op: 10 }, + Format23X { + va: 3, + op: 75, + vc: 1, + vb: 0, + }, + Format21C { + va: 0, + op: 98, + b: 9, + }, + Format21C { + va: 1, + op: 98, + b: 0, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 1, + }, + Format11X { va: 1, op: 10 }, + Format11N { + b: 5, + va: 2, + op: 18, + }, + Format23X { + va: 2, + op: 75, + vc: 1, + vb: 0, + }, + Format21C { + va: 0, + op: 98, + b: 9, + }, + Format21C { + va: 1, + op: 98, + b: 2, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 1, + }, + Format11X { va: 1, op: 10 }, + Format11N { + b: 6, + va: 2, + op: 18, + }, + Format23X { + va: 2, + op: 75, + vc: 1, + vb: 0, + }, + Format21C { + va: 0, + op: 98, + b: 9, + }, + Format21C { + va: 1, + op: 98, + b: 3, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 1, + }, + Format11X { va: 1, op: 10 }, + Format11N { + b: 7, + va: 2, + op: 18, + }, + Format23X { + va: 2, + op: 75, + vc: 1, + vb: 0, + }, + Format21C { + va: 0, + op: 98, + b: 9, + }, + Format21C { + va: 1, + op: 98, + b: 4, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 1, + }, + Format11X { va: 1, op: 10 }, + Format21S { + va: 2, + op: 19, + b: 8, + }, + Format23X { + va: 2, + op: 75, + vc: 1, + vb: 0, + }, + Format21C { + va: 0, + op: 98, + b: 9, + }, + Format21C { + va: 1, + op: 98, + b: 6, + }, + Format35C { + a: 1, + vg: 0, + op: 110, + b: 0, + vf: 0, + ve: 0, + vd: 0, + vc: 1, + }, + Format11X { va: 1, op: 10 }, + Format21S { + va: 2, + op: 19, + b: 9, + }, + Format23X { + va: 2, + op: 75, + vc: 1, + vb: 0, + }, + Format10X { op: 14 }, + ], + tries: vec![ + TryItem { + start_addr: 10, + insn_count: 8, + handler_off: 1, + }, + TryItem { + start_addr: 19, + insn_count: 10, + handler_off: 4, + }, + TryItem { + start_addr: 30, + insn_count: 10, + handler_off: 7, + }, + TryItem { + start_addr: 41, + insn_count: 10, + handler_off: 10, + }, + TryItem { + start_addr: 60, + insn_count: 8, + handler_off: 13, + }, + TryItem { + start_addr: 68, + insn_count: 10, + handler_off: 16, + }, + TryItem { + start_addr: 78, + insn_count: 10, + handler_off: 19, + }, + TryItem { + start_addr: 88, + insn_count: 10, + handler_off: 22, + }, + TryItem { + start_addr: 98, + insn_count: 11, + handler_off: 25, + }, + TryItem { + start_addr: 109, + insn_count: 11, + handler_off: 28, + }, + TryItem { + start_addr: 120, + insn_count: 11, + handler_off: 31, + }, + TryItem { + start_addr: 131, + insn_count: 12, + handler_off: 35, + }, + TryItem { + start_addr: 143, + insn_count: 12, + handler_off: 39, + }, + ], + handlers: Some(EncodedCatchHandlerList { + list: vec![ + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(18), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(29), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(40), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(51), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(68), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(78), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(88), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(98), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(109), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(120), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(131), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(143), + }], + catch_all_addr: None, + }, + EncodedCatchHandler { + handlers: vec![EncodedTypeAddrPair { + type_idx: Uleb128(19), + addr: Uleb128(155), + }], + catch_all_addr: None, + }, + ], + }), + }; + let raw = vec![ + 0x06, 0x00, // registers_size + 0x00, 0x00, // ins_size + 0x01, 0x00, // outs_size + 0x0d, 0x00, // tries_size + 0x1b, 0x00, 0x00, 0x00, // debug_info_off + 0x9c, 0x00, 0x00, 0x00, // insns_size + 0x71, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x21, 0x00, 0x23, 0x00, 0x1b, 0x00, + 0x69, 0x00, 0x0a, 0x00, 0x12, 0x11, 0x62, 0x02, 0x0b, 0x00, 0x6e, 0x10, 0x03, 0x00, + 0x02, 0x00, 0x0a, 0x02, 0x4b, 0x01, 0x00, 0x02, 0x12, 0x20, 0x62, 0x02, 0x0a, 0x00, + 0x62, 0x03, 0x0e, 0x00, 0x6e, 0x10, 0x03, 0x00, 0x03, 0x00, 0x0a, 0x03, 0x4b, 0x00, + 0x02, 0x03, 0x12, 0x32, 0x62, 0x03, 0x0a, 0x00, 0x62, 0x04, 0x0d, 0x00, 0x6e, 0x10, + 0x03, 0x00, 0x04, 0x00, 0x0a, 0x04, 0x4b, 0x02, 0x03, 0x04, 0x12, 0x43, 0x62, 0x04, + 0x0a, 0x00, 0x62, 0x05, 0x0c, 0x00, 0x6e, 0x10, 0x03, 0x00, 0x05, 0x00, 0x0a, 0x05, + 0x4b, 0x03, 0x04, 0x05, 0x71, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x04, 0x21, 0x44, + 0x23, 0x44, 0x1b, 0x00, 0x69, 0x04, 0x09, 0x00, 0x62, 0x05, 0x05, 0x00, 0x6e, 0x10, + 0x00, 0x00, 0x05, 0x00, 0x0a, 0x05, 0x4b, 0x01, 0x04, 0x05, 0x62, 0x01, 0x09, 0x00, + 0x62, 0x04, 0x08, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x04, 0x4b, 0x00, + 0x01, 0x04, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x07, 0x00, 0x6e, 0x10, 0x00, 0x00, + 0x01, 0x00, 0x0a, 0x01, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, + 0x01, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x4b, 0x03, 0x00, 0x01, + 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x00, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, + 0x0a, 0x01, 0x12, 0x52, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, + 0x02, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x12, 0x62, 0x4b, 0x02, + 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x03, 0x00, 0x6e, 0x10, 0x00, 0x00, + 0x01, 0x00, 0x0a, 0x01, 0x12, 0x72, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, + 0x62, 0x01, 0x04, 0x00, 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x13, 0x02, + 0x08, 0x00, 0x4b, 0x02, 0x00, 0x01, 0x62, 0x00, 0x09, 0x00, 0x62, 0x01, 0x06, 0x00, + 0x6e, 0x10, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x01, 0x13, 0x02, 0x09, 0x00, 0x4b, 0x02, + 0x00, 0x01, 0x0e, 0x00, // insns + // no padding: insns_size % 2 == 0 + //try_item 0x00 + 0x0a, 0x00, 0x00, 0x00, // start_addr + 0x08, 0x00, // insn_count + 0x01, 0x00, // handler_off + //try_item 0x01 + 0x13, 0x00, 0x00, 0x00, // start_addr + 0x0a, 0x00, // insn_count + 0x04, 0x00, // handler_off + //try_item 0x02 + 0x1e, 0x00, 0x00, 0x00, // start_addr + 0x0a, 0x00, // insn_count + 0x07, 0x00, // handler_off + //try_item 0x03 + 0x29, 0x00, 0x00, 0x00, // start_addr + 0x0a, 0x00, // insn_count + 0x0a, 0x00, // handler_off + //try_item 0x04 + 0x3c, 0x00, 0x00, 0x00, // start_addr + 0x08, 0x00, // insn_count + 0x0d, 0x00, // handler_off + //try_item 0x05 + 0x44, 0x00, 0x00, 0x00, // start_addr + 0x0a, 0x00, // insn_count + 0x10, 0x00, // handler_off + //try_item 0x06 + 0x4e, 0x00, 0x00, 0x00, // start_addr + 0x0a, 0x00, // insn_count + 0x13, 0x00, // handler_off + //try_item 0x07 + 0x58, 0x00, 0x00, 0x00, // start_addr + 0x0a, 0x00, // insn_count + 0x16, 0x00, // handler_off + //try_item 0x08 + 0x62, 0x00, 0x00, 0x00, // start_addr + 0x0b, 0x00, // insn_count + 0x19, 0x00, // handler_off + //try_item 0x09 + 0x6d, 0x00, 0x00, 0x00, // start_addr + 0x0b, 0x00, // insn_count + 0x1c, 0x00, // handler_off + //try_item 0x0a + 0x78, 0x00, 0x00, 0x00, // start_addr + 0x0b, 0x00, // insn_count + 0x1f, 0x00, // handler_off + //try_item 0x0b + 0x83, 0x00, 0x00, 0x00, // start_addr + 0x0c, 0x00, // insn_count + 0x23, 0x00, // handler_off + //try_item 0x0c + 0x8f, 0x00, 0x00, 0x00, // start_addr + 0x0c, 0x00, // insn_count + 0x27, 0x00, // handler_off + // encoded_catch_handler_list + 0x0d, // size + 0x01, 0x13, 0x12, // encoded_catch_handler 0x00 + 0x01, 0x13, 0x1d, // encoded_catch_handler 0x01 + 0x01, 0x13, 0x28, // encoded_catch_handler 0x02 + 0x01, 0x13, 0x33, // encoded_catch_handler 0x03 + 0x01, 0x13, 0x44, // encoded_catch_handler 0x04 + 0x01, 0x13, 0x4e, // encoded_catch_handler 0x05 + 0x01, 0x13, 0x58, // encoded_catch_handler 0x06 + 0x01, 0x13, 0x62, // encoded_catch_handler 0x07 + 0x01, 0x13, 0x6d, // encoded_catch_handler 0x08 + 0x01, 0x13, 0x78, // encoded_catch_handler 0x09 + 0x01, 0x13, 0x83, 0x01, // encoded_catch_handler 0x0a + 0x01, 0x13, 0x8f, 0x01, // encoded_catch_handler 0x0b + 0x01, 0x13, 0x9b, 0x01, // encoded_catch_handler 0x0c + ]; + assert_eq!(raw, code.serialize_to_vec().unwrap()); + assert_eq!(code, CodeItem::deserialize_from_slice(&raw).unwrap()); + assert_eq!(code.size(), raw.len()); + } }