From 00009436c549393c6aa001d9179f3c46632b3ec4 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Thu, 18 Jul 2024 14:28:50 +0200 Subject: [PATCH] WIP --- androscalpel/src/apk.rs | 946 ++++++++++++++++++++++++++++------------ 1 file changed, 666 insertions(+), 280 deletions(-) diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index cd492f0..b822d0a 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -790,81 +790,113 @@ impl Apk { } let ins = match format.clone() { Format10X { op: 0x00 } => Instruction::Nop {}, - Format12X { op: 0x01, va, vb } => Instruction::Move(Move::new(va as u16, vb as u16)), - Format22X { op: 0x02, va, vb } => Instruction::Move(Move::new(va as u16, vb)), - Format32X { op: 0x03, va, vb } => Instruction::Move(Move::new(va, vb)), - Format12X { op: 0x04, va, vb } => { - Instruction::MoveWide(MoveWide::new(va as u16, vb as u16)) - } - Format22X { op: 0x05, va, vb } => Instruction::MoveWide(MoveWide::new(va as u16, vb)), - Format32X { op: 0x06, va, vb } => Instruction::MoveWide(MoveWide::new(va, vb)), - Format12X { op: 0x07, va, vb } => { - Instruction::MoveObject(MoveObject::new(va as u16, vb as u16)) - } - Format22X { op: 0x08, va, vb } => { - Instruction::MoveObject(MoveObject::new(va as u16, vb)) - } - Format32X { op: 0x09, va, vb } => Instruction::MoveObject(MoveObject::new(va, vb)), - Format11X { op: 0x0a, va } => Instruction::MoveResult(MoveResult::new(va)), - Format11X { op: 0x0b, va } => Instruction::MoveResultWide(MoveResultWide::new(va)), - Format11X { op: 0x0c, va } => Instruction::MoveResultObject(MoveResultObject::new(va)), - Format11X { op: 0x0d, va } => Instruction::MoveException(MoveException::new(va)), - Format10X { op: 0x0e } => Instruction::ReturnVoid(ReturnVoid::new()), - Format11X { op: 0x0f, va } => Instruction::Return(Return::new(va)), - Format11X { op: 0x10, va } => Instruction::ReturnWide(ReturnWide::new(va)), - Format11X { op: 0x11, va } => Instruction::ReturnObject(ReturnObject::new(va)), - Format11N { op: 0x12, va, b } => Instruction::Const(Const::new(va, b as i32)), - Format21S { op: 0x13, va, b } => Instruction::Const(Const::new(va, b as i32)), - Format31I { op: 0x14, va, b } => Instruction::Const(Const::new(va, b)), - Format21H { op: 0x15, va, b } => Instruction::Const(Const::new(va, (b as i32) * 65536)), // *2**16 - Format21S { op: 0x16, va, b } => Instruction::ConstWide(ConstWide::new(va, b as i64)), - Format31I { op: 0x17, va, b } => Instruction::ConstWide(ConstWide::new(va, b as i64)), - Format51L { op: 0x18, va, b } => Instruction::ConstWide(ConstWide::new(va, b)), + Format12X { op: 0x01, va, vb } => Instruction::Move { + from: va as u16, + to: vb as u16, + }, + Format22X { op: 0x02, va, vb } => Instruction::Move { + from: va as u16, + to: vb, + }, + Format32X { op: 0x03, va, vb } => Instruction::Move { from: va, to: vb }, + Format12X { op: 0x04, va, vb } => Instruction::MoveWide { + from: va as u16, + to: vb as u16, + }, + Format22X { op: 0x05, va, vb } => Instruction::MoveWide { + from: va as u16, + to: vb, + }, + Format32X { op: 0x06, va, vb } => Instruction::MoveWide { from: va, to: vb }, + Format12X { op: 0x07, va, vb } => Instruction::MoveObject { + from: va as u16, + to: vb as u16, + }, + Format22X { op: 0x08, va, vb } => Instruction::MoveObject { + from: va as u16, + to: vb, + }, + Format32X { op: 0x09, va, vb } => Instruction::MoveObject { from: va, to: vb }, + Format11X { op: 0x0a, va } => Instruction::MoveResult { to: va }, + Format11X { op: 0x0b, va } => Instruction::MoveResultWide { to: va }, + Format11X { op: 0x0c, va } => Instruction::MoveResultObject { to: va }, + Format11X { op: 0x0d, va } => Instruction::MoveException { to: va }, + Format10X { op: 0x0e } => Instruction::ReturnVoid {}, + Format11X { op: 0x0f, va } => Instruction::Return { reg: va }, + Format11X { op: 0x10, va } => Instruction::ReturnWide { reg: va }, + Format11X { op: 0x11, va } => Instruction::ReturnObject { reg: va }, + Format11N { op: 0x12, va, b } => Instruction::Const { + reg: va, + lit: b as i32, + }, + Format21S { op: 0x13, va, b } => Instruction::Const { + reg: va, + lit: b as i32, + }, + Format31I { op: 0x14, va, b } => Instruction::Const { reg: va, lit: b }, + Format21H { op: 0x15, va, b } => Instruction::Const { + reg: va, + lit: (b as i32) * 65536, + }, // *2**16 + Format21S { op: 0x16, va, b } => Instruction::ConstWide { + reg: va, + lit: b as i64, + }, + Format31I { op: 0x17, va, b } => Instruction::ConstWide { + reg: va, + lit: b as i64, + }, + Format51L { op: 0x18, va, b } => Instruction::ConstWide { reg: va, lit: b }, Format21H { op: 0x19, va, b } => { - Instruction::ConstWide(ConstWide::new(va, (b as i64) * 281474976710656)) + Instruction::ConstWide { + reg: va, + lit: (b as i64) * 281474976710656, + } // * 2**48 } - Format21C { op: 0x1a, va, b } => { - Instruction::ConstString(ConstString::new(va, dex.get_string(b as u32)?.into())) - } - Format31C { op: 0x1b, va, b } => { - Instruction::ConstString(ConstString::new(va, dex.get_string(b)?.into())) - } - Format21C { op: 0x1c, va, b } => Instruction::ConstClass(ConstClass::new( - va, - Self::get_id_type_from_idx(b as usize, dex)?, - )), - Format11X { op: 0x1d, va } => Instruction::MonitorEnter(MonitorEnter::new(va)), - Format11X { op: 0x1e, va } => Instruction::MonitorExit(MonitorExit::new(va)), - Format21C { op: 0x1f, va, b } => Instruction::CheckCast(CheckCast::new( - va, - Self::get_id_type_from_idx(b as usize, dex)?, - )), + Format21C { op: 0x1a, va, b } => Instruction::ConstString { + reg: va, + lit: dex.get_string(b as u32)?.into(), + }, + Format31C { op: 0x1b, va, b } => Instruction::ConstString { + reg: va, + lit: dex.get_string(b)?.into(), + }, + Format21C { op: 0x1c, va, b } => Instruction::ConstClass { + reg: va, + lit: Self::get_id_type_from_idx(b as usize, dex)?, + }, + Format11X { op: 0x1d, va } => Instruction::MonitorEnter { reg: va }, + Format11X { op: 0x1e, va } => Instruction::MonitorExit { reg: va }, + Format21C { op: 0x1f, va, b } => Instruction::CheckCast { + reg: va, + lit: Self::get_id_type_from_idx(b as usize, dex)?, + }, Format22C { op: 0x20, va, vb, c, - } => Instruction::InstanceOf(InstanceOf::new( - va, - vb, - Self::get_id_type_from_idx(c as usize, dex)?, - )?), - Format12X { op: 0x21, va, vb } => Instruction::ArrayLength(ArrayLength::new(va, vb)?), - Format21C { op: 0x22, va, b } => Instruction::NewInstance(NewInstance::new( - va, - Self::get_id_type_from_idx(b as usize, dex)?, - )), + } => Instruction::InstanceOf { + dest: va, + obj: vb, + lit: Self::get_id_type_from_idx(c as usize, dex)?, + }, + Format12X { op: 0x21, va, vb } => Instruction::ArrayLength { dest: va, arr: vb }, + Format21C { op: 0x22, va, b } => Instruction::NewInstance { + reg: va, + lit: Self::get_id_type_from_idx(b as usize, dex)?, + }, Format22C { op: 0x23, va, vb, c, - } => Instruction::NewArray(NewArray::new( - va, - vb, - Self::get_id_type_from_idx(c as usize, dex)?, - )?), + } => Instruction::NewArray { + reg: va, + size_reg: vb, + lit: Self::get_id_type_from_idx(c as usize, dex)?, + }, Format35C { op: 0x24, a, @@ -878,12 +910,12 @@ impl Apk { let type_ = Self::get_id_type_from_idx(b as usize, dex)?; let reg_values: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::FilledNewArray(FilledNewArray::new(type_, reg_values)?) + Instruction::FilledNewArray { type_, reg_values } } Format3RC { op: 0x25, a, b, vc } => { let type_ = Self::get_id_type_from_idx(b as usize, dex)?; let reg_values = (vc..vc + a as u16).collect(); - Instruction::FilledNewArray(FilledNewArray::new(type_, reg_values)?) + Instruction::FilledNewArray { type_, reg_values } } Format31T { op: 0x26, va, b } => { if b < 0 && (-(b as i64)) as usize > addr { @@ -899,7 +931,11 @@ impl Apk { }; if let Some(ins) = insns_ref.get(&data_addr) { if let FormatFillArrayDataPayload { elt_width, data } = ins { - Instruction::FillArrayData(FillArrayData::new(va, *elt_width, data.clone())) + Instruction::FillArrayData { + arr: va, + elt_width: *elt_width, + data: data.clone(), + } } else { bail!( "Found fill-array-data-payload v{va} +{b} at 0x{addr:x}, \ @@ -913,7 +949,7 @@ impl Apk { ) } } - Format11X { op: 0x27, va } => Instruction::Throw(Throw::new(va)), + Format11X { op: 0x27, va } => Instruction::Throw { reg: va }, Format10T { op: 0x28, a } => { if a < 0 && (-(a as i64)) as usize > addr { bail!("Found goto {a} at 0x{addr:0x}: the destination is invalid (negative addresse)"); @@ -930,7 +966,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::Goto(Goto::new(label)) + Instruction::Goto { label } } Format20T { op: 0x29, a } => { if a < 0 && (-(a as i64)) as usize > addr { @@ -948,7 +984,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::Goto(Goto::new(label)) + Instruction::Goto { label } } Format30T { op: 0x2a, a } => { if a < 0 && (-(a as i64)) as usize > addr { @@ -966,7 +1002,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::Goto(Goto::new(label)) + Instruction::Goto { label } } Format31T { op: 0x2b, va, b } => { if b < 0 && -(b as i64) as usize > addr { @@ -1009,7 +1045,7 @@ impl Apk { branches.insert(key, label); key += 1; } - Instruction::Switch(Switch::new(va, branches)) + Instruction::Switch { reg: va, branches } } else { bail!( "Found packed-switch v{va} +{b} at 0x{addr:x}, \ @@ -1062,7 +1098,7 @@ impl Apk { } branches.insert(key, label); } - Instruction::Switch(Switch::new(va, branches)) + Instruction::Switch { reg: va, branches } } else { bail!( "Found packed-switch v{va} +{b} at 0x{addr:x}, \ @@ -1081,31 +1117,51 @@ impl Apk { va, vb, vc, - } => Instruction::CmpLFloat(CmpLFloat::new(va, vb, vc)), + } => Instruction::CmpLFloat { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x2e, va, vb, vc, - } => Instruction::CmpGFloat(CmpGFloat::new(va, vb, vc)), + } => Instruction::CmpGFloat { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x2f, va, vb, vc, - } => Instruction::CmpLDouble(CmpLDouble::new(va, vb, vc)), + } => Instruction::CmpLDouble { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x30, va, vb, vc, - } => Instruction::CmpGDouble(CmpGDouble::new(va, vb, vc)), + } => Instruction::CmpGDouble { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x31, va, vb, vc, - } => Instruction::CmpLong(CmpLong::new(va, vb, vc)), + } => Instruction::CmpLong { + dest: va, + b: vb, + c: vc, + }, Format22T { op: 0x32, va, @@ -1130,7 +1186,11 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfEq(IfEq::new(va, vb, label)?) + Instruction::IfEq { + a: va, + b: vb, + label, + } } Format22T { op: 0x33, @@ -1156,7 +1216,11 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfNe(IfNe::new(va, vb, label)?) + Instruction::IfNe { + a: va, + b: vb, + label, + } } Format22T { op: 0x34, @@ -1182,7 +1246,11 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfLt(IfLt::new(va, vb, label)?) + Instruction::IfLt { + a: va, + b: vb, + label, + } } Format22T { op: 0x35, @@ -1208,7 +1276,11 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfGe(IfGe::new(va, vb, label)?) + Instruction::IfGe { + a: va, + b: vb, + label, + } } Format22T { op: 0x36, @@ -1234,7 +1306,11 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfGt(IfGt::new(va, vb, label)?) + Instruction::IfGt { + a: va, + b: vb, + label, + } } Format22T { op: 0x37, @@ -1260,7 +1336,11 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfLe(IfLe::new(va, vb, label)?) + Instruction::IfLe { + a: va, + b: vb, + label, + } } Format21T { op: 0x38, va, b } => { if b < 0 && (-(b as i64)) as usize > addr { @@ -1281,7 +1361,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfEqZ(IfEqZ::new(va, label)?) + Instruction::IfEqZ { a: va, label } } Format21T { op: 0x39, va, b } => { if b < 0 && (-(b as i64)) as usize > addr { @@ -1302,7 +1382,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfNeZ(IfNeZ::new(va, label)?) + Instruction::IfNeZ { a: va, label } } Format21T { op: 0x3a, va, b } => { if b < 0 && (-(b as i64)) as usize > addr { @@ -1323,7 +1403,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfLtZ(IfLtZ::new(va, label)?) + Instruction::IfLtZ { a: va, label } } Format21T { op: 0x3b, va, b } => { if b < 0 && (-(b as i64)) as usize > addr { @@ -1344,7 +1424,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfGeZ(IfGeZ::new(va, label)?) + Instruction::IfGeZ { a: va, label } } Format21T { op: 0x3c, va, b } => { if b < 0 && (-(b as i64)) as usize > addr { @@ -1365,7 +1445,7 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfGtZ(IfGtZ::new(va, label)?) + Instruction::IfGtZ { a: va, label } } Format21T { op: 0x3d, va, b } => { if b < 0 && (-(b as i64)) as usize > addr { @@ -1386,92 +1466,148 @@ impl Apk { bail!("There is already a label at 0x{dest_addr:08X} with an invalid name"); } } - Instruction::IfLeZ(IfLeZ::new(va, label)?) + Instruction::IfLeZ { a: va, label } } Format23X { op: 0x44, va, vb, vc, - } => Instruction::AGet(AGet::new(va, vb, vc)), + } => Instruction::AGet { + dest: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x45, va, vb, vc, - } => Instruction::AGetWide(AGetWide::new(va, vb, vc)), + } => Instruction::AGetWide { + dest: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x46, va, vb, vc, - } => Instruction::AGetObject(AGetObject::new(va, vb, vc)), + } => Instruction::AGetObject { + dest: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x47, va, vb, vc, - } => Instruction::AGetBoolean(AGetBoolean::new(va, vb, vc)), + } => Instruction::AGetBoolean { + dest: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x48, va, vb, vc, - } => Instruction::AGetByte(AGetByte::new(va, vb, vc)), + } => Instruction::AGetByte { + dest: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x49, va, vb, vc, - } => Instruction::AGetChar(AGetChar::new(va, vb, vc)), + } => Instruction::AGetChar { + dest: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x4a, va, vb, vc, - } => Instruction::AGetShort(AGetShort::new(va, vb, vc)), + } => Instruction::AGetShort { + dest: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x4b, va, vb, vc, - } => Instruction::APut(APut::new(va, vb, vc)), + } => Instruction::APut { + from: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x4c, va, vb, vc, - } => Instruction::APutWide(APutWide::new(va, vb, vc)), + } => Instruction::APutWide { + from: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x4d, va, vb, vc, - } => Instruction::APutObject(APutObject::new(va, vb, vc)), + } => Instruction::APutObject { + from: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x4e, va, vb, vc, - } => Instruction::APutBoolean(APutBoolean::new(va, vb, vc)), + } => Instruction::APutBoolean { + from: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x4f, va, vb, vc, - } => Instruction::APutByte(APutByte::new(va, vb, vc)), + } => Instruction::APutByte { + from: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x50, va, vb, vc, - } => Instruction::APutChar(APutChar::new(va, vb, vc)), + } => Instruction::APutChar { + from: va, + arr: vb, + idx: vc, + }, Format23X { op: 0x51, va, vb, vc, - } => Instruction::APutShort(APutShort::new(va, vb, vc)), + } => Instruction::APutShort { + from: va, + arr: vb, + idx: vc, + }, Format22C { op: 0x52, va, @@ -1479,7 +1615,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IGet(IGet::new(va, vb, field)?) + Instruction::IGet { + to: va, + obj: vb, + field, + } } Format22C { op: 0x53, @@ -1488,7 +1628,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IGetWide(IGetWide::new(va, vb, field)?) + Instruction::IGetWide { + to: va, + obj: vb, + field, + } } Format22C { op: 0x54, @@ -1497,7 +1641,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IGetObject(IGetObject::new(va, vb, field)?) + Instruction::IGetObject { + to: va, + obj: vb, + field, + } } Format22C { op: 0x55, @@ -1506,7 +1654,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IGetBoolean(IGetBoolean::new(va, vb, field)?) + Instruction::IGetBoolean { + to: va, + obj: vb, + field, + } } Format22C { op: 0x56, @@ -1515,7 +1667,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IGetByte(IGetByte::new(va, vb, field)?) + Instruction::IGetByte { + to: va, + obj: vb, + field, + } } Format22C { op: 0x57, @@ -1524,7 +1680,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IGetChar(IGetChar::new(va, vb, field)?) + Instruction::IGetChar { + to: va, + obj: vb, + field, + } } Format22C { op: 0x58, @@ -1533,7 +1693,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IGetShort(IGetShort::new(va, vb, field)?) + Instruction::IGetShort { + to: va, + obj: vb, + field, + } } Format22C { op: 0x59, @@ -1542,7 +1706,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IPut(IPut::new(va, vb, field)?) + Instruction::IPut { + from: va, + obj: vb, + field, + } } Format22C { op: 0x5a, @@ -1551,7 +1719,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IPutWide(IPutWide::new(va, vb, field)?) + Instruction::IPutWide { + from: va, + obj: vb, + field, + } } Format22C { op: 0x5b, @@ -1560,7 +1732,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IPutObject(IPutObject::new(va, vb, field)?) + Instruction::IPutObject { + from: va, + obj: vb, + field, + } } Format22C { op: 0x5c, @@ -1569,7 +1745,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IPutBoolean(IPutBoolean::new(va, vb, field)?) + Instruction::IPutBoolean { + from: va, + obj: vb, + field, + } } Format22C { op: 0x5d, @@ -1578,7 +1758,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IPutByte(IPutByte::new(va, vb, field)?) + Instruction::IPutByte { + from: va, + obj: vb, + field, + } } Format22C { op: 0x5e, @@ -1587,7 +1771,11 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IPutChar(IPutChar::new(va, vb, field)?) + Instruction::IPutChar { + from: va, + obj: vb, + field, + } } Format22C { op: 0x5f, @@ -1596,63 +1784,67 @@ impl Apk { c, } => { let field = Self::get_id_field_from_idx(c as usize, dex)?; - Instruction::IPutShort(IPutShort::new(va, vb, field)?) + Instruction::IPutShort { + from: va, + obj: vb, + field, + } } Format21C { op: 0x60, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SGet(SGet::new(va, field)) + Instruction::SGet { to: va, field } } Format21C { op: 0x61, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SGetWide(SGetWide::new(va, field)) + Instruction::SGetWide { to: va, field } } Format21C { op: 0x62, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SGetObject(SGetObject::new(va, field)) + Instruction::SGetObject { to: va, field } } Format21C { op: 0x63, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SGetBoolean(SGetBoolean::new(va, field)) + Instruction::SGetBoolean { to: va, field } } Format21C { op: 0x64, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SGetByte(SGetByte::new(va, field)) + Instruction::SGetByte { to: va, field } } Format21C { op: 0x65, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SGetChar(SGetChar::new(va, field)) + Instruction::SGetChar { to: va, field } } Format21C { op: 0x66, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SGetShort(SGetShort::new(va, field)) + Instruction::SGetShort { to: va, field } } Format21C { op: 0x67, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SPut(SPut::new(va, field)) + Instruction::SPut { from: va, field } } Format21C { op: 0x68, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SPutWide(SPutWide::new(va, field)) + Instruction::SPutWide { from: va, field } } Format21C { op: 0x69, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SPutObject(SPutObject::new(va, field)) + Instruction::SPutObject { from: va, field } } Format21C { op: 0x6a, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SPutBoolean(SPutBoolean::new(va, field)) + Instruction::SPutBoolean { from: va, field } } Format21C { op: 0x6b, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SPutByte(SPutByte::new(va, field)) + Instruction::SPutByte { from: va, field } } Format21C { op: 0x6c, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SPutChar(SPutChar::new(va, field)) + Instruction::SPutChar { from: va, field } } Format21C { op: 0x6d, va, b } => { let field = Self::get_id_field_from_idx(b as usize, dex)?; - Instruction::SPutShort(SPutShort::new(va, field)) + Instruction::SPutShort { from: va, field } } Format35C { op: 0x6e, @@ -1667,7 +1859,7 @@ impl Apk { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::InvokeVirtual(InvokeVirtual::new(meth, args)?) + Instruction::InvokeVirtual { method: meth, args } } Format35C { op: 0x6f, @@ -1682,7 +1874,7 @@ impl Apk { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::InvokeSuper(InvokeSuper::new(meth, args)?) + Instruction::InvokeSuper { method: meth, args } } Format35C { op: 0x70, @@ -1697,7 +1889,7 @@ impl Apk { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::InvokeDirect(InvokeDirect::new(meth, args)?) + Instruction::InvokeDirect { method: meth, args } } Format35C { op: 0x71, @@ -1712,7 +1904,7 @@ impl Apk { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::InvokeStatic(InvokeStatic::new(meth, args)?) + Instruction::InvokeStatic { method: meth, args } } Format35C { op: 0x72, @@ -1727,418 +1919,596 @@ impl Apk { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::InvokeInterface(InvokeInterface::new(meth, args)?) + Instruction::InvokeInterface { method: meth, args } } Format3RC { op: 0x74, a, b, vc } => { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args = (vc..vc + a as u16).collect(); - Instruction::InvokeVirtual(InvokeVirtual::new(meth, args)?) + Instruction::InvokeVirtual { method: meth, args } } Format3RC { op: 0x75, a, b, vc } => { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args = (vc..vc + a as u16).collect(); - Instruction::InvokeSuper(InvokeSuper::new(meth, args)?) + Instruction::InvokeSuper { method: meth, args } } Format3RC { op: 0x76, a, b, vc } => { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args = (vc..vc + a as u16).collect(); - Instruction::InvokeDirect(InvokeDirect::new(meth, args)?) + Instruction::InvokeDirect { method: meth, args } } Format3RC { op: 0x77, a, b, vc } => { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args = (vc..vc + a as u16).collect(); - Instruction::InvokeStatic(InvokeStatic::new(meth, args)?) + Instruction::InvokeStatic { method: meth, args } } Format3RC { op: 0x78, a, b, vc } => { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let args = (vc..vc + a as u16).collect(); - Instruction::InvokeInterface(InvokeInterface::new(meth, args)?) + Instruction::InvokeInterface { method: meth, args } } - Format12X { op: 0x7b, va, vb } => Instruction::NegInt(NegInt::new(va, vb)?), - Format12X { op: 0x7c, va, vb } => Instruction::NotInt(NotInt::new(va, vb)?), - Format12X { op: 0x7d, va, vb } => Instruction::NegLong(NegLong::new(va, vb)?), - Format12X { op: 0x7e, va, vb } => Instruction::NotLong(NotLong::new(va, vb)?), - Format12X { op: 0x7f, va, vb } => Instruction::NegFloat(NegFloat::new(va, vb)?), - Format12X { op: 0x80, va, vb } => Instruction::NegDouble(NegDouble::new(va, vb)?), - Format12X { op: 0x81, va, vb } => Instruction::IntToLong(IntToLong::new(va, vb)?), - Format12X { op: 0x82, va, vb } => Instruction::IntToFloat(IntToFloat::new(va, vb)?), - Format12X { op: 0x83, va, vb } => Instruction::IntToDouble(IntToDouble::new(va, vb)?), - Format12X { op: 0x84, va, vb } => Instruction::LongToInt(LongToInt::new(va, vb)?), - Format12X { op: 0x85, va, vb } => Instruction::LongToFloat(LongToFloat::new(va, vb)?), - Format12X { op: 0x86, va, vb } => Instruction::LongToDouble(LongToDouble::new(va, vb)?), - Format12X { op: 0x87, va, vb } => Instruction::FloatToInt(FloatToInt::new(va, vb)?), - Format12X { op: 0x88, va, vb } => Instruction::FloatToLong(FloatToLong::new(va, vb)?), - Format12X { op: 0x89, va, vb } => { - Instruction::FloatToDouble(FloatToDouble::new(va, vb)?) - } - Format12X { op: 0x8a, va, vb } => Instruction::DoubleToInt(DoubleToInt::new(va, vb)?), - Format12X { op: 0x8b, va, vb } => Instruction::DoubleToLong(DoubleToLong::new(va, vb)?), - Format12X { op: 0x8c, va, vb } => { - Instruction::DoubleToFloat(DoubleToFloat::new(va, vb)?) - } - Format12X { op: 0x8d, va, vb } => Instruction::IntToByte(IntToByte::new(va, vb)?), - Format12X { op: 0x8e, va, vb } => Instruction::IntToChar(IntToChar::new(va, vb)?), - Format12X { op: 0x8f, va, vb } => Instruction::IntToShort(IntToShort::new(va, vb)?), + Format12X { op: 0x7b, va, vb } => Instruction::NegInt { dest: va, val: vb }, + Format12X { op: 0x7c, va, vb } => Instruction::NotInt { dest: va, val: vb }, + Format12X { op: 0x7d, va, vb } => Instruction::NegLong { dest: va, val: vb }, + Format12X { op: 0x7e, va, vb } => Instruction::NotLong { dest: va, val: vb }, + Format12X { op: 0x7f, va, vb } => Instruction::NegFloat { dest: va, val: vb }, + Format12X { op: 0x80, va, vb } => Instruction::NegDouble { dest: va, val: vb }, + Format12X { op: 0x81, va, vb } => Instruction::IntToLong { dest: va, val: vb }, + Format12X { op: 0x82, va, vb } => Instruction::IntToFloat { dest: va, val: vb }, + Format12X { op: 0x83, va, vb } => Instruction::IntToDouble { dest: va, val: vb }, + Format12X { op: 0x84, va, vb } => Instruction::LongToInt { dest: va, val: vb }, + Format12X { op: 0x85, va, vb } => Instruction::LongToFloat { dest: va, val: vb }, + Format12X { op: 0x86, va, vb } => Instruction::LongToDouble { dest: va, val: vb }, + Format12X { op: 0x87, va, vb } => Instruction::FloatToInt { dest: va, val: vb }, + Format12X { op: 0x88, va, vb } => Instruction::FloatToLong { dest: va, val: vb }, + Format12X { op: 0x89, va, vb } => Instruction::FloatToDouble { dest: va, val: vb }, + Format12X { op: 0x8a, va, vb } => Instruction::DoubleToInt { dest: va, val: vb }, + Format12X { op: 0x8b, va, vb } => Instruction::DoubleToLong { dest: va, val: vb }, + Format12X { op: 0x8c, va, vb } => Instruction::DoubleToFloat { dest: va, val: vb }, + Format12X { op: 0x8d, va, vb } => Instruction::IntToByte { dest: va, val: vb }, + Format12X { op: 0x8e, va, vb } => Instruction::IntToChar { dest: va, val: vb }, + Format12X { op: 0x8f, va, vb } => Instruction::IntToShort { dest: va, val: vb }, Format23X { op: 0x90, va, vb, vc, - } => Instruction::AddInt(AddInt::new(va, vb, vc)), + } => Instruction::AddInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x91, va, vb, vc, - } => Instruction::SubInt(SubInt::new(va, vb, vc)), + } => Instruction::SubInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x92, va, vb, vc, - } => Instruction::MulInt(MulInt::new(va, vb, vc)), + } => Instruction::MulInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x93, va, vb, vc, - } => Instruction::DivInt(DivInt::new(va, vb, vc)), + } => Instruction::DivInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x94, va, vb, vc, - } => Instruction::RemInt(RemInt::new(va, vb, vc)), + } => Instruction::RemInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x95, va, vb, vc, - } => Instruction::AndInt(AndInt::new(va, vb, vc)), + } => Instruction::AndInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x96, va, vb, vc, - } => Instruction::OrInt(OrInt::new(va, vb, vc)), + } => Instruction::OrInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x97, va, vb, vc, - } => Instruction::XorInt(XorInt::new(va, vb, vc)), + } => Instruction::XorInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x98, va, vb, vc, - } => Instruction::ShlInt(ShlInt::new(va, vb, vc)), + } => Instruction::ShlInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x99, va, vb, vc, - } => Instruction::ShrInt(ShrInt::new(va, vb, vc)), + } => Instruction::ShrInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x9a, va, vb, vc, - } => Instruction::UshrInt(UshrInt::new(va, vb, vc)), + } => Instruction::UshrInt { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x9b, va, vb, vc, - } => Instruction::AddLong(AddLong::new(va, vb, vc)), + } => Instruction::AddLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x9c, va, vb, vc, - } => Instruction::SubLong(SubLong::new(va, vb, vc)), + } => Instruction::SubLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x9d, va, vb, vc, - } => Instruction::MulLong(MulLong::new(va, vb, vc)), + } => Instruction::MulLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x9e, va, vb, vc, - } => Instruction::DivLong(DivLong::new(va, vb, vc)), + } => Instruction::DivLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0x9f, va, vb, vc, - } => Instruction::RemLong(RemLong::new(va, vb, vc)), + } => Instruction::RemLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa0, va, vb, vc, - } => Instruction::AndLong(AndLong::new(va, vb, vc)), + } => Instruction::AndLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa1, va, vb, vc, - } => Instruction::OrLong(OrLong::new(va, vb, vc)), + } => Instruction::OrLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa2, va, vb, vc, - } => Instruction::XorLong(XorLong::new(va, vb, vc)), + } => Instruction::XorLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa3, va, vb, vc, - } => Instruction::ShlLong(ShlLong::new(va, vb, vc)), + } => Instruction::ShlLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa4, va, vb, vc, - } => Instruction::ShrLong(ShrLong::new(va, vb, vc)), + } => Instruction::ShrLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa5, va, vb, vc, - } => Instruction::UshrLong(UshrLong::new(va, vb, vc)), + } => Instruction::UshrLong { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa6, va, vb, vc, - } => Instruction::AddFloat(AddFloat::new(va, vb, vc)), + } => Instruction::AddFloat { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa7, va, vb, vc, - } => Instruction::SubFloat(SubFloat::new(va, vb, vc)), + } => Instruction::SubFloat { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa8, va, vb, vc, - } => Instruction::MulFloat(MulFloat::new(va, vb, vc)), + } => Instruction::MulFloat { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xa9, va, vb, vc, - } => Instruction::DivFloat(DivFloat::new(va, vb, vc)), + } => Instruction::DivFloat { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xaa, va, vb, vc, - } => Instruction::RemFloat(RemFloat::new(va, vb, vc)), + } => Instruction::RemFloat { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xab, va, vb, vc, - } => Instruction::AddDouble(AddDouble::new(va, vb, vc)), + } => Instruction::AddDouble { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xac, va, vb, vc, - } => Instruction::SubDouble(SubDouble::new(va, vb, vc)), + } => Instruction::SubDouble { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xad, va, vb, vc, - } => Instruction::MulDouble(MulDouble::new(va, vb, vc)), + } => Instruction::MulDouble { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xae, va, vb, vc, - } => Instruction::DivDouble(DivDouble::new(va, vb, vc)), + } => Instruction::DivDouble { + dest: va, + b: vb, + c: vc, + }, Format23X { op: 0xaf, va, vb, vc, - } => Instruction::RemDouble(RemDouble::new(va, vb, vc)), - Format12X { op: 0xb0, va, vb } => Instruction::AddInt2Addr(AddInt2Addr::new(va, vb)?), - Format12X { op: 0xb1, va, vb } => Instruction::SubInt2Addr(SubInt2Addr::new(va, vb)?), - Format12X { op: 0xb2, va, vb } => Instruction::MulInt2Addr(MulInt2Addr::new(va, vb)?), - Format12X { op: 0xb3, va, vb } => Instruction::DivInt2Addr(DivInt2Addr::new(va, vb)?), - Format12X { op: 0xb4, va, vb } => Instruction::RemInt2Addr(RemInt2Addr::new(va, vb)?), - Format12X { op: 0xb5, va, vb } => Instruction::AndInt2Addr(AndInt2Addr::new(va, vb)?), - Format12X { op: 0xb6, va, vb } => Instruction::OrInt2Addr(OrInt2Addr::new(va, vb)?), - Format12X { op: 0xb7, va, vb } => Instruction::XorInt2Addr(XorInt2Addr::new(va, vb)?), - Format12X { op: 0xb8, va, vb } => Instruction::ShlInt2Addr(ShlInt2Addr::new(va, vb)?), - Format12X { op: 0xb9, va, vb } => Instruction::ShrInt2Addr(ShrInt2Addr::new(va, vb)?), - Format12X { op: 0xba, va, vb } => Instruction::UshrInt2Addr(UshrInt2Addr::new(va, vb)?), - Format12X { op: 0xbb, va, vb } => Instruction::AddLong2Addr(AddLong2Addr::new(va, vb)?), - Format12X { op: 0xbc, va, vb } => Instruction::SubLong2Addr(SubLong2Addr::new(va, vb)?), - Format12X { op: 0xbd, va, vb } => Instruction::MulLong2Addr(MulLong2Addr::new(va, vb)?), - Format12X { op: 0xbe, va, vb } => Instruction::DivLong2Addr(DivLong2Addr::new(va, vb)?), - Format12X { op: 0xbf, va, vb } => Instruction::RemLong2Addr(RemLong2Addr::new(va, vb)?), - Format12X { op: 0xc0, va, vb } => Instruction::AndLong2Addr(AndLong2Addr::new(va, vb)?), - Format12X { op: 0xc1, va, vb } => Instruction::OrLong2Addr(OrLong2Addr::new(va, vb)?), - Format12X { op: 0xc2, va, vb } => Instruction::XorLong2Addr(XorLong2Addr::new(va, vb)?), - Format12X { op: 0xc3, va, vb } => Instruction::ShlLong2Addr(ShlLong2Addr::new(va, vb)?), - Format12X { op: 0xc4, va, vb } => Instruction::ShrLong2Addr(ShrLong2Addr::new(va, vb)?), - Format12X { op: 0xc5, va, vb } => { - Instruction::UshrLong2Addr(UshrLong2Addr::new(va, vb)?) - } - Format12X { op: 0xc6, va, vb } => { - Instruction::AddFloat2Addr(AddFloat2Addr::new(va, vb)?) - } - Format12X { op: 0xc7, va, vb } => { - Instruction::SubFloat2Addr(SubFloat2Addr::new(va, vb)?) - } - Format12X { op: 0xc8, va, vb } => { - Instruction::MulFloat2Addr(MulFloat2Addr::new(va, vb)?) - } - Format12X { op: 0xc9, va, vb } => { - Instruction::DivFloat2Addr(DivFloat2Addr::new(va, vb)?) - } - Format12X { op: 0xca, va, vb } => { - Instruction::RemFloat2Addr(RemFloat2Addr::new(va, vb)?) - } - Format12X { op: 0xcb, va, vb } => { - Instruction::AddDouble2Addr(AddDouble2Addr::new(va, vb)?) - } - Format12X { op: 0xcc, va, vb } => { - Instruction::SubDouble2Addr(SubDouble2Addr::new(va, vb)?) - } - Format12X { op: 0xcd, va, vb } => { - Instruction::MulDouble2Addr(MulDouble2Addr::new(va, vb)?) - } - Format12X { op: 0xce, va, vb } => { - Instruction::DivDouble2Addr(DivDouble2Addr::new(va, vb)?) - } - Format12X { op: 0xcf, va, vb } => { - Instruction::RemDouble2Addr(RemDouble2Addr::new(va, vb)?) - } + } => Instruction::RemDouble { + dest: va, + b: vb, + c: vc, + }, + Format12X { op: 0xb0, va, vb } => Instruction::AddInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb1, va, vb } => Instruction::SubInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb2, va, vb } => Instruction::MulInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb3, va, vb } => Instruction::DivInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb4, va, vb } => Instruction::RemInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb5, va, vb } => Instruction::AndInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb6, va, vb } => Instruction::OrInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb7, va, vb } => Instruction::XorInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb8, va, vb } => Instruction::ShlInt2Addr { dest: va, b: vb }, + Format12X { op: 0xb9, va, vb } => Instruction::ShrInt2Addr { dest: va, b: vb }, + Format12X { op: 0xba, va, vb } => Instruction::UshrInt2Addr { dest: va, b: vb }, + Format12X { op: 0xbb, va, vb } => Instruction::AddLong2Addr { dest: va, b: vb }, + Format12X { op: 0xbc, va, vb } => Instruction::SubLong2Addr { dest: va, b: vb }, + Format12X { op: 0xbd, va, vb } => Instruction::MulLong2Addr { dest: va, b: vb }, + Format12X { op: 0xbe, va, vb } => Instruction::DivLong2Addr { dest: va, b: vb }, + Format12X { op: 0xbf, va, vb } => Instruction::RemLong2Addr { dest: va, b: vb }, + Format12X { op: 0xc0, va, vb } => Instruction::AndLong2Addr { dest: va, b: vb }, + Format12X { op: 0xc1, va, vb } => Instruction::OrLong2Addr { dest: va, b: vb }, + Format12X { op: 0xc2, va, vb } => Instruction::XorLong2Addr { dest: va, b: vb }, + Format12X { op: 0xc3, va, vb } => Instruction::ShlLong2Addr { dest: va, b: vb }, + Format12X { op: 0xc4, va, vb } => Instruction::ShrLong2Addr { dest: va, b: vb }, + Format12X { op: 0xc5, va, vb } => Instruction::UshrLong2Addr { dest: va, b: vb }, + Format12X { op: 0xc6, va, vb } => Instruction::AddFloat2Addr { dest: va, b: vb }, + Format12X { op: 0xc7, va, vb } => Instruction::SubFloat2Addr { dest: va, b: vb }, + Format12X { op: 0xc8, va, vb } => Instruction::MulFloat2Addr { dest: va, b: vb }, + Format12X { op: 0xc9, va, vb } => Instruction::DivFloat2Addr { dest: va, b: vb }, + Format12X { op: 0xca, va, vb } => Instruction::RemFloat2Addr { dest: va, b: vb }, + Format12X { op: 0xcb, va, vb } => Instruction::AddDouble2Addr { dest: va, b: vb }, + Format12X { op: 0xcc, va, vb } => Instruction::SubDouble2Addr { dest: va, b: vb }, + Format12X { op: 0xcd, va, vb } => Instruction::MulDouble2Addr { dest: va, b: vb }, + Format12X { op: 0xce, va, vb } => Instruction::DivDouble2Addr { dest: va, b: vb }, + Format12X { op: 0xcf, va, vb } => Instruction::RemDouble2Addr { dest: va, b: vb }, Format22S { op: 0xd0, va, vb, c, - } => Instruction::AddIntLit(AddIntLit::new(va, vb, c)?), + } => Instruction::AddIntLit { + dest: va, + b: vb, + lit: c, + }, Format22S { op: 0xd1, va, vb, c, - } => Instruction::RsubIntLit(RsubIntLit::new(va, vb, c)?), + } => Instruction::RsubIntLit { + dest: va, + b: vb, + lit: c, + }, Format22S { op: 0xd2, va, vb, c, - } => Instruction::MulIntLit(MulIntLit::new(va, vb, c)?), + } => Instruction::MulIntLit { + dest: va, + b: vb, + lit: c, + }, Format22S { op: 0xd3, va, vb, c, - } => Instruction::DivIntLit(DivIntLit::new(va, vb, c)?), + } => Instruction::DivIntLit { + dest: va, + b: vb, + lit: c, + }, Format22S { op: 0xd4, va, vb, c, - } => Instruction::RemIntLit(RemIntLit::new(va, vb, c)?), + } => Instruction::RemIntLit { + dest: va, + b: vb, + lit: c, + }, Format22S { op: 0xd5, va, vb, c, - } => Instruction::AndIntLit(AndIntLit::new(va, vb, c)?), + } => Instruction::AndIntLit { + dest: va, + b: vb, + lit: c, + }, Format22S { op: 0xd6, va, vb, c, - } => Instruction::OrIntLit(OrIntLit::new(va, vb, c)?), + } => Instruction::OrIntLit { + dest: va, + b: vb, + lit: c, + }, Format22S { op: 0xd7, va, vb, c, - } => Instruction::XorIntLit(XorIntLit::new(va, vb, c)?), + } => Instruction::XorIntLit { + dest: va, + b: vb, + lit: c, + }, Format22B { op: 0xd8, va, vb, c, - } => Instruction::AddIntLit(AddIntLit::new(va, vb, c as i16)?), + } => Instruction::AddIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xd9, va, vb, c, - } => Instruction::RsubIntLit(RsubIntLit::new(va, vb, c as i16)?), + } => Instruction::RsubIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xda, va, vb, c, - } => Instruction::MulIntLit(MulIntLit::new(va, vb, c as i16)?), + } => Instruction::MulIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xdb, va, vb, c, - } => Instruction::DivIntLit(DivIntLit::new(va, vb, c as i16)?), + } => Instruction::DivIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xdc, va, vb, c, - } => Instruction::RemIntLit(RemIntLit::new(va, vb, c as i16)?), + } => Instruction::RemIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xdd, va, vb, c, - } => Instruction::AndIntLit(AndIntLit::new(va, vb, c as i16)?), + } => Instruction::AndIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xde, va, vb, c, - } => Instruction::OrIntLit(OrIntLit::new(va, vb, c as i16)?), + } => Instruction::OrIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xdf, va, vb, c, - } => Instruction::XorIntLit(XorIntLit::new(va, vb, c as i16)?), + } => Instruction::XorIntLit { + dest: va, + b: vb, + lit: c as i16, + }, Format22B { op: 0xe0, va, vb, c, - } => Instruction::ShlIntLit(ShlIntLit::new(va, vb, c)), + } => Instruction::ShlIntLit { + dest: va, + b: vb, + lit: c, + }, Format22B { op: 0xe1, va, vb, c, - } => Instruction::ShrIntLit(ShrIntLit::new(va, vb, c)), + } => Instruction::ShrIntLit { + dest: va, + b: vb, + lit: c, + }, Format22B { op: 0xe2, va, vb, c, - } => Instruction::UshrIntLit(UshrIntLit::new(va, vb, c)), + } => Instruction::UshrIntLit { + dest: va, + b: vb, + lit: c, + }, Format45CC { op: 0xfa, a, @@ -2154,7 +2524,11 @@ impl Apk { let proto = Self::get_id_method_type_from_idx(h as usize, dex)?; let args: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::InvokePolymorphic(InvokePolymorphic::new(meth, proto, args)?) + Instruction::InvokePolymorphic { + method: meth, + proto, + args, + } } Format4RCC { op: 0xfb, @@ -2166,7 +2540,11 @@ impl Apk { let meth = Self::get_id_method_from_idx(b as usize, dex)?; let proto = Self::get_id_method_type_from_idx(h as usize, dex)?; let args = (vc..vc + a as u16).collect(); - Instruction::InvokePolymorphic(InvokePolymorphic::new(meth, proto, args)?) + Instruction::InvokePolymorphic { + method: meth, + proto, + args, + } } Format35C { op: 0xfc, @@ -2181,20 +2559,23 @@ impl Apk { let call_site = Self::get_call_site_from_idx(b as usize, dex)?; let args: Vec<_> = [vc as u16, vd as u16, ve as u16, vf as u16, vg as u16][..a as usize].into(); - Instruction::InvokeCustom(InvokeCustom::new(call_site, args)?) + Instruction::InvokeCustom { call_site, args } } Format3RC { op: 0xfd, a, b, vc } => { let call_site = Self::get_call_site_from_idx(b as usize, dex)?; let args = (vc..vc + a as u16).collect(); - Instruction::InvokeCustom(InvokeCustom::new(call_site, args)?) + Instruction::InvokeCustom { call_site, args } } Format21C { op: 0xfe, va, b } => { let meth_handle = Self::get_method_handle_from_idx(b as usize, dex)?; - Instruction::ConstMethodHandle(ConstMethodHandle::new(va, meth_handle)) + Instruction::ConstMethodHandle { + to: va, + handle: meth_handle, + } } Format21C { op: 0xff, va, b } => { let proto = Self::get_id_method_type_from_idx(b as usize, dex)?; - Instruction::ConstMethodType(ConstMethodType::new(va, proto)) + Instruction::ConstMethodType { to: va, proto } } FormatPackedSwitchPayload { .. } => return Ok(None), //bail!("{format:?} is a pseudo instruction"), @@ -2204,13 +2585,14 @@ impl Apk { //bail!("{format:?} is a pseudo instruction"), _ => bail!("Unknwon instruction found at {addr}: {format:?}"), }; + ins.sanity_check() + .with_context(|| anyhow!("Invalid instruction {ins:?} found at {addr}: {format:?}"))?; Ok(Some((ins, labels))) } /// Return a [`Code`] from it's offset in the dex file. pub fn get_code_from_off(offset: u32, dex: &DexFileReader) -> Result { use crate::instructions::Instruction; - use crate::instructions::{Label, Try}; let code_item = dex.get_struct_at_offset::(offset)?; let debug_info = if code_item.debug_info_off == 0 { @@ -2293,7 +2675,11 @@ impl Apk { bail!("Label collision at 0x{dest_addr:08X}: {label_} and {end_label}"); } } - let try_ = Instruction::Try(Try::new(end_label, handlers_, default_handler)); + let try_ = Instruction::Try { + end_label, + handlers: 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:08X}: \ @@ -2333,7 +2719,7 @@ impl Apk { insns.push(try_); } if let Some(label) = labels.remove(&addr) { - insns.push(Instruction::Label(Label::new(label))); + insns.push(Instruction::Label { name: label }); } insns.push(ins); } @@ -2343,7 +2729,7 @@ impl Apk { insns.push(try_); } if let Some(label) = labels.remove(&addr) { - insns.push(Instruction::Label(Label::new(label))); + insns.push(Instruction::Label { name: label }); } if !labels.is_empty() { bail!("Could not put all label as instructions (label out of insns?)");