const PADDING: [u8; 4] = [0x0, 0x0, 0x0, 0x0];
pub(crate) fn generate_plt0_code() -> Vec<u8> {
let mut plt_data = vec![];
plt_data.extend_from_slice(&[0xff, 0x35]);
plt_data.extend_from_slice(&PADDING);
plt_data.extend_from_slice(&[0xff, 0x25]);
plt_data.extend_from_slice(&PADDING);
plt_data.resize(16, 0x90);
plt_data
}
pub(crate) fn patch_plt0(
plt_data: &mut [u8],
plt0_off: usize,
plt0_vaddr: u64,
got_plt_vaddr: u64,
) {
let target_got1 = got_plt_vaddr + 8;
let rip1 = plt0_vaddr + 6;
let off1 = (target_got1 as i64 - rip1 as i64) as i32;
plt_data[plt0_off + 2..plt0_off + 6].copy_from_slice(&off1.to_le_bytes());
let target_got2 = got_plt_vaddr + 16;
let rip2 = plt0_vaddr + 12;
let off2 = (target_got2 as i64 - rip2 as i64) as i32;
plt_data[plt0_off + 8..plt0_off + 12].copy_from_slice(&off2.to_le_bytes());
}
pub(crate) fn generate_plt_entry_code(reloc_idx: u32, plt_entry_offset: u64) -> Vec<u8> {
let mut plt_data = vec![];
let plt0_offset = -((plt_entry_offset as i32) + 16);
plt_data.extend_from_slice(&[0xff, 0x25]);
plt_data.extend_from_slice(&PADDING);
plt_data.extend_from_slice(&[0x68]);
plt_data.extend_from_slice(&reloc_idx.to_le_bytes());
plt_data.extend_from_slice(&[0xe9]);
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,
plt_entry_vaddr: u64,
target_got_vaddr: u64,
) {
let rip = plt_entry_vaddr + 6;
let off = (target_got_vaddr as i64 - rip as i64) as i32;
plt_data[plt_entry_off + 2..plt_entry_off + 6].copy_from_slice(&off.to_le_bytes());
}
pub(crate) fn generate_helper_code() -> Vec<u8> {
vec![0xE9, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]
}
pub(crate) fn patch_helper(
text_data: &mut [u8],
helper_text_off: usize,
helper_vaddr: u64,
target_plt_vaddr: u64,
) {
let rel_off = (target_plt_vaddr as i64 - (helper_vaddr + 5) as i64) as i32;
text_data[helper_text_off] = 0xE9;
text_data[helper_text_off + 1..helper_text_off + 5].copy_from_slice(&rel_off.to_le_bytes());
}
pub(crate) fn generate_tls_helper_code() -> Vec<u8> {
let mut code = vec![0x90; 32];
code[0] = 0x55;
code[1..4].copy_from_slice(&[0x48, 0x89, 0xe5]);
code[4..7].copy_from_slice(&[0x48, 0x8d, 0x3d]);
code[11] = 0xe8;
code[16] = 0x5d;
code[17] = 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,
) {
let lea_off = (reloc_vaddr as i64 - (helper_vaddr + 11) as i64) as i32;
text_data[offset + 7..offset + 11].copy_from_slice(&lea_off.to_le_bytes());
let call_off = (tls_get_addr_vaddr as i64 - (helper_vaddr + 16) as i64) as i32;
text_data[offset + 12..offset + 16].copy_from_slice(&call_off.to_le_bytes());
}
pub(crate) fn get_ifunc_resolver_code() -> Vec<u8> {
let mut code = vec![0x90; 16];
code[0..3].copy_from_slice(&[0x48, 0x8d, 0x05]);
code[7] = 0xc3;
code
}
pub(crate) fn patch_ifunc_resolver(
text_data: &mut [u8],
offset: usize,
resolver_vaddr: u64,
target_vaddr: u64,
) {
let rel_off = (target_vaddr as i64 - (resolver_vaddr + 7) as i64) as i32;
text_data[offset + 3..offset + 7].copy_from_slice(&rel_off.to_le_bytes());
}