pub(crate) fn generate_plt0_code() -> Vec<u8> {
let mut plt_data = vec![];
plt_data.extend_from_slice(&[0xff, 0xb3, 0x04, 0x00, 0x00, 0x00]);
plt_data.extend_from_slice(&[0xff, 0xa3, 0x08, 0x00, 0x00, 0x00]);
plt_data.resize(16, 0x90);
plt_data
}
pub(crate) fn generate_plt_entry_code(reloc_idx: u32, plt_entry_offset: u64) -> Vec<u8> {
let mut plt_data = vec![];
let reloc_offset = reloc_idx * 8;
plt_data.extend_from_slice(&[0xff, 0xa3, 0, 0, 0, 0]);
plt_data.extend_from_slice(&[0x68]);
plt_data.extend_from_slice(&reloc_offset.to_le_bytes());
plt_data.extend_from_slice(&[0xe9]);
let plt0_offset = -(plt_entry_offset as i32 + 16);
plt_data.extend_from_slice(&plt0_offset.to_le_bytes());
plt_data.resize(16, 0x90);
plt_data
}
pub(crate) fn patch_plt_entry(
plt_data: &mut [u8],
plt_entry_off: usize,
target_got_vaddr: u64,
got_vaddr: u64,
) {
let offset = (target_got_vaddr - got_vaddr) as u32;
plt_data[plt_entry_off + 2..plt_entry_off + 6].copy_from_slice(&offset.to_le_bytes());
}
pub(crate) fn generate_helper_code() -> Vec<u8> {
let mut code = vec![0x90; 32];
code[0] = 0xe8;
code[1] = 0x00;
code[2] = 0x00;
code[3] = 0x00;
code[4] = 0x00;
code[5] = 0x5b;
code[6] = 0x81;
code[7] = 0xc3;
code[12] = 0xe9;
code
}
pub(crate) fn patch_helper(
text_data: &mut [u8],
helper_text_off: usize,
helper_vaddr: u64,
target_plt_vaddr: u64,
got_vaddr: u64,
) {
let got_off = (got_vaddr as i64 - (helper_vaddr + 5) as i64) as i32;
text_data[helper_text_off + 8..helper_text_off + 12].copy_from_slice(&got_off.to_le_bytes());
let rel_off = (target_plt_vaddr as i64 - (helper_vaddr + 17) as i64) as i32;
text_data[helper_text_off + 13..helper_text_off + 17].copy_from_slice(&rel_off.to_le_bytes());
}
pub(crate) fn get_ifunc_resolver_code() -> Vec<u8> {
let mut code = vec![0x90; 16];
code[0] = 0xe8;
code[1] = 0x00;
code[2] = 0x00;
code[3] = 0x00;
code[4] = 0x00;
code[5] = 0x58;
code[6] = 0x05;
code[11] = 0xc3;
code
}
pub(crate) fn patch_ifunc_resolver(
text_data: &mut [u8],
offset: usize,
resolver_vaddr: u64,
target_vaddr: u64,
) {
let imm32 = (target_vaddr as i64 - (resolver_vaddr + 5) as i64) as i32;
text_data[offset + 7..offset + 11].copy_from_slice(&imm32.to_le_bytes());
}
pub(crate) fn generate_tls_helper_code() -> Vec<u8> {
let mut code = vec![0x90; 64];
code[0] = 0x55;
code[1] = 0x89;
code[2] = 0xe5;
code[3] = 0x53;
code[4] = 0xe8;
code[5] = 0x00;
code[6] = 0x00;
code[7] = 0x00;
code[8] = 0x00;
code[9] = 0x5b;
code[10] = 0x81;
code[11] = 0xc3;
code[16] = 0x8d;
code[17] = 0x83;
code[22] = 0x50;
code[23] = 0xe8;
code[28] = 0x83;
code[29] = 0xc4;
code[30] = 0x04;
code[31] = 0x5b;
code[32] = 0x5d;
code[33] = 0xc3;
code
}
pub(crate) fn patch_tls_tester(
text_data: &mut [u8],
offset: usize,
helper_vaddr: u64,
reloc_vaddr: u64,
tls_get_addr_vaddr: u64,
got_vaddr: u64,
) {
let got_off = (got_vaddr as i64 - (helper_vaddr + 9) as i64) as i32;
text_data[offset + 12..offset + 16].copy_from_slice(&got_off.to_le_bytes());
let reloc_off = (reloc_vaddr as i64 - got_vaddr as i64) as i32;
text_data[offset + 18..offset + 22].copy_from_slice(&reloc_off.to_le_bytes());
let rel_off = (tls_get_addr_vaddr as i64 - (helper_vaddr + 28) as i64) as i32;
text_data[offset + 24..offset + 28].copy_from_slice(&rel_off.to_le_bytes());
}