Skip to content

Instantly share code, notes, and snippets.

@haraldh
Created May 12, 2020 15:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haraldh/3bc00e425081f5bdfdd6d0c07c1b4430 to your computer and use it in GitHub Desktop.
Save haraldh/3bc00e425081f5bdfdd6d0c07c1b4430 to your computer and use it in GitHub Desktop.
extern "C" {
static _DYNAMIC: u64;
}
use core::mem::size_of;
use goblin::elf::dynamic::dyn64::Dyn;
use goblin::elf::dynamic::{DT_REL, DT_RELA, DT_RELASZ, DT_RELSZ};
use goblin::elf::reloc::reloc64::Rel;
use goblin::elf::reloc::reloc64::Rela;
use goblin::elf::reloc::reloc64::R_X86_64_RELATIVE;
const DYN_CNT: usize = 32;
#[no_mangle]
pub unsafe extern "C" fn dyn_reloc(_arg1: u64, base: u64, dynv: *const Dyn) {
let mut dynv = dynv;
//let dynv = _DYNAMIC as *const _ as *const usize;
let mut dt_rel: u64 = 0;
let mut dt_relsz: u64 = 0;
let mut dt_rela: u64 = 0;
let mut dt_relasz: u64 = 0;
loop {
let d = *dynv;
match d.d_tag {
DT_REL => dt_rel = d.d_val,
DT_RELSZ => dt_relsz = d.d_val,
DT_RELA => dt_rela = d.d_val,
DT_RELASZ => dt_relasz = d.d_val,
0 => break,
_ => {}
}
dynv = dynv.offset(1);
}
if dt_relsz > 0 {
let mut rel: *const Rel = (dt_rel + base) as _;
for _ in (0..(dt_relsz as usize / size_of::<Rel>())) {
if ((*rel).r_info & 0x7fffffff) != R_X86_64_RELATIVE as _ {
rel = rel.offset(1);
continue;
}
let rel_addr: *mut u64 = ((*rel).r_offset + base) as _;
rel_addr.write(rel_addr.read() + base);
rel = rel.offset(1);
}
}
if dt_relasz > 0 {
let mut rela: *const Rela = (dt_rela + base) as _;
for _ in (0..(dt_relasz as usize / size_of::<Rela>())) {
if ((*rela).r_info & 0x7fffffff) != R_X86_64_RELATIVE as _ {
rela = rela.offset(1);
continue;
}
let rel_addr: *mut u64 = ((*rela).r_offset + base) as _;
rel_addr.write((base as i64 + (*rela).r_addend) as u64);
rela = rela.offset(1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment