allow multiple label at the same address when parsing .dex
This commit is contained in:
parent
e2dc3381b6
commit
be5922a726
1 changed files with 36 additions and 142 deletions
|
|
@ -852,19 +852,20 @@ impl Apk {
|
|||
}
|
||||
|
||||
/// Convert an instruction format to an instruction.
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn instruction_format_to_instruction<F>(
|
||||
format: &InsFormat,
|
||||
addr: usize,
|
||||
insns_ref: &HashMap<usize, &InsFormat>,
|
||||
dex: &DexFileReader,
|
||||
label_ins: &mut F,
|
||||
) -> Result<Option<(instructions::Instruction, HashMap<usize, String>)>>
|
||||
) -> Result<Option<(instructions::Instruction, HashMap<usize, Vec<String>>)>>
|
||||
where
|
||||
F: FnMut(&instructions::Instruction, usize) -> Option<String>,
|
||||
{
|
||||
use crate::instructions::*;
|
||||
use InsFormat::*;
|
||||
let mut labels = HashMap::new();
|
||||
let mut labels = HashMap::<_, Vec<_>>::new();
|
||||
let ins = match format.clone() {
|
||||
Format10X { op: 0x00 } => Instruction::Nop {},
|
||||
Format12X { op: 0x01, va, vb } => Instruction::Move {
|
||||
|
|
@ -1037,12 +1038,7 @@ impl Apk {
|
|||
addr - (-(a as i64) as usize)
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::Goto { label }
|
||||
}
|
||||
Format20T { op: 0x29, a } => {
|
||||
|
|
@ -1055,12 +1051,7 @@ impl Apk {
|
|||
addr - (-(a as i64) as usize)
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::Goto { label }
|
||||
}
|
||||
Format30T { op: 0x2a, a } => {
|
||||
|
|
@ -1073,12 +1064,7 @@ impl Apk {
|
|||
addr - (-(a as i64) as usize)
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::Goto { label }
|
||||
}
|
||||
Format31T { op: 0x2b, va, b } => {
|
||||
|
|
@ -1110,15 +1096,7 @@ impl Apk {
|
|||
addr - (-(target as i64) as usize)
|
||||
};
|
||||
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:08X} with \
|
||||
an invalid name"
|
||||
);
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
branches.insert(key, label);
|
||||
key += 1;
|
||||
}
|
||||
|
|
@ -1164,15 +1142,7 @@ impl Apk {
|
|||
addr - (-target as usize)
|
||||
};
|
||||
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:08X} with \
|
||||
an invalid name"
|
||||
);
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
branches.insert(key, label);
|
||||
}
|
||||
Instruction::Switch { reg: va, branches }
|
||||
|
|
@ -1257,12 +1227,7 @@ impl Apk {
|
|||
addr - (-(c as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfEq {
|
||||
a: va,
|
||||
b: vb,
|
||||
|
|
@ -1287,12 +1252,7 @@ impl Apk {
|
|||
addr - (-(c as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfNe {
|
||||
a: va,
|
||||
b: vb,
|
||||
|
|
@ -1317,12 +1277,7 @@ impl Apk {
|
|||
addr - (-(c as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfLt {
|
||||
a: va,
|
||||
b: vb,
|
||||
|
|
@ -1347,12 +1302,7 @@ impl Apk {
|
|||
addr - (-(c as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfGe {
|
||||
a: va,
|
||||
b: vb,
|
||||
|
|
@ -1377,12 +1327,7 @@ impl Apk {
|
|||
addr - (-(c as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfGt {
|
||||
a: va,
|
||||
b: vb,
|
||||
|
|
@ -1407,12 +1352,7 @@ impl Apk {
|
|||
addr - (-(c as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfLe {
|
||||
a: va,
|
||||
b: vb,
|
||||
|
|
@ -1432,12 +1372,7 @@ impl Apk {
|
|||
addr - (-(b as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfEqZ { a: va, label }
|
||||
}
|
||||
Format21T { op: 0x39, va, b } => {
|
||||
|
|
@ -1453,12 +1388,7 @@ impl Apk {
|
|||
addr - (-(b as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfNeZ { a: va, label }
|
||||
}
|
||||
Format21T { op: 0x3a, va, b } => {
|
||||
|
|
@ -1474,12 +1404,7 @@ impl Apk {
|
|||
addr - (-(b as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfLtZ { a: va, label }
|
||||
}
|
||||
Format21T { op: 0x3b, va, b } => {
|
||||
|
|
@ -1495,12 +1420,7 @@ impl Apk {
|
|||
addr - (-(b as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfGeZ { a: va, label }
|
||||
}
|
||||
Format21T { op: 0x3c, va, b } => {
|
||||
|
|
@ -1516,12 +1436,7 @@ impl Apk {
|
|||
addr - (-(b as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfGtZ { a: va, label }
|
||||
}
|
||||
Format21T { op: 0x3d, va, b } => {
|
||||
|
|
@ -1537,12 +1452,7 @@ impl Apk {
|
|||
addr - (-(b as i64)) as usize
|
||||
};
|
||||
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:08X} with an invalid name");
|
||||
}
|
||||
}
|
||||
labels.entry(dest_addr).or_default().push(label.clone());
|
||||
Instruction::IfLeZ { a: va, label }
|
||||
}
|
||||
Format23X {
|
||||
|
|
@ -2666,7 +2576,7 @@ impl Apk {
|
|||
.with_context(|| anyhow!("Invalid instruction {ins:?} found at {addr}: {format:?}"))?;
|
||||
if let Some(label) = label_ins(&ins, addr) {
|
||||
//let label = format!("label_{addr:08X}");
|
||||
labels.insert(addr, label);
|
||||
labels.entry(addr).or_default().push(label);
|
||||
}
|
||||
|
||||
Ok(Some((ins, labels)))
|
||||
|
|
@ -2705,7 +2615,7 @@ impl Apk {
|
|||
} else {
|
||||
(DebugInfo::EndOfData, None)
|
||||
};
|
||||
let mut labels: HashMap<usize, String> = HashMap::new();
|
||||
let mut labels: HashMap<usize, Vec<String>> = HashMap::new();
|
||||
let mut tries = HashMap::new();
|
||||
for TryItem {
|
||||
start_addr,
|
||||
|
|
@ -2725,12 +2635,7 @@ impl Apk {
|
|||
.get_handler_at_offset(handler_off)?;
|
||||
let default_handler = if let Some(Uleb128(addr)) = *catch_all_addr {
|
||||
let label = format!("label_{addr:08X}");
|
||||
if let Some(label_) = labels.insert(addr as usize, label.clone()) {
|
||||
if label_ != label {
|
||||
// TODO: that's an internal error
|
||||
bail!("Label collision at 0x{addr:08X}: {label_} and {label}");
|
||||
}
|
||||
}
|
||||
labels.entry(addr as usize).or_default().push(label.clone());
|
||||
Some(label)
|
||||
} else {
|
||||
None
|
||||
|
|
@ -2742,22 +2647,15 @@ impl Apk {
|
|||
} in handlers.iter().cloned()
|
||||
{
|
||||
let label = format!("label_{addr:08X}");
|
||||
if let Some(label_) = labels.insert(addr as usize, label.clone()) {
|
||||
if label_ != label {
|
||||
// TODO: that's an internal error
|
||||
bail!("Label collision at 0x{addr:08X}: {label_} and {label}");
|
||||
}
|
||||
}
|
||||
labels.entry(addr as usize).or_default().push(label.clone());
|
||||
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: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}");
|
||||
}
|
||||
}
|
||||
labels
|
||||
.entry(dest_addr as usize)
|
||||
.or_default()
|
||||
.push(end_label.clone());
|
||||
let try_ = Instruction::Try {
|
||||
end_label,
|
||||
handlers: handlers_,
|
||||
|
|
@ -2789,14 +2687,6 @@ impl Apk {
|
|||
)? {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -2852,8 +2742,10 @@ impl Apk {
|
|||
if let Some(try_) = tries.remove(&addr) {
|
||||
insns.push(try_);
|
||||
}
|
||||
if let Some(label) = labels.remove(&addr) {
|
||||
insns.push(Instruction::Label { name: label });
|
||||
if let Some(label_l) = labels.remove(&addr) {
|
||||
for label in label_l.into_iter() {
|
||||
insns.push(Instruction::Label { name: label });
|
||||
}
|
||||
}
|
||||
insns.push(ins);
|
||||
}
|
||||
|
|
@ -2862,8 +2754,10 @@ impl Apk {
|
|||
if let Some(try_) = tries.remove(&addr) {
|
||||
insns.push(try_);
|
||||
}
|
||||
if let Some(label) = labels.remove(&addr) {
|
||||
insns.push(Instruction::Label { name: label });
|
||||
if let Some(label_l) = labels.remove(&addr) {
|
||||
for label in label_l.into_iter() {
|
||||
insns.push(Instruction::Label { name: label });
|
||||
}
|
||||
}
|
||||
if !labels.is_empty() {
|
||||
bail!("Could not put all label as instructions (label out of insns?)");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue