mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-22 23:31:26 +00:00
Fix #7086 - plt calculation with partial relro elf
This commit is contained in:
parent
94d85cad32
commit
e1c89440b3
@ -1107,7 +1107,7 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
ut8 rl[sizeof (Elf_(Rel))] = {0};
|
||||
ut8 rla[sizeof (Elf_(Rela))] = {0};
|
||||
RBinElfSection *rel_sec = NULL;
|
||||
Elf_(Addr) plt_sym_addr = -1;
|
||||
Elf_(Addr) plt_sym_addr = UT32_MAX;
|
||||
ut64 got_addr, got_offset;
|
||||
ut64 plt_addr;
|
||||
int j, k, tsize, len, nrel;
|
||||
@ -1116,15 +1116,15 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
const char *rela_sect[] = { ".rela.plt", ".rel.plt", ".rela.dyn", ".rel.dyn", NULL };
|
||||
|
||||
if ((!bin->shdr || !bin->strtab) && !bin->phdr) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
if ((got_offset = Elf_(r_bin_elf_get_section_offset) (bin, ".got")) == -1 &&
|
||||
(got_offset = Elf_(r_bin_elf_get_section_offset) (bin, ".got.plt")) == -1) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
if ((got_addr = Elf_(r_bin_elf_get_section_addr) (bin, ".got")) == -1 &&
|
||||
(got_addr = Elf_(r_bin_elf_get_section_addr) (bin, ".got.plt")) == -1) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
if (bin->is_rela == DT_REL) {
|
||||
j = 0;
|
||||
@ -1141,24 +1141,24 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
tsize = sizeof (Elf_(Rela));
|
||||
}
|
||||
if (!rel_sec) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
if (rel_sec->size < 1) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
nrel = (ut32)((int)rel_sec->size / (int)tsize);
|
||||
if (nrel < 1) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
if (is_rela) {
|
||||
rela = calloc (nrel, tsize);
|
||||
if (!rela) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
} else {
|
||||
rel = calloc (nrel, tsize);
|
||||
if (!rel) {
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
}
|
||||
for (j = k = 0; j < rel_sec->size && k < nrel; j += tsize, k++) {
|
||||
@ -1169,7 +1169,9 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
if (rel_sec->offset + j + tsize > bin->size) {
|
||||
goto out;
|
||||
}
|
||||
len = r_buf_read_at (bin->b, rel_sec->offset + j, is_rela? rla: rl, is_rela? sizeof (Elf_(Rela)): sizeof (Elf_(Rel)));
|
||||
len = r_buf_read_at (
|
||||
bin->b, rel_sec->offset + j, is_rela ? rla : rl,
|
||||
is_rela ? sizeof (Elf_ (Rela)) : sizeof (Elf_ (Rel)));
|
||||
if (len < 1) {
|
||||
goto out;
|
||||
}
|
||||
@ -1225,7 +1227,7 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
plt_addr = Elf_(r_bin_elf_get_section_addr) (bin, ".plt");
|
||||
if (plt_addr == -1) {
|
||||
free (rela);
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
if (reloc_type == R_386_PC16) {
|
||||
plt_addr += k * 12 + 20;
|
||||
@ -1245,7 +1247,7 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
plt_addr = Elf_(r_bin_elf_get_section_addr) (bin, ".plt");
|
||||
if (plt_addr == -1) {
|
||||
free (rela);
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
switch (reloc_type) {
|
||||
case R_386_8:
|
||||
@ -1293,7 +1295,7 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
//XXX HACK ALERT!!!! full relro?? try to fix it
|
||||
//will there always be .plt.got, what would happen if is .got.plt?
|
||||
RBinElfSection *s = get_section_by_name (bin, ".plt.got");
|
||||
if (Elf_(r_bin_elf_has_relro)(bin) != R_ELF_FULL_RELRO || !s) {
|
||||
if (Elf_(r_bin_elf_has_relro)(bin) < R_ELF_PART_RELRO || !s) {
|
||||
goto done;
|
||||
}
|
||||
plt_addr = s->offset;
|
||||
@ -1304,7 +1306,7 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
|
||||
form
|
||||
|
||||
ff253a152000 JMP QWORD [RIP + 0x20153A]
|
||||
6690 NOP
|
||||
6690 NOP
|
||||
----
|
||||
ff25ec9f0408 JMP DWORD [reloc.puts_236]
|
||||
|
||||
@ -1382,7 +1384,7 @@ done:
|
||||
return plt_sym_addr;
|
||||
out:
|
||||
free (REL);
|
||||
return -1;
|
||||
return UT32_MAX;
|
||||
}
|
||||
|
||||
int Elf_(r_bin_elf_has_nx)(ELFOBJ *bin) {
|
||||
@ -2462,7 +2464,7 @@ static RBinElfSymbol* get_symbols_from_phdr(ELFOBJ *bin, int type) {
|
||||
if (!sym || !ret) {
|
||||
goto beach;
|
||||
}
|
||||
for (i = 0, ret_ctr = 0; i < nsym; i++) {
|
||||
for (i = 1, ret_ctr = 0; i < nsym; i++) {
|
||||
if (i >= capacity1) { // maybe grow
|
||||
// You take what you want, but you eat what you take.
|
||||
Elf_(Sym)* temp_sym = (Elf_(Sym)*) realloc(sym, (capacity1 * GROWTH_FACTOR) * sym_size);
|
||||
@ -2502,13 +2504,12 @@ static RBinElfSymbol* get_symbols_from_phdr(ELFOBJ *bin, int type) {
|
||||
sym[i].st_shndx = READ16 (s, j);
|
||||
#endif
|
||||
// zero symbol is always empty
|
||||
if (i == 0) continue;
|
||||
// Examine entry and maybe store
|
||||
if (type == R_BIN_ELF_IMPORTS && sym[i].st_shndx == STN_UNDEF) {
|
||||
if (sym[i].st_value) {
|
||||
toffset = sym[i].st_value;
|
||||
} else if ((toffset = get_import_addr (bin, i)) == -1) {
|
||||
toffset = 0;
|
||||
} else {
|
||||
toffset = get_import_addr (bin, i);
|
||||
}
|
||||
tsize = 16;
|
||||
} else if (type == R_BIN_ELF_SYMBOLS &&
|
||||
@ -2630,7 +2631,8 @@ static int Elf_(fix_symbols)(ELFOBJ *bin, int nsym, int type, RBinElfSymbol **sy
|
||||
if (d->offset == p->offset) {
|
||||
p->in_shdr = true;
|
||||
if (*p->name && strcmp (d->name, p->name)) {
|
||||
strcpy (d->name, p->name);
|
||||
//eprintf ("%s by %s\n", p->name, d->name);
|
||||
//strcpy (d->name, p->name);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
@ -2784,15 +2786,17 @@ static RBinElfSymbol* Elf_(_r_bin_elf_get_symbols_imports)(ELFOBJ *bin, int type
|
||||
if (type == R_BIN_ELF_IMPORTS && sym[k].st_shndx == STN_UNDEF) {
|
||||
if (sym[k].st_value) {
|
||||
toffset = sym[k].st_value;
|
||||
} else if ((toffset = get_import_addr (bin, k)) == -1) {
|
||||
toffset = 0;
|
||||
} else {
|
||||
toffset = get_import_addr (bin, k);
|
||||
}
|
||||
tsize = 16;
|
||||
} else if (type == R_BIN_ELF_SYMBOLS && sym[k].st_shndx != STN_UNDEF &&
|
||||
ELF_ST_TYPE(sym[k].st_info) != STT_SECTION && ELF_ST_TYPE(sym[k].st_info) != STT_FILE) {
|
||||
} else if (type == R_BIN_ELF_SYMBOLS &&
|
||||
sym[k].st_shndx != STN_UNDEF &&
|
||||
ELF_ST_TYPE (sym[k].st_info) != STT_SECTION &&
|
||||
ELF_ST_TYPE (sym[k].st_info) != STT_FILE) {
|
||||
//int idx = sym[k].st_shndx;
|
||||
tsize = sym[k].st_size;
|
||||
toffset = (ut64)sym[k].st_value; //-sym_offset; // + (ELF_ST_TYPE(sym[k].st_info) == STT_FUNC?sym_offset:data_offset);
|
||||
toffset = (ut64)sym[k].st_value;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -2830,6 +2834,7 @@ static RBinElfSymbol* Elf_(_r_bin_elf_get_symbols_imports)(ELFOBJ *bin, int type
|
||||
}
|
||||
}
|
||||
if (!ret) {
|
||||
eprintf ("CALLING FROM PHDR\n");
|
||||
return (type == R_BIN_ELF_SYMBOLS)
|
||||
? Elf_(r_bin_elf_get_phdr_symbols) (bin)
|
||||
: Elf_(r_bin_elf_get_phdr_imports) (bin);
|
||||
|
@ -592,10 +592,9 @@ static RList* relocs(RBinFile *arch) {
|
||||
return NULL;
|
||||
}
|
||||
bin = arch->o->bin_obj;
|
||||
if (!(ret = r_list_new ())) {
|
||||
if (!(ret = r_list_newf (free))) {
|
||||
return NULL;
|
||||
}
|
||||
ret->free = free;
|
||||
/* FIXME: This is a _temporary_ fix/workaround to prevent a use-after-
|
||||
* free detected by ASan that would corrupt the relocation names */
|
||||
r_list_free (imports (arch));
|
||||
|
@ -1396,7 +1396,7 @@ static RBinSymbol *get_symbol(RBin *bin, RList *symbols, const char *name, ut64
|
||||
/* XXX: This is a hack to get PLT references in rabin2 -i */
|
||||
/* imp. is a prefix that can be rewritten by the symbol table */
|
||||
static ut64 impaddr(RBin *bin, int va, const char *name) {
|
||||
char impname[512];
|
||||
char *impname;
|
||||
RList *symbols;
|
||||
RBinSymbol *s;
|
||||
|
||||
@ -1406,8 +1406,7 @@ static ut64 impaddr(RBin *bin, int va, const char *name) {
|
||||
if (!(symbols = r_bin_get_symbols (bin))) {
|
||||
return false;
|
||||
}
|
||||
// TODO: avoid using snprintf here
|
||||
snprintf (impname, sizeof (impname), "imp.%s", name);
|
||||
impname = sdb_fmt (2, "imp.%s", name);
|
||||
s = get_symbol (bin, symbols, impname, 0LL);
|
||||
if (s) {
|
||||
if (va) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user