bug fix bug fix bug fix WIP
This commit is contained in:
parent
b30e91b86a
commit
b17a84212f
5 changed files with 153 additions and 151 deletions
|
|
@ -742,7 +742,7 @@ impl Apk {
|
||||||
addr: usize,
|
addr: usize,
|
||||||
insns_ref: &HashMap<usize, &InsFormat>,
|
insns_ref: &HashMap<usize, &InsFormat>,
|
||||||
dex: &DexFileReader,
|
dex: &DexFileReader,
|
||||||
) -> Result<(instructions::Instruction, HashMap<usize, String>)> {
|
) -> Result<Option<(instructions::Instruction, HashMap<usize, String>)>> {
|
||||||
use crate::instructions::*;
|
use crate::instructions::*;
|
||||||
use InsFormat::*;
|
use InsFormat::*;
|
||||||
let mut labels = HashMap::new();
|
let mut labels = HashMap::new();
|
||||||
|
|
@ -867,7 +867,7 @@ impl Apk {
|
||||||
} else {
|
} else {
|
||||||
bail!(
|
bail!(
|
||||||
"Found fill-array-data-payload v{va} +{b} at 0x{addr:x}, \
|
"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 {
|
} else {
|
||||||
addr - (-a as usize)
|
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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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))
|
Instruction::Goto(Goto::new(label))
|
||||||
|
|
@ -899,11 +899,11 @@ impl Apk {
|
||||||
} else {
|
} else {
|
||||||
addr - (-a as usize)
|
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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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))
|
Instruction::Goto(Goto::new(label))
|
||||||
|
|
@ -917,11 +917,11 @@ impl Apk {
|
||||||
} else {
|
} else {
|
||||||
addr - (-a as usize)
|
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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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))
|
Instruction::Goto(Goto::new(label))
|
||||||
|
|
@ -954,12 +954,12 @@ impl Apk {
|
||||||
} else {
|
} else {
|
||||||
addr - (-target as usize)
|
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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// TODO: internal error, panic?
|
||||||
bail!(
|
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"
|
an invalid name"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1008,12 +1008,12 @@ impl Apk {
|
||||||
} else {
|
} else {
|
||||||
addr - (-target as usize)
|
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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// TODO: internal error, panic?
|
||||||
bail!(
|
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"
|
an invalid name"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1079,13 +1079,13 @@ impl Apk {
|
||||||
let dest_addr = if c > 0 {
|
let dest_addr = if c > 0 {
|
||||||
addr + c as usize
|
addr + c as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfEq(IfEq::new(va, vb, label)?)
|
||||||
|
|
@ -1105,13 +1105,13 @@ impl Apk {
|
||||||
let dest_addr = if c > 0 {
|
let dest_addr = if c > 0 {
|
||||||
addr + c as usize
|
addr + c as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfNe(IfNe::new(va, vb, label)?)
|
||||||
|
|
@ -1131,13 +1131,13 @@ impl Apk {
|
||||||
let dest_addr = if c > 0 {
|
let dest_addr = if c > 0 {
|
||||||
addr + c as usize
|
addr + c as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfLt(IfLt::new(va, vb, label)?)
|
||||||
|
|
@ -1157,13 +1157,13 @@ impl Apk {
|
||||||
let dest_addr = if c > 0 {
|
let dest_addr = if c > 0 {
|
||||||
addr + c as usize
|
addr + c as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfGe(IfGe::new(va, vb, label)?)
|
||||||
|
|
@ -1183,13 +1183,13 @@ impl Apk {
|
||||||
let dest_addr = if c > 0 {
|
let dest_addr = if c > 0 {
|
||||||
addr + c as usize
|
addr + c as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfGt(IfGt::new(va, vb, label)?)
|
||||||
|
|
@ -1209,13 +1209,13 @@ impl Apk {
|
||||||
let dest_addr = if c > 0 {
|
let dest_addr = if c > 0 {
|
||||||
addr + c as usize
|
addr + c as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfLe(IfLe::new(va, vb, label)?)
|
||||||
|
|
@ -1230,13 +1230,13 @@ impl Apk {
|
||||||
let dest_addr = if b > 0 {
|
let dest_addr = if b > 0 {
|
||||||
addr + b as usize
|
addr + b as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfEqZ(IfEqZ::new(va, label)?)
|
||||||
|
|
@ -1251,13 +1251,13 @@ impl Apk {
|
||||||
let dest_addr = if b > 0 {
|
let dest_addr = if b > 0 {
|
||||||
addr + b as usize
|
addr + b as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfNeZ(IfNeZ::new(va, label)?)
|
||||||
|
|
@ -1272,13 +1272,13 @@ impl Apk {
|
||||||
let dest_addr = if b > 0 {
|
let dest_addr = if b > 0 {
|
||||||
addr + b as usize
|
addr + b as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfLtZ(IfLtZ::new(va, label)?)
|
||||||
|
|
@ -1293,13 +1293,13 @@ impl Apk {
|
||||||
let dest_addr = if b > 0 {
|
let dest_addr = if b > 0 {
|
||||||
addr + b as usize
|
addr + b as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfGeZ(IfGeZ::new(va, label)?)
|
||||||
|
|
@ -1314,13 +1314,13 @@ impl Apk {
|
||||||
let dest_addr = if b > 0 {
|
let dest_addr = if b > 0 {
|
||||||
addr + b as usize
|
addr + b as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
Instruction::IfGtZ(IfGtZ::new(va, label)?)
|
||||||
|
|
@ -1335,13 +1335,13 @@ impl Apk {
|
||||||
let dest_addr = if b > 0 {
|
let dest_addr = if b > 0 {
|
||||||
addr + b as usize
|
addr + b as usize
|
||||||
} else {
|
} 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 let Some(old_label) = labels.insert(dest_addr, label.clone()) {
|
||||||
if old_label != label {
|
if old_label != label {
|
||||||
// TODO: internal error, panic?
|
// 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)?)
|
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)?;
|
let proto = Self::get_id_method_type_from_idx(b as usize, dex)?;
|
||||||
Instruction::ConstMethodType(ConstMethodType::new(va, proto))
|
Instruction::ConstMethodType(ConstMethodType::new(va, proto))
|
||||||
}
|
}
|
||||||
FormatPackedSwitchPayload { .. } => bail!("{format:?} is a pseudo instruction"),
|
FormatPackedSwitchPayload { .. } => return Ok(None),
|
||||||
FormatSparseSwitchPayload { .. } => bail!("{format:?} is a pseudo instruction"),
|
//bail!("{format:?} is a pseudo instruction"),
|
||||||
FormatFillArrayDataPayload { .. } => 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:?}"),
|
_ => 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.
|
/// Return a [`Code`] from it's offset in the dex file.
|
||||||
|
|
@ -2192,10 +2195,11 @@ impl Apk {
|
||||||
))?
|
))?
|
||||||
.get_handler_at_offset(handler_off)?;
|
.get_handler_at_offset(handler_off)?;
|
||||||
let default_handler = if let Some(Uleb128(addr)) = *catch_all_addr {
|
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 let Some(label_) = labels.insert(addr as usize, label.clone()) {
|
||||||
if label_ != label {
|
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)
|
Some(label)
|
||||||
|
|
@ -2208,20 +2212,27 @@ impl Apk {
|
||||||
addr: Uleb128(addr),
|
addr: Uleb128(addr),
|
||||||
} in handlers.iter().cloned()
|
} 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 let Some(label_) = labels.insert(addr as usize, label.clone()) {
|
||||||
if label_ != label {
|
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))
|
handlers_.push((Self::get_id_type_from_idx(type_idx as usize, dex)?, label))
|
||||||
}
|
}
|
||||||
let dest_addr = start_addr + insn_count as u32;
|
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));
|
let try_ = Instruction::Try(Try::new(end_label, handlers_, default_handler));
|
||||||
if let Some(try__) = tries.insert(start_addr as usize, try_.clone()) {
|
if let Some(try__) = tries.insert(start_addr as usize, try_.clone()) {
|
||||||
bail!(
|
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_:?}"
|
{try__:?}, {try_:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -2231,25 +2242,27 @@ impl Apk {
|
||||||
let mut addr = 0;
|
let mut addr = 0;
|
||||||
for ins_f in &code_item.insns {
|
for ins_f in &code_item.insns {
|
||||||
instructions_raw.insert(addr, ins_f);
|
instructions_raw.insert(addr, ins_f);
|
||||||
addr += ins_f.size();
|
addr += ins_f.size() / 2;
|
||||||
}
|
}
|
||||||
let mut instructions = vec![];
|
let mut instructions = vec![];
|
||||||
addr = 0;
|
addr = 0;
|
||||||
for ins_f in &code_item.insns {
|
for ins_f in &code_item.insns {
|
||||||
let (ins, ins_labels) =
|
if let Some((ins, ins_labels)) =
|
||||||
Self::instruction_format_to_instruction(ins_f, addr, &instructions_raw, dex)?;
|
Self::instruction_format_to_instruction(ins_f, addr, &instructions_raw, dex)?
|
||||||
|
{
|
||||||
instructions.push((addr, ins));
|
instructions.push((addr, ins));
|
||||||
addr += ins_f.size() / 2;
|
addr += ins_f.size() / 2;
|
||||||
for (key, val) in &ins_labels {
|
for (key, val) in &ins_labels {
|
||||||
if let Some(val_) = ins_labels.get(key) {
|
if let Some(val_) = ins_labels.get(key) {
|
||||||
if val_ != val {
|
if val_ != val {
|
||||||
// TODO: internal error, panic?
|
// TODO: internal error, panic?
|
||||||
bail!("Label collision at 0x{key:80X}: {val_} and {val}");
|
bail!("Label collision at 0x{key:08X}: {val_} and {val}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
labels.extend(ins_labels);
|
labels.extend(ins_labels);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let mut insns = vec![];
|
let mut insns = vec![];
|
||||||
for (addr, ins) in instructions {
|
for (addr, ins) in instructions {
|
||||||
if let Some(try_) = tries.remove(&addr) {
|
if let Some(try_) = tries.remove(&addr) {
|
||||||
|
|
@ -2260,6 +2273,20 @@ impl Apk {
|
||||||
}
|
}
|
||||||
insns.push(ins);
|
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 {
|
Ok(Code {
|
||||||
registers_size: code_item.registers_size,
|
registers_size: code_item.registers_size,
|
||||||
ins_size: code_item.ins_size,
|
ins_size: code_item.ins_size,
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,6 @@ impl DexWriter {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Estimate instructions addresses
|
// Estimate instructions addresses
|
||||||
let mut min_addr = 0;
|
let mut min_addr = 0;
|
||||||
let mut max_addr = 0;
|
let mut max_addr = 0;
|
||||||
|
|
@ -1226,7 +1225,8 @@ impl DexWriter {
|
||||||
let try_item = TryItem {
|
let try_item = TryItem {
|
||||||
start_addr: addr as u32,
|
start_addr: addr as u32,
|
||||||
insn_count: (end_block_addr - addr) as u16,
|
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);
|
tries.push(try_item);
|
||||||
let mut catches = EncodedCatchHandler {
|
let mut catches = EncodedCatchHandler {
|
||||||
|
|
@ -1279,6 +1279,10 @@ impl DexWriter {
|
||||||
}
|
}
|
||||||
insns.extend(payloads);
|
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() {
|
let debug_info_off = if code.debug_info.is_empty() {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -8009,21 +8009,9 @@ impl IfEqZ {
|
||||||
#[new]
|
#[new]
|
||||||
pub fn new(a: u8, label: String) -> Result<Self> {
|
pub fn new(a: u8, label: String) -> Result<Self> {
|
||||||
let ins = Self { a, label };
|
let ins = Self { a, label };
|
||||||
ins.sanity_check()?;
|
|
||||||
Ok(ins)
|
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 {
|
pub fn __str__(&self) -> String {
|
||||||
format!("if-eqz {} {}", self.a, self.label)
|
format!("if-eqz {} {}", self.a, self.label)
|
||||||
}
|
}
|
||||||
|
|
@ -8122,21 +8110,9 @@ impl IfNeZ {
|
||||||
#[new]
|
#[new]
|
||||||
pub fn new(a: u8, label: String) -> Result<Self> {
|
pub fn new(a: u8, label: String) -> Result<Self> {
|
||||||
let ins = Self { a, label };
|
let ins = Self { a, label };
|
||||||
ins.sanity_check()?;
|
|
||||||
Ok(ins)
|
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 {
|
pub fn __str__(&self) -> String {
|
||||||
format!("if-neq {} {}", self.a, self.label)
|
format!("if-neq {} {}", self.a, self.label)
|
||||||
}
|
}
|
||||||
|
|
@ -8235,21 +8211,9 @@ impl IfLtZ {
|
||||||
#[new]
|
#[new]
|
||||||
pub fn new(a: u8, label: String) -> Result<Self> {
|
pub fn new(a: u8, label: String) -> Result<Self> {
|
||||||
let ins = Self { a, label };
|
let ins = Self { a, label };
|
||||||
ins.sanity_check()?;
|
|
||||||
Ok(ins)
|
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 {
|
pub fn __str__(&self) -> String {
|
||||||
format!("if-lt {} {}", self.a, self.label)
|
format!("if-lt {} {}", self.a, self.label)
|
||||||
}
|
}
|
||||||
|
|
@ -8348,21 +8312,9 @@ impl IfGeZ {
|
||||||
#[new]
|
#[new]
|
||||||
pub fn new(a: u8, label: String) -> Result<Self> {
|
pub fn new(a: u8, label: String) -> Result<Self> {
|
||||||
let ins = Self { a, label };
|
let ins = Self { a, label };
|
||||||
ins.sanity_check()?;
|
|
||||||
Ok(ins)
|
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 {
|
pub fn __str__(&self) -> String {
|
||||||
format!("if-ge {} {}", self.a, self.label)
|
format!("if-ge {} {}", self.a, self.label)
|
||||||
}
|
}
|
||||||
|
|
@ -8461,21 +8413,9 @@ impl IfGtZ {
|
||||||
#[new]
|
#[new]
|
||||||
pub fn new(a: u8, label: String) -> Result<Self> {
|
pub fn new(a: u8, label: String) -> Result<Self> {
|
||||||
let ins = Self { a, label };
|
let ins = Self { a, label };
|
||||||
ins.sanity_check()?;
|
|
||||||
Ok(ins)
|
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 {
|
pub fn __str__(&self) -> String {
|
||||||
format!("if-gt {} {}", self.a, self.label)
|
format!("if-gt {} {}", self.a, self.label)
|
||||||
}
|
}
|
||||||
|
|
@ -8574,21 +8514,9 @@ impl IfLeZ {
|
||||||
#[new]
|
#[new]
|
||||||
pub fn new(a: u8, label: String) -> Result<Self> {
|
pub fn new(a: u8, label: String) -> Result<Self> {
|
||||||
let ins = Self { a, label };
|
let ins = Self { a, label };
|
||||||
ins.sanity_check()?;
|
|
||||||
Ok(ins)
|
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 {
|
pub fn __str__(&self) -> String {
|
||||||
format!("if-le {} {}", self.a, self.label)
|
format!("if-le {} {}", self.a, self.label)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,16 @@ impl CodeItem {
|
||||||
pub fn sanity_check(&self) -> Result<()> {
|
pub fn sanity_check(&self) -> Result<()> {
|
||||||
if self.tries.is_empty() && self.handlers.is_some() {
|
if self.tries.is_empty() && self.handlers.is_some() {
|
||||||
return Err(Error::InconsistantStruct(
|
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() {
|
if !self.tries.is_empty() && self.handlers.is_none() {
|
||||||
return Err(Error::InconsistantStruct(
|
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;
|
let mut max_addr = 0;
|
||||||
|
|
@ -48,7 +52,9 @@ impl CodeItem {
|
||||||
let addr = item.start_addr;
|
let addr = item.start_addr;
|
||||||
if addr < max_addr {
|
if addr < max_addr {
|
||||||
return Err(Error::InconsistantStruct(
|
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);
|
max_addr = addr + (item.insn_count as u32);
|
||||||
|
|
@ -121,8 +127,10 @@ impl CodeItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if i < addresses.len() && addresses[i] < addr {
|
if i < addresses.len() && addresses[i] < addr {
|
||||||
|
println!("{addresses:x?}");
|
||||||
return Err(Error::InconsistantStruct(format!(
|
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 insns = vec![];
|
||||||
let mut serialized_insns_size = 0;
|
let mut serialized_insns_size = 0;
|
||||||
while serialized_insns_size != insns_size {
|
while serialized_insns_size < insns_size {
|
||||||
let ins = Instruction::deserialize(input)?;
|
let ins = Instruction::deserialize(input).map_err(|err| {
|
||||||
serialized_insns_size += ins.size() as u32;
|
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);
|
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 {
|
if tries_size != 0 && insns_size % 2 == 1 {
|
||||||
let _ = u16::deserialize(input)?;
|
let _ = u16::deserialize(input)?;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +283,8 @@ impl EncodedCatchHandlerList {
|
||||||
current_offset += handler.size();
|
current_offset += handler.size();
|
||||||
}
|
}
|
||||||
Err(Error::InconsistantStruct(format!(
|
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"
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -389,8 +389,11 @@ impl Instruction {
|
||||||
requires the first byte to be 0 found {v}"
|
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_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::from_be_bytes([a_h0, a_h1, a_l0, a_l1]);
|
||||||
|
*/
|
||||||
|
let a = i32::deserialize(input)?;
|
||||||
Ok(Self::Format30T { op, a })
|
Ok(Self::Format30T { op, a })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -412,24 +415,33 @@ impl Instruction {
|
||||||
pub fn deserialize_31i(input: &mut dyn ReadSeek) -> Result<Self> {
|
pub fn deserialize_31i(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
let op = u8::deserialize(input)?;
|
let op = u8::deserialize(input)?;
|
||||||
let va = 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_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]);
|
let b = i32::from_be_bytes([b_h0, b_h1, b_l0, b_l1]);
|
||||||
|
*/
|
||||||
Ok(Self::Format31I { va, op, b })
|
Ok(Self::Format31I { va, op, b })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_31t(input: &mut dyn ReadSeek) -> Result<Self> {
|
pub fn deserialize_31t(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
let op = u8::deserialize(input)?;
|
let op = u8::deserialize(input)?;
|
||||||
let va = 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_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]);
|
let b = i32::from_be_bytes([b_h0, b_h1, b_l0, b_l1]);
|
||||||
|
*/
|
||||||
Ok(Self::Format31T { va, op, b })
|
Ok(Self::Format31T { va, op, b })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_31c(input: &mut dyn ReadSeek) -> Result<Self> {
|
pub fn deserialize_31c(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
let op = u8::deserialize(input)?;
|
let op = u8::deserialize(input)?;
|
||||||
let va = 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_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]);
|
let b = u32::from_be_bytes([b_h0, b_h1, b_l0, b_l1]);
|
||||||
|
*/
|
||||||
Ok(Self::Format31C { va, op, b })
|
Ok(Self::Format31C { va, op, b })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -824,8 +836,11 @@ impl Serializable for Instruction {
|
||||||
Self::Format30T { op, a } => {
|
Self::Format30T { op, a } => {
|
||||||
op.serialize(output)?;
|
op.serialize(output)?;
|
||||||
0u8.serialize(output)?;
|
0u8.serialize(output)?;
|
||||||
|
/*
|
||||||
let [a_h0, a_h1, a_l0, a_l1] = a.to_be_bytes();
|
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)
|
u32::from_be_bytes([a_l0, a_l1, a_h0, a_h1]).serialize(output)
|
||||||
|
*/
|
||||||
|
a.serialize(output)
|
||||||
}
|
}
|
||||||
Self::Format32X { op, va, vb } => {
|
Self::Format32X { op, va, vb } => {
|
||||||
op.serialize(output)?;
|
op.serialize(output)?;
|
||||||
|
|
@ -836,20 +851,29 @@ impl Serializable for Instruction {
|
||||||
Self::Format31I { va, op, b } => {
|
Self::Format31I { va, op, b } => {
|
||||||
op.serialize(output)?;
|
op.serialize(output)?;
|
||||||
va.serialize(output)?;
|
va.serialize(output)?;
|
||||||
|
/*
|
||||||
let [b_h0, b_h1, b_l0, b_l1] = b.to_be_bytes();
|
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)
|
u32::from_be_bytes([b_l0, b_l1, b_h0, b_h1]).serialize(output)
|
||||||
|
*/
|
||||||
|
b.serialize(output)
|
||||||
}
|
}
|
||||||
Self::Format31T { va, op, b } => {
|
Self::Format31T { va, op, b } => {
|
||||||
op.serialize(output)?;
|
op.serialize(output)?;
|
||||||
va.serialize(output)?;
|
va.serialize(output)?;
|
||||||
|
/*
|
||||||
let [b_h0, b_h1, b_l0, b_l1] = b.to_be_bytes();
|
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)
|
u32::from_be_bytes([b_l0, b_l1, b_h0, b_h1]).serialize(output)
|
||||||
|
*/
|
||||||
|
b.serialize(output)
|
||||||
}
|
}
|
||||||
Self::Format31C { va, op, b } => {
|
Self::Format31C { va, op, b } => {
|
||||||
op.serialize(output)?;
|
op.serialize(output)?;
|
||||||
va.serialize(output)?;
|
va.serialize(output)?;
|
||||||
|
/*
|
||||||
let [b_h0, b_h1, b_l0, b_l1] = b.to_be_bytes();
|
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)
|
u32::from_be_bytes([b_l0, b_l1, b_h0, b_h1]).serialize(output)
|
||||||
|
*/
|
||||||
|
b.serialize(output)
|
||||||
}
|
}
|
||||||
Self::Format35C {
|
Self::Format35C {
|
||||||
a,
|
a,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue