WIP
This commit is contained in:
parent
cfbd3fb90b
commit
920cc181dc
2 changed files with 2473 additions and 1270 deletions
|
|
@ -445,7 +445,7 @@ impl DexWriter {
|
||||||
}
|
}
|
||||||
Instruction::ConstString { .. } => {
|
Instruction::ConstString { .. } => {
|
||||||
let size = ins
|
let size = ins
|
||||||
.get_raw_ins(Some(&self.strings))
|
.get_raw_ins(Some(&self.strings), None, None, None, None, None)
|
||||||
.with_context(|| format!("In code of {}", method_id.__repr__()))?
|
.with_context(|| format!("In code of {}", method_id.__repr__()))?
|
||||||
.size()
|
.size()
|
||||||
/ 2;
|
/ 2;
|
||||||
|
|
@ -469,7 +469,10 @@ impl DexWriter {
|
||||||
addr += ins.max_ins_size() / 2;
|
addr += ins.max_ins_size() / 2;
|
||||||
}
|
}
|
||||||
Instruction::ConstString { .. } => {
|
Instruction::ConstString { .. } => {
|
||||||
addr += ins.get_raw_ins(Some(&self.strings, None))?.size() / 2;
|
addr += ins
|
||||||
|
.get_raw_ins(Some(&self.strings), None, None, None, None, None)?
|
||||||
|
.size()
|
||||||
|
/ 2;
|
||||||
// should not fail after
|
// should not fail after
|
||||||
// first loop, no need
|
// first loop, no need
|
||||||
// for context
|
// for context
|
||||||
|
|
@ -514,33 +517,35 @@ impl DexWriter {
|
||||||
// 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(None, None)?;
|
let nop = (Instruction::Nop {})
|
||||||
|
.get_raw_ins(None, None, None, None, None, None)?;
|
||||||
payload_addr += nop.size() / 2;
|
payload_addr += nop.size() / 2;
|
||||||
payloads.push(nop);
|
payloads.push(nop);
|
||||||
}
|
}
|
||||||
let data_offset = payload_addr as i32 - addr as i32;
|
let data_offset = payload_addr as i32 - addr as i32;
|
||||||
payload_addr += payload.size() / 2;
|
payload_addr += payload.size() / 2;
|
||||||
payloads.push(payload);
|
payloads.push(payload);
|
||||||
let ins = ins.get_raw_ins(data_offset);
|
let ins = ins.get_raw_ins(None, None, None, None, None, Some(data_offset))?;
|
||||||
addr += ins.size() / 2;
|
addr += ins.size() / 2;
|
||||||
insns.push(ins);
|
insns.push(ins);
|
||||||
}
|
}
|
||||||
Instruction::Goto(ins) => {
|
Instruction::Goto { .. } => {
|
||||||
let goto_size = goto_sizes[goto_idx];
|
let goto_size = goto_sizes[goto_idx];
|
||||||
goto_idx += 1;
|
goto_idx += 1;
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
let ins = ins.get_raw_ins(
|
||||||
"Label {} not found in code of {}, but found goto with this label",
|
None,
|
||||||
ins.label,
|
None,
|
||||||
method_id.__repr__()
|
None,
|
||||||
))?;
|
Some((addr, &label_addrs)),
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
Some(goto_size),
|
||||||
let ins = ins.get_raw_ins(branch_offset, goto_size);
|
None,
|
||||||
|
)?;
|
||||||
addr += ins.size() / 2;
|
addr += ins.size() / 2;
|
||||||
insns.push(ins);
|
insns.push(ins);
|
||||||
}
|
}
|
||||||
Instruction::Switch(ins) => {
|
Instruction::Switch { branches, .. } => {
|
||||||
let mut key_targets = vec![];
|
let mut key_targets = vec![];
|
||||||
for (key, label) in &ins.branches {
|
for (key, label) in branches {
|
||||||
let label_addr = label_addrs.get(label).ok_or(anyhow!(
|
let label_addr = label_addrs.get(label).ok_or(anyhow!(
|
||||||
"Label {} not found in code of {}, but found goto with this label",
|
"Label {} not found in code of {}, but found goto with this label",
|
||||||
label,
|
label,
|
||||||
|
|
@ -550,7 +555,7 @@ impl DexWriter {
|
||||||
key_targets.push((*key, branch_offset));
|
key_targets.push((*key, branch_offset));
|
||||||
}
|
}
|
||||||
key_targets.sort_by_key(|(key, _)| *key);
|
key_targets.sort_by_key(|(key, _)| *key);
|
||||||
let payload = if ins.is_packed() {
|
let payload = if ins.is_packed()? {
|
||||||
let (first_key, _) = *key_targets.first().ok_or(anyhow!(
|
let (first_key, _) = *key_targets.first().ok_or(anyhow!(
|
||||||
"Found empty swith in code of {}",
|
"Found empty swith in code of {}",
|
||||||
method_id.__repr__()
|
method_id.__repr__()
|
||||||
|
|
@ -565,554 +570,15 @@ impl DexWriter {
|
||||||
// https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/verifier/method_verifier.cc;drc=e8c3e7be783937a340cd4f3280b69962d6f1ea0c;l=1464
|
// https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/verifier/method_verifier.cc;drc=e8c3e7be783937a340cd4f3280b69962d6f1ea0c;l=1464
|
||||||
// The ART check if the switch table is 4 bytes aligned (= 2 ins alligned)
|
// The ART check if the switch 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, None, None, None, None)?;
|
||||||
payload_addr += nop.size() / 2;
|
payload_addr += nop.size() / 2;
|
||||||
payloads.push(nop);
|
payloads.push(nop);
|
||||||
}
|
}
|
||||||
let data_offset = payload_addr as i32 - addr as i32;
|
let data_offset = payload_addr as i32 - addr as i32;
|
||||||
payload_addr += payload.size() / 2;
|
payload_addr += payload.size() / 2;
|
||||||
payloads.push(payload);
|
payloads.push(payload);
|
||||||
let ins = ins.get_raw_ins(data_offset);
|
let ins = ins.get_raw_ins(None, None, None, None, None, Some(data_offset))?;
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfEq(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfNe(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfLt(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfGe(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfGt(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfLe(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfEqZ(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfNeZ(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfLtZ(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfGeZ(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfGtZ(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IfLeZ(ins) => {
|
|
||||||
let label_addr = label_addrs.get(&ins.label).ok_or(anyhow!(
|
|
||||||
"Label {} not found in code of {}, but found if with this label",
|
|
||||||
ins.label,
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let branch_offset = *label_addr as i32 - addr as i32;
|
|
||||||
if branch_offset > i16::MAX as i32 || branch_offset < i16::MIN as i32 {
|
|
||||||
bail!(
|
|
||||||
"Found an if that jump to far from the instruction in code of {}",
|
|
||||||
method_id.__repr__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let ins = ins.get_raw_ins(branch_offset as i16);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IGet(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IGetWide(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IGetObject(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IGetBoolean(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IGetByte(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IGetChar(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IGetShort(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IPut(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IPutWide(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IPutObject(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IPutBoolean(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IPutByte(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IPutChar(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::IPutShort(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SGet(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SGetWide(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SGetObject(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SGetBoolean(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SGetByte(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SGetChar(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SGetShort(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SPut(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SPutWide(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SPutObject(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SPutBoolean(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SPutByte(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SPutChar(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
|
||||||
insns.push(ins);
|
|
||||||
}
|
|
||||||
Instruction::SPutShort(ins) => {
|
|
||||||
let field = &ins.field;
|
|
||||||
let field_idx = self.field_ids.get(field).ok_or(anyhow!(
|
|
||||||
"Field {} (field of class {}, found in code of {}) not found in dex builder",
|
|
||||||
field.__repr__(),
|
|
||||||
field.class_.__repr__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))?;
|
|
||||||
let ins = ins.get_raw_ins(*field_idx);
|
|
||||||
addr += ins.size() / 2;
|
addr += ins.size() / 2;
|
||||||
insns.push(ins);
|
insns.push(ins);
|
||||||
}
|
}
|
||||||
|
|
@ -1308,7 +774,14 @@ impl DexWriter {
|
||||||
Instruction::Label { .. } => (),
|
Instruction::Label { .. } => (),
|
||||||
_ => {
|
_ => {
|
||||||
let ins = ins
|
let ins = ins
|
||||||
.get_raw_ins(Some(&self.strings), Some(&self.type_ids))
|
.get_raw_ins(
|
||||||
|
Some(&self.strings),
|
||||||
|
Some(&self.type_ids),
|
||||||
|
Some(&self.field_ids),
|
||||||
|
Some((addr, &label_addrs)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
.with_context(|| {
|
.with_context(|| {
|
||||||
format!(
|
format!(
|
||||||
"Failed to convert instruction {} (found in code of {}) to raw instruction",
|
"Failed to convert instruction {} (found in code of {}) to raw instruction",
|
||||||
|
|
@ -1323,7 +796,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(None, None)?;
|
let nop = (Instruction::Nop {}).get_raw_ins(None, None, None, None, 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