From d5c411ba043ef62c81e4941990f0625bd3ea3814 Mon Sep 17 00:00:00 2001 From: norly Date: Thu, 30 May 2013 18:13:59 +0100 Subject: [PATCH] More rigorous sh_addr and sh_offset checking --- src/elfops/check.c | 5 ++++- src/model/fromFile.c | 26 +++++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/elfops/check.c b/src/elfops/check.c index daf6542..be8704b 100644 --- a/src/elfops/check.c +++ b/src/elfops/check.c @@ -165,7 +165,10 @@ int elfu_eCheck(Elf *e) * Find parent PHDR: */ for (j = 0; j < numPhdr; j++) { if (PHDR_CONTAINS_SCN_IN_MEMORY(&phdrs[j], &shdrs[i])) { - if (!PHDR_CONTAINS_SCN_IN_FILE(&phdrs[j], &shdrs[i])) { + GElf_Off shoff = phdrs[j].p_offset + (shdrs[i].sh_addr - phdrs[j].p_vaddr); + + if (shdrs[i].sh_offset != shoff + || !PHDR_CONTAINS_SCN_IN_FILE(&phdrs[j], &shdrs[i])) { ELFU_WARN("elfu_eCheck: Memory/file offsets/sizes are not congruent for SHDR %d, PHDR %d.\n", i, j); goto ERROR; } diff --git a/src/model/fromFile.c b/src/model/fromFile.c index ee0536d..7b8bfd3 100644 --- a/src/model/fromFile.c +++ b/src/model/fromFile.c @@ -42,14 +42,21 @@ static ElfuPhdr* parentPhdr(ElfuElf *me, ElfuScn *ms) continue; } - if (ms->shdr.sh_addr >= mp->phdr.p_vaddr - && OFFS_END(ms->shdr.sh_addr, ms->shdr.sh_size) <= OFFS_END(mp->phdr.p_vaddr, mp->phdr.p_memsz)) { + if (PHDR_CONTAINS_SCN_IN_MEMORY(&mp->phdr, &ms->shdr)) { return mp; - } else if (ms->shdr.sh_offset >= mp->phdr.p_offset - && OFFS_END(ms->shdr.sh_offset, SCNFILESIZE(&ms->shdr)) <= OFFS_END(mp->phdr.p_offset, mp->phdr.p_filesz) - && OFFS_END(ms->shdr.sh_offset, ms->shdr.sh_size) <= OFFS_END(mp->phdr.p_offset, mp->phdr.p_memsz)) { + } + + /* Give sections a second chance if they do not have any sh_addr + * at all. */ + /* Actually we don't, because it's ambiguous. + * Re-enable for experiments with strangely-formatted files. + if (ms->shdr.sh_addr == 0 + && PHDR_CONTAINS_SCN_IN_FILE(&mp->phdr, &ms->shdr) + && OFFS_END(ms->shdr.sh_offset, ms->shdr.sh_size) + <= OFFS_END(mp->phdr.p_offset, mp->phdr.p_memsz)) { return mp; } + */ } return NULL; @@ -287,6 +294,15 @@ ElfuElf* elfu_mFromElf(Elf *e) ElfuPhdr *parent = parentPhdr(me, ms); if (parent) { + GElf_Off shaddr = parent->phdr.p_vaddr + + (ms->shdr.sh_offset - parent->phdr.p_offset); + + if (ms->shdr.sh_addr == 0) { + ms->shdr.sh_addr = shaddr; + } else { + assert(ms->shdr.sh_addr == shaddr); + } + CIRCLEQ_INSERT_TAIL(&parent->childScnList, ms, elemChildScn); } else { CIRCLEQ_INSERT_TAIL(&me->orphanScnList, ms, elemChildScn); -- 2.30.2