Fix #18375 - Only patch arm64 relocs when not initialized ##bin

This commit is contained in:
pancake 2022-02-01 21:41:32 +01:00 committed by pancake
parent 22342066c1
commit 3ee8e4a4ef
6 changed files with 82 additions and 9 deletions

View File

@ -228,7 +228,6 @@ static void filter_classes(RBinFile *bf, RList *list) {
static RRBTree *list2rbtree(RList *relocs) {
RRBTree *tree = r_crbtree_new (free);
if (tree) {
RListIter *it;
RBinReloc *reloc;

View File

@ -2743,6 +2743,7 @@ static void fix_rva_and_offset_relocable_file(ELFOBJ *bin, RBinElfReloc *r, size
}
static void fix_rva_and_offset_exec_file(ELFOBJ *bin, RBinElfReloc *r) {
// read target and fix patch
r->rva = r->offset;
r->offset = Elf_(r_bin_elf_v2p) (bin, r->offset);
}
@ -2961,7 +2962,6 @@ RBinElfReloc* Elf_(r_bin_elf_get_relocs) (ELFOBJ *bin) {
if (!bin) {
return NULL;
}
if (!bin->g_relocs) {
bin->g_relocs = populate_relocs_record (bin);
}

View File

@ -13,8 +13,6 @@
static RBinInfo* info(RBinFile *bf);
//TODO: implement r_bin_symbol_dup() and r_bin_symbol_free ?
static int get_file_type(RBinFile *bf) {
ELFOBJ *obj = bf->o->bin_obj;
char *type = Elf_(r_bin_elf_get_file_type (obj));
@ -909,11 +907,12 @@ static RList* relocs(RBinFile *bf) {
return ret;
}
static void _patch_reloc(ELFOBJ *bo, ut16 e_machine, RIOBind *iob, RBinElfReloc *rel, ut64 S, ut64 B, ut64 L) {
// static void _patch_reloc(ELFOBJ *bo, ut16 e_machine, RIOBind *iob, RBinElfReloc *rel, ut64 S, ut64 B, ut64 L) {
static void _patch_reloc(RBinObject *binobj, struct Elf_(r_bin_elf_obj_t) *bo, ut16 e_machine, RIOBind *iob, RBinElfReloc *rel, ut64 S, ut64 B, ut64 L) {
ut64 V = 0;
ut64 A = rel->addend;
ut64 P = rel->rva;
ut8 buf[8];
ut8 buf[8] = {0};
switch (e_machine) {
case EM_ARM:
if (!rel->sym && rel->mode == DT_REL) {
@ -927,8 +926,22 @@ static void _patch_reloc(ELFOBJ *bo, ut16 e_machine, RIOBind *iob, RBinElfReloc
break;
case EM_AARCH64:
V = S + A;
#if 0
r_write_le64 (buf, V);
iob->write_at (iob->io, rel->rva, buf, 8);
#else
iob->read_at (iob->io, rel->rva, buf, 8);
// only patch the relocs that are initialized with zeroes
// if the destination contains a different value it's a constant useful for static analysis
ut64 addr = r_read_le64 (buf);
if (addr) {
r_write_le64 (buf, A);
iob->write_at (iob->io, rel->rva, buf, 8);
} else {
r_write_le64 (buf, S);
iob->write_at (iob->io, rel->rva, buf, 8);
}
#endif
break;
case EM_PPC64: {
int low = 0, word = 0;
@ -1173,7 +1186,7 @@ static RList* patch_relocs(RBin *b) {
}
//ut64 raddr = sym_addr? sym_addr: vaddr;
ut64 raddr = (sym_addr && sym_addr != UT64_MAX)? sym_addr: vaddr;
_patch_reloc (bin, bin->ehdr.e_machine, &b->iob, &relcs[i], raddr, 0, plt_entry_addr);
_patch_reloc (obj, bin, bin->ehdr.e_machine, &b->iob, &relcs[i], raddr, 0, plt_entry_addr);
if (!(ptr = reloc_convert (bin, &relcs[i], n_vaddr))) {
continue;
}

View File

@ -4485,6 +4485,14 @@ static void ds_print_relocs(RDisasmState *ds) {
bool demangle = r_config_get_i (core->config, "asm.demangle");
bool keep_lib = r_config_get_i (core->config, "bin.demangle.libs");
RBinReloc *rel = r_core_getreloc (core, ds->at, ds->analop.size);
#if 0
if (!rel) {
ut8 buf[8];
r_io_read_at (core->io, ds->at, buf, 8);
ut64 n = r_read_le64 (buf);
rel = r_core_getreloc (core, n, ds->analop.size);
}
#endif
if (rel) {
int cstrlen = 0;
char *ll = r_cons_lastline (&cstrlen);

View File

@ -116,8 +116,8 @@ EXPECT=<<EOF
0x00126510 .qword 0x0000000000005a6c ; sym..datadiv_decode9958896245423089702 ; [13] -rw- section size 728 named .init_array
0x00126518 .qword 0x0000000000005a80 ; sym..datadiv_decode10476194973746341988
0x00126520 .qword 0x00000000000efddc ; sym..datadiv_decode16323044921667855934
0x00126528 .qword 0x00000000001bd998
0x00126530 .qword 0x000000000022c634
0x00126528 .qword 0x0000000000009080 ; entry.init0
0x00126530 .qword 0x0000000000077d14 ; entry.init1
0x00126538 .qword 0x00000000000f22e0 ; sym..datadiv_decode667225052219618748
0x00126540 .qword 0x00000000000f22e4 ; sym..datadiv_decode8132880250332170398
0x00126548 .qword 0x00000000000f22e8 ; sym..datadiv_decode3655886617018729963

View File

@ -159,5 +159,58 @@ ret
0x0800007c e8fc ffff ff55 89e5 6800 0000 00e8 fcff .....U..h.......
0x0800008c ffff 31c0 c9c3 5589 e568 0f00 0000 e8fc ..1...U..h......
0x0800009c ffff ff58 c9c3 ...X..
NAME=ELF: relocs init array
FILE=bins/elf/r2pay-arm64.so
CMDS=<<EOF
s section..init_array
pd 10
pd 1 @ 0x0800009f
EOF
EXPECT=<<EOF
call __fentry__
push ebp
mov ebp, esp
push 0
call printk
xor eax, eax
leave
ret
push ebp
mov ebp, esp
push 0xf
call printk
pop eax
leave
ret
- offset - 7C7D 7E7F 8081 8283 8485 8687 8889 8A8B CDEF0123456789AB
0x0800007c e8fc ffff ff55 89e5 6800 0000 00e8 fcff .....U..h.......
0x0800008c ffff 31c0 c9c3 5589 e568 0f00 0000 e8fc ..1...U..h......
0x0800009c ffff ff58 c9c3 ...X..
EOF
RUN
NAME=ELF: relocs r2pay
FILE=bins/elf/r2pay-arm64.so
ARGS=-e bin.cache=true
CMDS=<<EOF
s section..init_array
pd 10
pd 1 @ 0x0800009f
EOF
EXPECT=<<EOF
;-- section..init_array:
;-- segment.LOAD1:
0x00126510 .qword 0x0000000000005a6c ; sym..datadiv_decode9958896245423089702 ; [13] -rw- section size 728 named .init_array
0x00126518 .qword 0x0000000000005a80 ; sym..datadiv_decode10476194973746341988
0x00126520 .qword 0x00000000000efddc ; sym..datadiv_decode16323044921667855934
0x00126528 .qword 0x0000000000009080 ; entry.init0
0x00126530 .qword 0x0000000000077d14 ; entry.init1
0x00126538 .qword 0x00000000000f22e0 ; sym..datadiv_decode667225052219618748
0x00126540 .qword 0x00000000000f22e4 ; sym..datadiv_decode8132880250332170398
0x00126548 .qword 0x00000000000f22e8 ; sym..datadiv_decode3655886617018729963
0x00126550 .qword 0x00000000000f22ec ; sym..datadiv_decode16406252260792032531
0x00126558 .qword 0x00000000000f22f0 ; sym..datadiv_decode13403071575248320347
0x0800009f unaligned
EOF
RUN