WIP
This commit is contained in:
parent
b72fd67b7d
commit
cfbd3fb90b
2 changed files with 617 additions and 632 deletions
|
|
@ -438,18 +438,17 @@ impl DexWriter {
|
||||||
|
|
||||||
for ins in &code.insns {
|
for ins in &code.insns {
|
||||||
match ins {
|
match ins {
|
||||||
Instruction::Label(Label { name }) => {
|
Instruction::Label { name } => {
|
||||||
label_min_max_addrs.insert(name.clone(), (min_addr, max_addr));
|
label_min_max_addrs.insert(name.clone(), (min_addr, max_addr));
|
||||||
min_addr += ins.min_ins_size() / 2;
|
min_addr += ins.min_ins_size() / 2;
|
||||||
max_addr += ins.max_ins_size() / 2;
|
max_addr += ins.max_ins_size() / 2;
|
||||||
}
|
}
|
||||||
Instruction::ConstString(ins) => {
|
Instruction::ConstString { .. } => {
|
||||||
let string_idx = self.strings.get(&ins.lit).ok_or(anyhow!(
|
let size = ins
|
||||||
"String {} (found in code of {}) not found in dex builder",
|
.get_raw_ins(Some(&self.strings))
|
||||||
ins.lit.__repr__(),
|
.with_context(|| format!("In code of {}", method_id.__repr__()))?
|
||||||
method_id.__repr__()
|
.size()
|
||||||
))?;
|
/ 2;
|
||||||
let size = ins.get_raw_ins(*string_idx).size() / 2;
|
|
||||||
min_addr += size;
|
min_addr += size;
|
||||||
max_addr += size;
|
max_addr += size;
|
||||||
}
|
}
|
||||||
|
|
@ -465,23 +464,23 @@ impl DexWriter {
|
||||||
let mut goto_sizes = vec![];
|
let mut goto_sizes = vec![];
|
||||||
for ins in &code.insns {
|
for ins in &code.insns {
|
||||||
match ins {
|
match ins {
|
||||||
Instruction::Label(Label { name }) => {
|
Instruction::Label { name } => {
|
||||||
label_addrs.insert(name.clone(), addr);
|
label_addrs.insert(name.clone(), addr);
|
||||||
addr += ins.max_ins_size() / 2;
|
addr += ins.max_ins_size() / 2;
|
||||||
}
|
}
|
||||||
Instruction::ConstString(ins) => {
|
Instruction::ConstString { .. } => {
|
||||||
let string_idx = self.strings.get(&ins.lit).ok_or(anyhow!(
|
addr += ins.get_raw_ins(Some(&self.strings, None))?.size() / 2;
|
||||||
"String {} (found in code of {}) not found in dex builder",
|
// should not fail after
|
||||||
ins.lit.__repr__(),
|
// first loop, no need
|
||||||
method_id.__repr__()
|
// for context
|
||||||
))?;
|
|
||||||
addr += ins.get_raw_ins(*string_idx).size() / 2;
|
|
||||||
}
|
}
|
||||||
Instruction::Goto(Goto { label }) => {
|
Instruction::Goto { label } => {
|
||||||
let (min_addr, max_addr) = label_min_max_addrs
|
let (min_addr, max_addr) = label_min_max_addrs
|
||||||
.get(label)
|
.get(label)
|
||||||
.ok_or(anyhow!("Label {label} not found in label estimation map"))?;
|
.ok_or(anyhow!("Label {label} not found in label estimation map"))?;
|
||||||
let size = Goto::size_from_branch_offset_interval(addr, *min_addr, *max_addr)?;
|
let size = Instruction::goto_size_from_branch_offset_interval(
|
||||||
|
addr, *min_addr, *max_addr,
|
||||||
|
)?;
|
||||||
goto_sizes.push(size);
|
goto_sizes.push(size);
|
||||||
addr += size / 2;
|
addr += size / 2;
|
||||||
}
|
}
|
||||||
|
|
@ -502,86 +501,20 @@ impl DexWriter {
|
||||||
addr = 0;
|
addr = 0;
|
||||||
for ins in &code.insns {
|
for ins in &code.insns {
|
||||||
match ins {
|
match ins {
|
||||||
Instruction::ConstString(ins) => {
|
Instruction::FillArrayData {
|
||||||
let string_idx = self.strings.get(&ins.lit).ok_or(anyhow!(
|
data,
|
||||||
"String {} (found in code of {}) not found in dex builder",
|
elt_width,
|
||||||
ins.lit.__repr__(),
|
arr,
|
||||||
method_id.__repr__()
|
} => {
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*string_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::ConstClass(ins) => {
|
|
||||||
let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!(
|
|
||||||
"Class {} (type of class found in code of {}) not found in dex builder",
|
|
||||||
ins.lit.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(class_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::CheckCast(ins) => {
|
|
||||||
let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!(
|
|
||||||
"Class {} (type of class found in code of {}) not found in dex builder",
|
|
||||||
ins.lit.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(class_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::InstanceOf(ins) => {
|
|
||||||
let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!(
|
|
||||||
"Class {} (type of class found in code of {}) not found in dex builder",
|
|
||||||
ins.lit.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(class_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::NewInstance(ins) => {
|
|
||||||
let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!(
|
|
||||||
"Class {} (type of class found in code of {}) not found in dex builder",
|
|
||||||
ins.lit.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(class_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::NewArray(ins) => {
|
|
||||||
let class_idx = *self.type_ids.get(&ins.lit).ok_or(anyhow!(
|
|
||||||
"Type {} (type found in code of {}) not found in dex builder",
|
|
||||||
ins.lit.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(class_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::FilledNewArray(ins) => {
|
|
||||||
let class_idx = *self.type_ids.get(&ins.type_).ok_or(anyhow!(
|
|
||||||
"Type {} (type found in code of {}) not found in dex builder",
|
|
||||||
ins.type_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(class_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::FillArrayData(ins) => {
|
|
||||||
let payload = InsFormat::FormatFillArrayDataPayload {
|
let payload = InsFormat::FormatFillArrayDataPayload {
|
||||||
elt_width: ins.elt_width,
|
elt_width: *elt_width,
|
||||||
data: ins.data.clone(),
|
data: data.clone(),
|
||||||
};
|
};
|
||||||
if payload_addr % 2 != 0 {
|
if payload_addr % 2 != 0 {
|
||||||
// https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/verifier/method_verifier.cc;drc=e8c3e7be783937a340cd4f3280b69962d6f1ea0c;l=1347
|
// https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/verifier/method_verifier.cc;drc=e8c3e7be783937a340cd4f3280b69962d6f1ea0c;l=1347
|
||||||
// The ART check if the array data table is 4 bytes aligned (= 2 ins alligned)
|
// The ART check if the array data table is 4 bytes aligned (= 2 ins alligned)
|
||||||
// TODO: check how it is donne in android and other dex generation code.
|
// TODO: check how it is donne in android and other dex generation code.
|
||||||
let nop = (Instruction::Nop {}).get_raw_ins()?;
|
let nop = (Instruction::Nop {}).get_raw_ins(None, None)?;
|
||||||
payload_addr += nop.size() / 2;
|
payload_addr += nop.size() / 2;
|
||||||
payloads.push(nop);
|
payloads.push(nop);
|
||||||
}
|
}
|
||||||
|
|
@ -1372,15 +1305,17 @@ impl DexWriter {
|
||||||
handler_off += catches.size();
|
handler_off += catches.size();
|
||||||
handlers.list.push(catches);
|
handlers.list.push(catches);
|
||||||
}
|
}
|
||||||
Instruction::Label(_) => (),
|
Instruction::Label { .. } => (),
|
||||||
_ => {
|
_ => {
|
||||||
let ins = ins.get_raw_ins().with_context(|| {
|
let ins = ins
|
||||||
format!(
|
.get_raw_ins(Some(&self.strings), Some(&self.type_ids))
|
||||||
|
.with_context(|| {
|
||||||
|
format!(
|
||||||
"Failed to convert instruction {} (found in code of {}) to raw instruction",
|
"Failed to convert instruction {} (found in code of {}) to raw instruction",
|
||||||
ins.__repr__(),
|
ins.__repr__(),
|
||||||
method_id.__repr__()
|
method_id.__repr__()
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
addr += ins.size() / 2;
|
addr += ins.size() / 2;
|
||||||
insns.push(ins);
|
insns.push(ins);
|
||||||
}
|
}
|
||||||
|
|
@ -1388,7 +1323,7 @@ impl DexWriter {
|
||||||
}
|
}
|
||||||
if addr % 2 != 0 {
|
if addr % 2 != 0 {
|
||||||
// make sure the payload section is 4 bytes aligned
|
// make sure the payload section is 4 bytes aligned
|
||||||
let nop = (Instruction::Nop {}).get_raw_ins()?;
|
let nop = (Instruction::Nop {}).get_raw_ins(None, None)?;
|
||||||
//addr += nop.size() / 2;
|
//addr += nop.size() / 2;
|
||||||
insns.push(nop);
|
insns.push(nop);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue