* r_bin_elf
- Fixed "imports bug" in ELF64
(needs more love ;)
- More fixups in section_resize for ELF64
This commit is contained in:
parent
c5303272d9
commit
5fc2e91777
2 changed files with 117 additions and 16 deletions
|
|
@ -347,7 +347,6 @@ static u64 ELF_(get_import_addr)(ELF_(r_bin_elf_obj) *bin, int sym)
|
|||
{
|
||||
ELF_(Ehdr) *ehdr = &bin->ehdr;
|
||||
ELF_(Shdr) *shdr = bin->shdr, *shdrp;
|
||||
ELF_(Rel) *rel, *relp;
|
||||
ELF_(Addr) plt_sym_addr, got_addr = 0;
|
||||
const char *string = bin->string;
|
||||
int i, j;
|
||||
|
|
@ -364,7 +363,50 @@ static u64 ELF_(get_import_addr)(ELF_(r_bin_elf_obj) *bin, int sym)
|
|||
|
||||
shdrp = shdr;
|
||||
for (i = 0; i < ehdr->e_shnum; i++, shdrp++) {
|
||||
if (!strcmp(&string[shdrp->sh_name], ".rel.plt")) {
|
||||
if (!strcmp(&string[shdrp->sh_name], ".rela.plt")) {
|
||||
ELF_(Rela) *rel, *relp;
|
||||
rel = (ELF_(Rela) *)malloc(shdrp->sh_size);
|
||||
if (rel == NULL) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) != shdrp->sh_offset) {
|
||||
perror("lseek");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size) {
|
||||
perror("read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
relp = rel;
|
||||
for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Rela)), relp++) {
|
||||
ELF_(aux_swap_endian)((u8*)&(relp->r_offset), sizeof(ELF_(Addr)));
|
||||
ELF_(aux_swap_endian)((u8*)&(relp->r_info), sizeof(ELF_(Word)));
|
||||
}
|
||||
|
||||
got_offset = (rel->r_offset - bin->base_addr - got_addr) & ELF_GOTOFF_MASK;
|
||||
relp = rel;
|
||||
for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Rela)), relp++) {
|
||||
if (ELF_R_SYM(relp->r_info) == sym) {
|
||||
if (lseek(bin->fd, relp->r_offset-bin->base_addr-got_offset, SEEK_SET)
|
||||
!= relp->r_offset-bin->base_addr-got_offset) {
|
||||
perror("lseek");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read(bin->fd, &plt_sym_addr, sizeof(ELF_(Addr))) != sizeof(ELF_(Addr))) {
|
||||
perror("read");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return plt_sym_addr-6;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(&string[shdrp->sh_name], ".rel.plt")) {
|
||||
ELF_(Rel) *rel, *relp;
|
||||
rel = (ELF_(Rel) *)malloc(shdrp->sh_size);
|
||||
if (rel == NULL) {
|
||||
perror("malloc");
|
||||
|
|
@ -388,19 +430,18 @@ static u64 ELF_(get_import_addr)(ELF_(r_bin_elf_obj) *bin, int sym)
|
|||
}
|
||||
|
||||
got_offset = (rel->r_offset - bin->base_addr - got_addr) & ELF_GOTOFF_MASK;
|
||||
|
||||
relp = rel;
|
||||
for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Rel)), relp++) {
|
||||
if (ELF32_R_SYM(relp->r_info) == sym) {
|
||||
if (ELF_R_SYM(relp->r_info) == sym) {
|
||||
if (lseek(bin->fd, relp->r_offset-bin->base_addr-got_offset, SEEK_SET)
|
||||
!= relp->r_offset-bin->base_addr-got_offset) {
|
||||
perror("lseek");
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read(bin->fd, &plt_sym_addr, sizeof(ELF_(Addr))) != sizeof(ELF_(Addr))) {
|
||||
perror("read");
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return plt_sym_addr-6;
|
||||
|
|
@ -667,7 +708,6 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u
|
|||
ELF_(Ehdr) *ehdr = &bin->ehdr;
|
||||
ELF_(Phdr) *phdr = bin->phdr, *phdrp;
|
||||
ELF_(Shdr) *shdr = bin->shdr, *shdrp;
|
||||
ELF_(Rel) *rel, *relp;
|
||||
const char *string = bin->string;
|
||||
ELF_(Word) rsz_osize = 0, rsz_fsize;
|
||||
ELF_(Word) rsz_size = (ELF_(Word)) size;
|
||||
|
|
@ -700,6 +740,7 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u
|
|||
/* rewrite rel's (imports) */
|
||||
for (i = 0, shdrp = shdr; i < ehdr->e_shnum; i++, shdrp++) {
|
||||
if (!strcmp(&string[shdrp->sh_name], ".rel.plt")) {
|
||||
ELF_(Rel) *rel, *relp;
|
||||
rel = (ELF_(Rel) *)malloc(shdrp->sh_size);
|
||||
if (rel == NULL) {
|
||||
perror("malloc");
|
||||
|
|
@ -726,6 +767,36 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u
|
|||
}
|
||||
}
|
||||
free(rel);
|
||||
break;
|
||||
} else if (!strcmp(&string[shdrp->sh_name], ".rela.plt")) {
|
||||
ELF_(Rela) *rel, *relp;
|
||||
rel = (ELF_(Rela) *)malloc(shdrp->sh_size);
|
||||
if (rel == NULL) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) < 0)
|
||||
perror("lseek");
|
||||
if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size)
|
||||
perror("read");
|
||||
|
||||
for (j = 0, relp = rel; j < shdrp->sh_size; j += sizeof(ELF_(Rela)), relp++) {
|
||||
ELF_(aux_swap_endian)((u8*)&(relp->r_offset), sizeof(ELF_(Addr)));
|
||||
ELF_(aux_swap_endian)((u8*)&(relp->r_info), sizeof(ELF_(Word)));
|
||||
/* rewrite relp->r_offset */
|
||||
if (relp->r_offset - bin->base_addr >= rsz_offset + rsz_osize) {
|
||||
new_addr = (ELF_(Addr)) (relp->r_offset + delta);
|
||||
off = shdrp->sh_offset + j;
|
||||
|
||||
if (lseek(bin->fd, off, SEEK_SET) < 0)
|
||||
perror("lseek");
|
||||
if (write(bin->fd, &new_addr, sizeof(ELF_(Addr))) != sizeof(ELF_(Addr)))
|
||||
perror("write (off)");
|
||||
}
|
||||
}
|
||||
free(rel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -921,7 +992,7 @@ int ELF_(r_bin_elf_get_imports)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_import *impo
|
|||
for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) {
|
||||
if (k == 0)
|
||||
continue;
|
||||
if (symp->st_shndx == STN_UNDEF && ELF32_ST_BIND(symp->st_info) != STB_WEAK) {
|
||||
if (symp->st_shndx == STN_UNDEF && ELF_ST_BIND(symp->st_info) != STB_WEAK) {
|
||||
memcpy(importp->name, &string[symp->st_name], ELF_NAME_LENGTH);
|
||||
importp->name[ELF_NAME_LENGTH-1] = '\0';
|
||||
if (symp->st_value)
|
||||
|
|
@ -931,7 +1002,7 @@ int ELF_(r_bin_elf_get_imports)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_import *impo
|
|||
if (importp->offset >= bin->base_addr)
|
||||
importp->offset -= bin->base_addr;
|
||||
|
||||
switch (ELF32_ST_BIND(symp->st_info)) {
|
||||
switch (ELF_ST_BIND(symp->st_info)) {
|
||||
case STB_LOCAL: snprintf(importp->bind, ELF_NAME_LENGTH, "LOCAL"); break;
|
||||
case STB_GLOBAL: snprintf(importp->bind, ELF_NAME_LENGTH, "GLOBAL"); break;
|
||||
case STB_NUM: snprintf(importp->bind, ELF_NAME_LENGTH, "NUM"); break;
|
||||
|
|
@ -941,7 +1012,7 @@ int ELF_(r_bin_elf_get_imports)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_import *impo
|
|||
case STB_HIPROC: snprintf(importp->bind, ELF_NAME_LENGTH, "HIPROC"); break;
|
||||
default: snprintf(importp->bind, ELF_NAME_LENGTH, "UNKNOWN");
|
||||
}
|
||||
switch (ELF32_ST_TYPE(symp->st_info)) {
|
||||
switch (ELF_ST_TYPE(symp->st_info)) {
|
||||
case STT_NOTYPE: snprintf(importp->type, ELF_NAME_LENGTH, "NOTYPE"); break;
|
||||
case STT_OBJECT: snprintf(importp->type, ELF_NAME_LENGTH, "OBJECT"); break;
|
||||
case STT_FUNC: snprintf(importp->type, ELF_NAME_LENGTH, "FUNC"); break;
|
||||
|
|
@ -995,7 +1066,7 @@ int ELF_(r_bin_elf_get_imports_count)(ELF_(r_bin_elf_obj) *bin)
|
|||
for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) {
|
||||
if (k == 0)
|
||||
continue;
|
||||
if (symp->st_shndx == STN_UNDEF && ELF32_ST_BIND(symp->st_info) != STB_WEAK) {
|
||||
if (symp->st_shndx == STN_UNDEF && ELF_ST_BIND(symp->st_info) != STB_WEAK) {
|
||||
ctr++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1072,14 +1143,14 @@ int ELF_(r_bin_elf_get_symbols)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_symbol *symb
|
|||
for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) {
|
||||
if (k == 0)
|
||||
continue;
|
||||
if (symp->st_shndx != STN_UNDEF && ELF32_ST_TYPE(symp->st_info) != STT_SECTION && ELF32_ST_BIND(symp->st_info) != STB_WEAK) {
|
||||
if (symp->st_shndx != STN_UNDEF && ELF_ST_TYPE(symp->st_info) != STT_SECTION && ELF_ST_BIND(symp->st_info) != STB_WEAK) {
|
||||
symbolp->size = (u64)symp->st_size;
|
||||
memcpy(symbolp->name, &string[symp->st_name], ELF_NAME_LENGTH);
|
||||
symbolp->name[ELF_NAME_LENGTH-1] = '\0';
|
||||
symbolp->offset = (u64)symp->st_value + sym_offset;
|
||||
if (symbolp->offset >= bin->base_addr)
|
||||
symbolp->offset -= bin->base_addr;
|
||||
switch (ELF32_ST_BIND(symp->st_info)) {
|
||||
switch (ELF_ST_BIND(symp->st_info)) {
|
||||
case STB_LOCAL: snprintf(symbolp->bind, ELF_NAME_LENGTH, "LOCAL"); break;
|
||||
case STB_GLOBAL: snprintf(symbolp->bind, ELF_NAME_LENGTH, "GLOBAL"); break;
|
||||
case STB_NUM: snprintf(symbolp->bind, ELF_NAME_LENGTH, "NUM"); break;
|
||||
|
|
@ -1089,7 +1160,7 @@ int ELF_(r_bin_elf_get_symbols)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_symbol *symb
|
|||
case STB_HIPROC: snprintf(symbolp->bind, ELF_NAME_LENGTH, "HIPROC"); break;
|
||||
default: snprintf(symbolp->bind, ELF_NAME_LENGTH, "UNKNOWN");
|
||||
}
|
||||
switch (ELF32_ST_TYPE(symp->st_info)) {
|
||||
switch (ELF_ST_TYPE(symp->st_info)) {
|
||||
case STT_NOTYPE: snprintf(symbolp->type, ELF_NAME_LENGTH, "NOTYPE"); break;
|
||||
case STT_OBJECT: snprintf(symbolp->type, ELF_NAME_LENGTH, "OBJECT"); break;
|
||||
case STT_FUNC: snprintf(symbolp->type, ELF_NAME_LENGTH, "FUNC"); break;
|
||||
|
|
@ -1144,7 +1215,7 @@ int ELF_(r_bin_elf_get_symbols_count)(ELF_(r_bin_elf_obj) *bin)
|
|||
for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) {
|
||||
if (k == 0)
|
||||
continue;
|
||||
if (symp->st_shndx != STN_UNDEF && ELF32_ST_TYPE(symp->st_info) != STT_SECTION && ELF32_ST_BIND(symp->st_info) != STB_WEAK)
|
||||
if (symp->st_shndx != STN_UNDEF && ELF_ST_TYPE(symp->st_info) != STT_SECTION && ELF_ST_BIND(symp->st_info) != STB_WEAK)
|
||||
ctr++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,41 @@
|
|||
02111-1307 USA. */
|
||||
|
||||
#undef ELF_
|
||||
#undef ELF_ST_BIND
|
||||
#undef ELF_ST_TYPE
|
||||
#undef ELF_ST_INFO
|
||||
#undef ELF_ST_VISIBILITY
|
||||
#undef ELF_ST_R_SYM
|
||||
#undef ELF_R_TYPE
|
||||
#undef ELF_R_INFO
|
||||
#undef ELF_M_SYM
|
||||
#undef ELF_M_SIZE
|
||||
#undef ELF_M_INFO
|
||||
|
||||
#ifdef R_BIN_ELF64
|
||||
#define ELF_(name) Elf64_##name
|
||||
#define ELF_(name) Elf64_##name
|
||||
#define ELF_ST_BIND ELF64_ST_BIND
|
||||
#define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
#define ELF_ST_INFO ELF64_ST_INFO
|
||||
#define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY
|
||||
#define ELF_R_SYM ELF64_R_SYM
|
||||
#define ELF_R_TYPE ELF64_R_TYPE
|
||||
#define ELF_R_INFO ELF64_R_INFO
|
||||
#define ELF_M_SYM ELF64_M_SYM
|
||||
#define ELF_M_SIZE ELF64_M_SIZE
|
||||
#define ELF_M_INFO ELF64_M_INFO
|
||||
#else
|
||||
#define ELF_(name) Elf32_##name
|
||||
#define ELF_ST_BIND ELF32_ST_BIND
|
||||
#define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
#define ELF_ST_INFO ELF32_ST_INFO
|
||||
#define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY
|
||||
#define ELF_R_SYM ELF32_R_SYM
|
||||
#define ELF_R_TYPE ELF32_R_TYPE
|
||||
#define ELF_R_INFO ELF32_R_INFO
|
||||
#define ELF_M_SYM ELF32_M_SYM
|
||||
#define ELF_M_SIZE ELF32_M_SIZE
|
||||
#define ELF_M_INFO ELF32_M_INFO
|
||||
#endif
|
||||
|
||||
#ifndef _INCLUDE_ELF_SPECS_H
|
||||
|
|
|
|||
Loading…
Reference in a new issue