diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index 3278e20..fa85244 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -742,7 +742,7 @@ impl Apk { addr: usize, insns_ref: &HashMap, dex: &DexFileReader, - ) -> Result<(instructions::Instruction, HashMap)> { + ) -> Result)>> { use crate::instructions::*; use InsFormat::*; let mut labels = HashMap::new(); @@ -867,7 +867,7 @@ impl Apk { } else { bail!( "Found fill-array-data-payload v{va} +{b} at 0x{addr:x}, \ - no instruction found at {data_addr:x}" + no instruction found at 0x{data_addr:x}" ) } } @@ -881,11 +881,11 @@ impl Apk { } else { addr - (-a as usize) }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::Goto(Goto::new(label)) @@ -899,11 +899,11 @@ impl Apk { } else { addr - (-a as usize) }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::Goto(Goto::new(label)) @@ -917,11 +917,11 @@ impl Apk { } else { addr - (-a as usize) }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::Goto(Goto::new(label)) @@ -954,12 +954,12 @@ impl Apk { } else { addr - (-target as usize) }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? bail!( - "There is already a label at 0x{dest_addr:80X} with \ + "There is already a label at 0x{dest_addr:08X} with \ an invalid name" ); } @@ -1008,12 +1008,12 @@ impl Apk { } else { addr - (-target as usize) }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? bail!( - "There is already a label at 0x{dest_addr:80X} with \ + "There is already a label at 0x{dest_addr:08X} with \ an invalid name" ); } @@ -1079,13 +1079,13 @@ impl Apk { let dest_addr = if c > 0 { addr + c as usize } else { - addr - c as usize + addr - (-c) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfEq(IfEq::new(va, vb, label)?) @@ -1105,13 +1105,13 @@ impl Apk { let dest_addr = if c > 0 { addr + c as usize } else { - addr - c as usize + addr - (-c) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfNe(IfNe::new(va, vb, label)?) @@ -1131,13 +1131,13 @@ impl Apk { let dest_addr = if c > 0 { addr + c as usize } else { - addr - c as usize + addr - (-c) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfLt(IfLt::new(va, vb, label)?) @@ -1157,13 +1157,13 @@ impl Apk { let dest_addr = if c > 0 { addr + c as usize } else { - addr - c as usize + addr - (-c) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfGe(IfGe::new(va, vb, label)?) @@ -1183,13 +1183,13 @@ impl Apk { let dest_addr = if c > 0 { addr + c as usize } else { - addr - c as usize + addr - (-c) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfGt(IfGt::new(va, vb, label)?) @@ -1209,13 +1209,13 @@ impl Apk { let dest_addr = if c > 0 { addr + c as usize } else { - addr - c as usize + addr - (-c) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfLe(IfLe::new(va, vb, label)?) @@ -1230,13 +1230,13 @@ impl Apk { let dest_addr = if b > 0 { addr + b as usize } else { - addr - b as usize + addr - (-b) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfEqZ(IfEqZ::new(va, label)?) @@ -1251,13 +1251,13 @@ impl Apk { let dest_addr = if b > 0 { addr + b as usize } else { - addr - b as usize + addr - (-b) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfNeZ(IfNeZ::new(va, label)?) @@ -1272,13 +1272,13 @@ impl Apk { let dest_addr = if b > 0 { addr + b as usize } else { - addr - b as usize + addr - (-b) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfLtZ(IfLtZ::new(va, label)?) @@ -1293,13 +1293,13 @@ impl Apk { let dest_addr = if b > 0 { addr + b as usize } else { - addr - b as usize + addr - (-b) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfGeZ(IfGeZ::new(va, label)?) @@ -1314,13 +1314,13 @@ impl Apk { let dest_addr = if b > 0 { addr + b as usize } else { - addr - b as usize + addr - (-b) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfGtZ(IfGtZ::new(va, label)?) @@ -1335,13 +1335,13 @@ impl Apk { let dest_addr = if b > 0 { addr + b as usize } else { - addr - b as usize + addr - (-b) as usize }; - let label = format!("label_{dest_addr:80X}"); + let label = format!("label_{dest_addr:08X}"); if let Some(old_label) = labels.insert(dest_addr, label.clone()) { if old_label != label { // TODO: internal error, panic? - bail!("There is already a label at 0x{dest_addr:80X} with an invalid name"); + bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } Instruction::IfLeZ(IfLeZ::new(va, label)?) @@ -2154,12 +2154,15 @@ impl Apk { let proto = Self::get_id_method_type_from_idx(b as usize, dex)?; Instruction::ConstMethodType(ConstMethodType::new(va, proto)) } - FormatPackedSwitchPayload { .. } => bail!("{format:?} is a pseudo instruction"), - FormatSparseSwitchPayload { .. } => bail!("{format:?} is a pseudo instruction"), - FormatFillArrayDataPayload { .. } => bail!("{format:?} is a pseudo instruction"), + FormatPackedSwitchPayload { .. } => return Ok(None), + //bail!("{format:?} is a pseudo instruction"), + FormatSparseSwitchPayload { .. } => return Ok(None), + //bail!("{format:?} is a pseudo instruction"), + FormatFillArrayDataPayload { .. } => return Ok(None), + //bail!("{format:?} is a pseudo instruction"), _ => bail!("Unknwon instruction found at {addr}: {format:?}"), }; - Ok((ins, labels)) + Ok(Some((ins, labels))) } /// Return a [`Code`] from it's offset in the dex file. @@ -2192,10 +2195,11 @@ impl Apk { ))? .get_handler_at_offset(handler_off)?; let default_handler = if let Some(Uleb128(addr)) = *catch_all_addr { - let label = format!("label_{addr:80X}"); + let label = format!("label_{addr:08X}"); if let Some(label_) = labels.insert(addr as usize, label.clone()) { if label_ != label { - bail!("Label collision at 0x{addr:80X}: {label_} and {label}"); + // TODO: that's an internal error + bail!("Label collision at 0x{addr:08X}: {label_} and {label}"); } } Some(label) @@ -2208,20 +2212,27 @@ impl Apk { addr: Uleb128(addr), } in handlers.iter().cloned() { - let label = format!("label_{addr:80X}"); + let label = format!("label_{addr:08X}"); if let Some(label_) = labels.insert(addr as usize, label.clone()) { if label_ != label { - bail!("Label collision at 0x{addr:80X}: {label_} and {label}"); + // TODO: that's an internal error + bail!("Label collision at 0x{addr:08X}: {label_} and {label}"); } } handlers_.push((Self::get_id_type_from_idx(type_idx as usize, dex)?, label)) } let dest_addr = start_addr + insn_count as u32; - let end_label = format!("label_{dest_addr:80X}"); + let end_label = format!("label_{dest_addr:08X}"); + if let Some(label_) = labels.insert(dest_addr as usize, end_label.clone()) { + if label_ != end_label { + // TODO: that's an internal error + bail!("Label collision at 0x{dest_addr:08X}: {label_} and {end_label}"); + } + } let try_ = Instruction::Try(Try::new(end_label, handlers_, default_handler)); if let Some(try__) = tries.insert(start_addr as usize, try_.clone()) { bail!( - "Found two try blocks at the same address 0x{start_addr:80X}: \ + "Found two try blocks at the same address 0x{start_addr:08X}: \ {try__:?}, {try_:?}" ); } @@ -2231,24 +2242,26 @@ impl Apk { let mut addr = 0; for ins_f in &code_item.insns { instructions_raw.insert(addr, ins_f); - addr += ins_f.size(); + addr += ins_f.size() / 2; } let mut instructions = vec![]; addr = 0; for ins_f in &code_item.insns { - let (ins, ins_labels) = - Self::instruction_format_to_instruction(ins_f, addr, &instructions_raw, dex)?; - instructions.push((addr, ins)); - addr += ins_f.size() / 2; - for (key, val) in &ins_labels { - if let Some(val_) = ins_labels.get(key) { - if val_ != val { - // TODO: internal error, panic? - bail!("Label collision at 0x{key:80X}: {val_} and {val}"); + if let Some((ins, ins_labels)) = + Self::instruction_format_to_instruction(ins_f, addr, &instructions_raw, dex)? + { + instructions.push((addr, ins)); + addr += ins_f.size() / 2; + for (key, val) in &ins_labels { + if let Some(val_) = ins_labels.get(key) { + if val_ != val { + // TODO: internal error, panic? + bail!("Label collision at 0x{key:08X}: {val_} and {val}"); + } } } + labels.extend(ins_labels); } - labels.extend(ins_labels); } let mut insns = vec![]; for (addr, ins) in instructions { @@ -2260,6 +2273,20 @@ impl Apk { } insns.push(ins); } + // notice: addr is not the same as the one in the loop, this one is computed previously + // and is the addr after the last ins. + if let Some(try_) = tries.remove(&addr) { + insns.push(try_); + } + if let Some(label) = labels.remove(&addr) { + insns.push(Instruction::Label(Label::new(label))); + } + if !labels.is_empty() { + bail!("Could not put all label as instructions (label out of insns?)"); + } + if !tries.is_empty() { + bail!("Could not put all try block as instructions (addr not aligned with ins?)"); + } Ok(Code { registers_size: code_item.registers_size, ins_size: code_item.ins_size, diff --git a/androscalpel/src/dex_writer.rs b/androscalpel/src/dex_writer.rs index 6ad4000..7865997 100644 --- a/androscalpel/src/dex_writer.rs +++ b/androscalpel/src/dex_writer.rs @@ -377,7 +377,6 @@ impl DexWriter { .unwrap() .clone() }; - // Estimate instructions addresses let mut min_addr = 0; let mut max_addr = 0; @@ -1226,7 +1225,8 @@ impl DexWriter { let try_item = TryItem { start_addr: addr as u32, insn_count: (end_block_addr - addr) as u16, - handler_off: handler_off as u16, + handler_off: handler_off as u16, // will be ajusted once the size of the + // handler list object is known }; tries.push(try_item); let mut catches = EncodedCatchHandler { @@ -1279,6 +1279,10 @@ impl DexWriter { } insns.extend(payloads); + for try_ in &mut tries { + try_.handler_off += handlers.size_field().size() as u16; + } + let debug_info_off = if code.debug_info.is_empty() { 0 } else { diff --git a/androscalpel/src/instructions.rs b/androscalpel/src/instructions.rs index bcbdd9b..0e5b249 100644 --- a/androscalpel/src/instructions.rs +++ b/androscalpel/src/instructions.rs @@ -8009,21 +8009,9 @@ impl IfEqZ { #[new] pub fn new(a: u8, label: String) -> Result { let ins = Self { a, label }; - ins.sanity_check()?; Ok(ins) } - pub fn sanity_check(&self) -> Result<()> { - if self.a & 0b1111_0000 != 0 { - Err(anyhow!( - "if-eqz uses registers indexed on 4 bits, found {}", - self.a - )) - } else { - Ok(()) - } - } - pub fn __str__(&self) -> String { format!("if-eqz {} {}", self.a, self.label) } @@ -8122,21 +8110,9 @@ impl IfNeZ { #[new] pub fn new(a: u8, label: String) -> Result { let ins = Self { a, label }; - ins.sanity_check()?; Ok(ins) } - pub fn sanity_check(&self) -> Result<()> { - if self.a & 0b1111_0000 != 0 { - Err(anyhow!( - "if-neq uses registers indexed on 4 bits, found {}", - self.a - )) - } else { - Ok(()) - } - } - pub fn __str__(&self) -> String { format!("if-neq {} {}", self.a, self.label) } @@ -8235,21 +8211,9 @@ impl IfLtZ { #[new] pub fn new(a: u8, label: String) -> Result { let ins = Self { a, label }; - ins.sanity_check()?; Ok(ins) } - pub fn sanity_check(&self) -> Result<()> { - if self.a & 0b1111_0000 != 0 { - Err(anyhow!( - "if-lt uses registers indexed on 4 bits, found {}", - self.a - )) - } else { - Ok(()) - } - } - pub fn __str__(&self) -> String { format!("if-lt {} {}", self.a, self.label) } @@ -8348,21 +8312,9 @@ impl IfGeZ { #[new] pub fn new(a: u8, label: String) -> Result { let ins = Self { a, label }; - ins.sanity_check()?; Ok(ins) } - pub fn sanity_check(&self) -> Result<()> { - if self.a & 0b1111_0000 != 0 { - Err(anyhow!( - "if-ge uses registers indexed on 4 bits, found {}", - self.a - )) - } else { - Ok(()) - } - } - pub fn __str__(&self) -> String { format!("if-ge {} {}", self.a, self.label) } @@ -8461,21 +8413,9 @@ impl IfGtZ { #[new] pub fn new(a: u8, label: String) -> Result { let ins = Self { a, label }; - ins.sanity_check()?; Ok(ins) } - pub fn sanity_check(&self) -> Result<()> { - if self.a & 0b1111_0000 != 0 { - Err(anyhow!( - "if-gt uses registers indexed on 4 bits, found {}", - self.a - )) - } else { - Ok(()) - } - } - pub fn __str__(&self) -> String { format!("if-gt {} {}", self.a, self.label) } @@ -8574,21 +8514,9 @@ impl IfLeZ { #[new] pub fn new(a: u8, label: String) -> Result { let ins = Self { a, label }; - ins.sanity_check()?; Ok(ins) } - pub fn sanity_check(&self) -> Result<()> { - if self.a & 0b1111_0000 != 0 { - Err(anyhow!( - "if-le uses registers indexed on 4 bits, found {}", - self.a - )) - } else { - Ok(()) - } - } - pub fn __str__(&self) -> String { format!("if-le {} {}", self.a, self.label) } diff --git a/androscalpel_serializer/src/items/code.rs b/androscalpel_serializer/src/items/code.rs index 2fae98d..df51031 100644 --- a/androscalpel_serializer/src/items/code.rs +++ b/androscalpel_serializer/src/items/code.rs @@ -35,12 +35,16 @@ impl CodeItem { pub fn sanity_check(&self) -> Result<()> { if self.tries.is_empty() && self.handlers.is_some() { return Err(Error::InconsistantStruct( - "CodeItem cannot have a `handlers` value if `tries_size` is 0 (CodeItem.tries is empty)".into() + "CodeItem cannot have a `handlers` value if `tries_size` \ + is 0 (CodeItem.tries is empty)" + .into(), )); } if !self.tries.is_empty() && self.handlers.is_none() { return Err(Error::InconsistantStruct( - "CodeItem must have a `handlers` value if `tries_size` is not 0 (CodeItem.tries not empty)".into() + "CodeItem must have a `handlers` value if `tries_size` \ + is not 0 (CodeItem.tries not empty)" + .into(), )); } let mut max_addr = 0; @@ -48,7 +52,9 @@ impl CodeItem { let addr = item.start_addr; if addr < max_addr { return Err(Error::InconsistantStruct( - "try_item in a code_item must be non overlapping and sorted from low to high address".into() + "try_item in a code_item must be non overlapping and \ + sorted from low to high address" + .into(), )); } max_addr = addr + (item.insn_count as u32); @@ -121,8 +127,10 @@ impl CodeItem { } } if i < addresses.len() && addresses[i] < addr { + println!("{addresses:x?}"); return Err(Error::InconsistantStruct(format!( - "Found an address in try block (0x{addr:x}) that does not align with an instruction" + "Found an address in try block (0x{:x}) that does not align with an instruction", + addresses[i] ))); } @@ -170,11 +178,21 @@ impl Serializable for CodeItem { let mut insns = vec![]; let mut serialized_insns_size = 0; - while serialized_insns_size != insns_size { - let ins = Instruction::deserialize(input)?; - serialized_insns_size += ins.size() as u32; + while serialized_insns_size < insns_size { + let ins = Instruction::deserialize(input).map_err(|err| { + Error::DeserializationError(format!( + "Failed to deserialize instruction at 0x{serialized_insns_size:x}: {err}" + )) + })?; + serialized_insns_size += ins.size() as u32 / 2; insns.push(ins); } + if serialized_insns_size != insns_size { + return Err(Error::DeserializationError(format!( + "Failed to deserialize instructions, expected size of {insns_size} code \ + units (16 bits), found at least {serialized_insns_size}" + ))); + } if tries_size != 0 && insns_size % 2 == 1 { let _ = u16::deserialize(input)?; } @@ -265,7 +283,8 @@ impl EncodedCatchHandlerList { current_offset += handler.size(); } Err(Error::InconsistantStruct(format!( - "Offset 0x{offset:x} does not match with the begining of a EncodedCatchHandler in this EncodedCatchHandlerList" + "Offset 0x{offset:x} does not match with the begining of a \ + EncodedCatchHandler in this EncodedCatchHandlerList" ))) } } diff --git a/androscalpel_serializer/src/items/instructions.rs b/androscalpel_serializer/src/items/instructions.rs index 5e99312..eb16465 100644 --- a/androscalpel_serializer/src/items/instructions.rs +++ b/androscalpel_serializer/src/items/instructions.rs @@ -389,8 +389,11 @@ impl Instruction { requires the first byte to be 0 found {v}" ))); } + /* let [a_l0, a_l1, a_h0, a_h1] = i32::deserialize(input)?.to_be_bytes(); let a = i32::from_be_bytes([a_h0, a_h1, a_l0, a_l1]); + */ + let a = i32::deserialize(input)?; Ok(Self::Format30T { op, a }) } @@ -412,24 +415,33 @@ impl Instruction { pub fn deserialize_31i(input: &mut dyn ReadSeek) -> Result { let op = u8::deserialize(input)?; let va = u8::deserialize(input)?; + let b = i32::deserialize(input)?; + /* let [b_l0, b_l1, b_h0, b_h1] = i32::deserialize(input)?.to_be_bytes(); let b = i32::from_be_bytes([b_h0, b_h1, b_l0, b_l1]); + */ Ok(Self::Format31I { va, op, b }) } pub fn deserialize_31t(input: &mut dyn ReadSeek) -> Result { let op = u8::deserialize(input)?; let va = u8::deserialize(input)?; + let b = i32::deserialize(input)?; + /* let [b_l0, b_l1, b_h0, b_h1] = i32::deserialize(input)?.to_be_bytes(); let b = i32::from_be_bytes([b_h0, b_h1, b_l0, b_l1]); + */ Ok(Self::Format31T { va, op, b }) } pub fn deserialize_31c(input: &mut dyn ReadSeek) -> Result { let op = u8::deserialize(input)?; let va = u8::deserialize(input)?; + let b = u32::deserialize(input)?; + /* let [b_l0, b_l1, b_h0, b_h1] = u32::deserialize(input)?.to_be_bytes(); let b = u32::from_be_bytes([b_h0, b_h1, b_l0, b_l1]); + */ Ok(Self::Format31C { va, op, b }) } @@ -824,8 +836,11 @@ impl Serializable for Instruction { Self::Format30T { op, a } => { op.serialize(output)?; 0u8.serialize(output)?; + /* let [a_h0, a_h1, a_l0, a_l1] = a.to_be_bytes(); u32::from_be_bytes([a_l0, a_l1, a_h0, a_h1]).serialize(output) + */ + a.serialize(output) } Self::Format32X { op, va, vb } => { op.serialize(output)?; @@ -836,20 +851,29 @@ impl Serializable for Instruction { Self::Format31I { va, op, b } => { op.serialize(output)?; va.serialize(output)?; + /* let [b_h0, b_h1, b_l0, b_l1] = b.to_be_bytes(); u32::from_be_bytes([b_l0, b_l1, b_h0, b_h1]).serialize(output) + */ + b.serialize(output) } Self::Format31T { va, op, b } => { op.serialize(output)?; va.serialize(output)?; + /* let [b_h0, b_h1, b_l0, b_l1] = b.to_be_bytes(); u32::from_be_bytes([b_l0, b_l1, b_h0, b_h1]).serialize(output) + */ + b.serialize(output) } Self::Format31C { va, op, b } => { op.serialize(output)?; va.serialize(output)?; + /* let [b_h0, b_h1, b_l0, b_l1] = b.to_be_bytes(); u32::from_be_bytes([b_l0, b_l1, b_h0, b_h1]).serialize(output) + */ + b.serialize(output) } Self::Format35C { a,