#include <assert.h>
#include <stdlib.h>
-#include <libelf/libelf.h>
-#include <libelf/gelf.h>
#include <libelfu/libelfu.h>
int elfu_eCheck(Elf *e)
goto ERROR;
}
+ if (ehdr.e_machine != EM_386 && ehdr.e_machine != EM_X86_64) {
+ ELFU_WARN("Sorry, only x86-32 and x86-64 ELF files are supported at the moment.\n");
+ goto ERROR;
+ }
+
if (elf_getphdrnum(e, &numPhdr)) {
ELFU_WARNELF("elf_getphdrnum");
goto ERROR;
}
/* Section should not overlap with PHDRs. */
- if (OVERLAPPING(shdrs[i].sh_offset, elfu_gScnSizeFile(&shdrs[i]),
+ if (OVERLAPPING(shdrs[i].sh_offset, SCNFILESIZE(&shdrs[i]),
ehdr.e_phoff, numPhdr * ehdr.e_phentsize)) {
ELFU_WARN("elfu_eCheck: Section %d overlaps with PHDR.\n", i);
goto ERROR;
}
/* Section should not overlap with SHDRs. */
- if (OVERLAPPING(shdrs[i].sh_offset, elfu_gScnSizeFile(&shdrs[i]),
+ if (OVERLAPPING(shdrs[i].sh_offset, SCNFILESIZE(&shdrs[i]),
ehdr.e_shoff, numShdr * ehdr.e_shentsize)) {
ELFU_WARN("elfu_eCheck: Section %d overlaps with SHDRs.\n", i);
goto ERROR;
}
/* Sections must not overlap in file. */
- if (OVERLAPPING(shdrs[i].sh_offset, elfu_gScnSizeFile(&shdrs[i]),
- shdrs[j].sh_offset, elfu_gScnSizeFile(&shdrs[j]))) {
+ if (OVERLAPPING(shdrs[i].sh_offset, SCNFILESIZE(&shdrs[i]),
+ shdrs[j].sh_offset, SCNFILESIZE(&shdrs[j]))) {
ELFU_WARN("elfu_eCheck: Sections %d and %d overlap in file.\n", i, j);
goto ERROR;
}
}
+
+ /* Section addr/offset should match parent PHDR.
+ * Find parent PHDR: */
+ for (j = 0; j < numPhdr; j++) {
+ if (PHDR_CONTAINS_SCN_IN_MEMORY(&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;
+ }
+ }
+ }
+
+ /* sh_link members should not point to sections out of range. */
+ if (shdrs[i].sh_link >= numShdr) {
+ ELFU_WARN("elfu_eCheck: Bogus sh_link in SHDR %d.\n", i);
+ }
}
}