This commit is contained in:
Jean-Marie Mineau 2024-07-17 21:19:20 +02:00
parent 69e7476904
commit cb80922d38
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
2 changed files with 775 additions and 3187 deletions

View file

@ -445,19 +445,11 @@ impl DexWriter {
} }
Instruction::ConstString { .. } => { Instruction::ConstString { .. } => {
let size = ins let size = ins
.get_raw_ins( .get_raw_ins(GetRawInsParam {
Some(&self.strings), strings: Some(&self.strings),
None, ..GetRawInsParam::default()
None, })
None, .with_context(|| format!("Error in code of {}", method_id.__repr__()))?
None,
None,
None,
None,
None,
None,
)
.with_context(|| format!("In code of {}", method_id.__repr__()))?
.size() .size()
/ 2; / 2;
min_addr += size; min_addr += size;
@ -481,18 +473,10 @@ impl DexWriter {
} }
Instruction::ConstString { .. } => { Instruction::ConstString { .. } => {
addr += ins addr += ins
.get_raw_ins( .get_raw_ins(GetRawInsParam {
Some(&self.strings), strings: Some(&self.strings),
None, ..GetRawInsParam::default()
None, })?
None,
None,
None,
None,
None,
None,
None,
)?
.size() .size()
/ 2; / 2;
// should not fail after // should not fail after
@ -539,45 +523,43 @@ 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( let nop = (Instruction::Nop {}).get_raw_ins(GetRawInsParam::default())?;
None, None, None, None, 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( let ins = ins
None, .get_raw_ins(GetRawInsParam {
None, data_offset: Some(data_offset),
None, ..GetRawInsParam::default()
None, })
None, .with_context(|| {
None, format!(
None, "Failed to convert instruction {} (found in code of {}) to raw instruction",
None, ins.__repr__(),
None, method_id.__repr__()
Some(data_offset), )
)?; })?;
addr += ins.size() / 2; addr += ins.size() / 2;
insns.push(ins); insns.push(ins);
} }
Instruction::Goto { .. } => { Instruction::Goto { .. } => {
let goto_size = goto_sizes[goto_idx]; let goto_size = goto_sizes[goto_idx];
goto_idx += 1; goto_idx += 1;
let ins = ins.get_raw_ins( let ins = ins.get_raw_ins(GetRawInsParam {
None, jump_data: Some((addr, &label_addrs)),
None, goto_size: Some(goto_size),
None, ..GetRawInsParam::default()
None, })
None, .with_context(|| {
None, format!(
None, "Failed to convert instruction {} (found in code of {}) to raw instruction",
Some((addr, &label_addrs)), ins.__repr__(),
Some(goto_size), method_id.__repr__()
None, )
)?; })?;
addr += ins.size() / 2; addr += ins.size() / 2;
insns.push(ins); insns.push(ins);
} }
@ -608,63 +590,58 @@ 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(GetRawInsParam::default())?;
None, None, None, None, 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( let ins = ins.get_raw_ins(GetRawInsParam {
None, data_offset: Some(data_offset),
None, ..GetRawInsParam::default()
None, })
None, .with_context(|| {
None, format!(
None, "Failed to convert instruction {} (found in code of {}) to raw instruction",
None, ins.__repr__(),
None, method_id.__repr__()
None, )
Some(data_offset), })?;
)?;
addr += ins.size() / 2; addr += ins.size() / 2;
insns.push(ins); insns.push(ins);
} }
Instruction::InvokeCustom { call_site, .. } => { Instruction::InvokeCustom { call_site, .. } => {
let call_site_idx = self.call_site_ids.len(); let call_site_idx = self.call_site_ids.len();
self.insert_call_site_item(&call_site)?; self.insert_call_site_item(&call_site)?;
let ins = ins.get_raw_ins( let ins = ins.get_raw_ins(GetRawInsParam {
None, call_site_idx: Some(call_site_idx),
None, ..GetRawInsParam::default()
None, })
None, .with_context(|| {
None, format!(
Some(call_site_idx), "Failed to convert instruction {} (found in code of {}) to raw instruction",
None, ins.__repr__(),
None, method_id.__repr__()
None, )
None, })?;
)?;
addr += ins.size() / 2; addr += ins.size() / 2;
insns.push(ins); insns.push(ins);
} }
Instruction::ConstMethodHandle { handle, .. } => { Instruction::ConstMethodHandle { handle, .. } => {
let method_handle_idx = self.method_handles.len(); let method_handle_idx = self.method_handles.len();
self.insert_method_handle(&handle)?; self.insert_method_handle(&handle)?;
let ins = ins.get_raw_ins( let ins = ins.get_raw_ins(GetRawInsParam {
None, method_handle_idx: Some(method_handle_idx),
None, ..GetRawInsParam::default()
None, })
None, .with_context(|| {
None, format!(
None, "Failed to convert instruction {} (found in code of {}) to raw instruction",
Some(method_handle_idx), ins.__repr__(),
None, method_id.__repr__()
None, )
None, })?;
)?;
addr += ins.size() / 2; addr += ins.size() / 2;
insns.push(ins); insns.push(ins);
} }
@ -728,24 +705,21 @@ impl DexWriter {
Instruction::Label { .. } => (), Instruction::Label { .. } => (),
_ => { _ => {
let ins = ins let ins = ins
.get_raw_ins( .get_raw_ins(GetRawInsParam {
Some(&self.strings), strings: Some(&self.strings),
Some(&self.type_ids), type_ids: Some(&self.type_ids),
Some(&self.field_ids), field_ids: Some(&self.field_ids),
Some(&self.method_ids), method_ids: Some(&self.method_ids),
Some(&self.proto_ids), proto_ids: Some(&self.proto_ids),
None, jump_data: Some((addr, &label_addrs)),
None, ..GetRawInsParam::default()
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",
ins.__repr__(), ins.__repr__(),
method_id.__repr__() method_id.__repr__()
) )
})?; })?;
addr += ins.size() / 2; addr += ins.size() / 2;
insns.push(ins); insns.push(ins);
@ -754,8 +728,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 {}) let nop = (Instruction::Nop {}).get_raw_ins(GetRawInsParam::default())?;
.get_raw_ins(None, None, None, None, None, None, None, None, None, None)?;
//addr += nop.size() / 2; //addr += nop.size() / 2;
insns.push(nop); insns.push(nop);
} }
@ -796,10 +769,10 @@ impl DexWriter {
self.debug_info_items.push(item); self.debug_info_items.push(item);
debug_info_off + 1 debug_info_off + 1
}; };
let handlers = if handlers.list.is_empty() { let handlers = if encoded_handlers.list.is_empty() {
None None
} else { } else {
Some(handlers) Some(encoded_handlers)
}; };
let item = CodeItem { let item = CodeItem {
registers_size: code.registers_size, registers_size: code.registers_size,

File diff suppressed because it is too large Load diff