diff --git a/a.out b/a.out index 7910224..4ab547b 100755 Binary files a/a.out and b/a.out differ diff --git a/helpelf b/helpelf index c64aa80..35485ea 100755 Binary files a/helpelf and b/helpelf differ diff --git a/main.c b/main.c index e1b78a2..92d0d60 100644 --- a/main.c +++ b/main.c @@ -32,33 +32,7 @@ #include #include #include - -// Data structures as per ELF specification: -// https://refspecs.linuxfoundation.org/elf/elf.pdf -// Only what we need (no elf.h) - -#define MAX_FILENAME 256 -#define EI_NIDENT 16 -#define MAX_HEADER_LEN 2048 -#define PF_X 1 -#define PT_GNU_STACK 0x6474e551 -#define SHT_DYNSYM 11 -#define SHT_SYMTAB 2 -#define PT_GNU_RELRO 0x6474e552 -#define PT_DYNAMIC 2 -#define DT_BIND_NOW 24 -#define PT_INTERP 3 - -#define Elf32_Half uint16_t -#define Elf32_Word uint32_t -#define Elf32_Sword int32_t -#define Elf32_Addr uint32_t -#define Elf32_Off uint32_t - -#define Elf64_Half uint32_t -#define Elf64_Word uint64_t -#define Elf64_Addr uint64_t -#define Elf64_Off uint64_t +#include bool verbose = false; bool pie = false; @@ -69,100 +43,18 @@ bool bind_now = false; bool stripped = true; bool interp = false; -struct Elf32_Ehdr +int parse_elf_header32(Elf32_Ehdr* header, FILE* fp) { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -}; - -struct Elf32_Phdr -{ - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -}; - -struct Elf32_Shdr -{ - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -}; - -struct Elf32_Sym -{ - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; -}; - -struct Elf32_Dyn -{ - Elf32_Sword d_tag; - union - { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - -struct Elf64_Ehdr -{ - unsigned char e_ident[EI_NIDENT]; - Elf64_Half e_type; - Elf64_Half e_machine; - Elf64_Word e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - Elf64_Word e_flags; - Elf64_Half e_ehsize; - Elf64_Half e_phentsize; - Elf64_Half e_phnum; - Elf64_Half e_shentsize; - Elf64_Half e_shnum; - Elf64_Half e_shstrndx; -}; - -int parse_elf_header32(struct Elf32_Ehdr* header, FILE* fp) -{ - if (!fread(header, sizeof(struct Elf32_Ehdr), 1, fp)) + if (!fread(header, sizeof(Elf32_Ehdr), 1, fp)) { return -EINVAL; } return 0; } -int parse_elf_header64(struct Elf64_Ehdr* header, FILE* fp) +int parse_elf_header64(Elf64_Ehdr* header, FILE* fp) { - if (!fread(header, sizeof(struct Elf64_Ehdr), 1, fp)) + if (!fread(header, sizeof(Elf64_Ehdr), 1, fp)) { return -EINVAL; } @@ -204,18 +96,18 @@ void display_elf_common(unsigned char e_ident[EI_NIDENT]) } } -void check_dynamic32(struct Elf32_Ehdr* header, FILE* fp) +void check_dynamic32(Elf32_Ehdr* header, FILE* fp) { // Is dynamically linked? (has PT_INTERP program header?) // read program headers fseek(fp, header->e_phoff, SEEK_SET); - struct Elf32_Phdr *p_headers = malloc(header->e_phnum * sizeof(struct Elf32_Phdr)); + Elf32_Phdr *p_headers = malloc(header->e_phnum * sizeof(Elf32_Phdr)); if (!p_headers) { puts("Memory allocation error."); exit(-ENOMEM); } - if (!fread(p_headers, sizeof(struct Elf32_Phdr), header->e_phnum, fp)) + if (!fread(p_headers, sizeof(Elf32_Phdr), header->e_phnum, fp)) { puts("Read error."); exit(-EIO); @@ -256,7 +148,7 @@ void check_dynamic32(struct Elf32_Ehdr* header, FILE* fp) } } -void display_elf32(struct Elf32_Ehdr* header, FILE* fp) +void display_elf32(Elf32_Ehdr* header, FILE* fp) { printf("32-bit ELF "); display_elf_common(header->e_ident); @@ -331,7 +223,7 @@ void display_elf32(struct Elf32_Ehdr* header, FILE* fp) } } -void check_sec32(struct Elf32_Ehdr* header, FILE* fp) +void check_sec32(Elf32_Ehdr* header, FILE* fp) { /* NX: * Browse thru program header table (e_phnum items) from e_phoff (program header offset) @@ -340,8 +232,8 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp) fseek(fp, header->e_phoff, SEEK_SET); for (size_t i=0; ie_phnum; i++) { - struct Elf32_Phdr p_header; - if (!fread(&p_header, 1, sizeof(struct Elf32_Phdr), fp)) + Elf32_Phdr p_header; + if (!fread(&p_header, 1, sizeof(Elf32_Phdr), fp)) { puts("Read error."); exit(-EIO); @@ -367,20 +259,20 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp) fseek(fp, header->e_shoff, SEEK_SET); // Read section headers - struct Elf32_Shdr *s_headers = malloc(header->e_shnum * sizeof(struct Elf32_Shdr)); + Elf32_Shdr *s_headers = malloc(header->e_shnum * sizeof(Elf32_Shdr)); if (!s_headers) { puts("Memory allocation error."); exit(-ENOMEM); } - if (!fread(s_headers, sizeof(struct Elf32_Shdr), header->e_shnum, fp)) + if (!fread(s_headers, sizeof(Elf32_Shdr), header->e_shnum, fp)) { puts("Read error."); exit(-EIO); } // Find section name string table (at e_shstrndx) and read it - struct Elf32_Shdr s_header_str = s_headers[header->e_shstrndx]; + Elf32_Shdr s_header_str = s_headers[header->e_shstrndx]; char* s_header_strtab = malloc(s_header_str.sh_size); if (!s_header_strtab) { @@ -403,7 +295,7 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp) { // load symbol table unsigned int nsyms = s_headers[i].sh_size / s_headers[i].sh_entsize; - struct Elf32_Sym *syms = malloc(s_headers[i].sh_size); + Elf32_Sym *syms = malloc(s_headers[i].sh_size); if (!syms) { puts("Memory allocation error."); @@ -417,7 +309,7 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp) } // load string table - struct Elf32_Shdr str_header = s_headers[s_headers[i].sh_link]; + Elf32_Shdr str_header = s_headers[s_headers[i].sh_link]; char* strtab = malloc(str_header.sh_size); if (!strtab) { @@ -449,13 +341,13 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp) // Read program headers fseek(fp, header->e_phoff, SEEK_SET); - struct Elf32_Phdr *p_headers = malloc(header->e_phnum * sizeof(struct Elf32_Phdr)); + Elf32_Phdr *p_headers = malloc(header->e_phnum * sizeof(Elf32_Phdr)); if (!p_headers) { puts("Memory allocation error."); exit(-ENOMEM); } - if (!fread (p_headers, sizeof(struct Elf32_Phdr), header->e_phnum, fp)) + if (!fread (p_headers, sizeof(Elf32_Phdr), header->e_phnum, fp)) { puts("Read error."); exit(-EIO); @@ -479,15 +371,15 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp) if (dyn_off && dyn_size) { - int n = dyn_size / sizeof(struct Elf32_Dyn); - struct Elf32_Dyn *dyns = malloc(dyn_size); + int n = dyn_size / sizeof(Elf32_Dyn); + Elf32_Dyn *dyns = malloc(dyn_size); if (!dyns) { puts("Memory allocation error."); exit(-ENOMEM); } fseek(fp, dyn_off, SEEK_SET); - if (!fread(dyns, sizeof(struct Elf32_Dyn), n, fp)) + if (!fread(dyns, sizeof(Elf32_Dyn), n, fp)) { puts("Read error."); exit(-EIO); @@ -506,7 +398,7 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp) } -void display_elf64(struct Elf64_Ehdr* header) +void display_elf64(Elf64_Ehdr* header) { printf("64-bit ELF "); display_elf_common(header->e_ident); @@ -577,7 +469,7 @@ int main(int argc, char* argv[]) switch(elf_obj_size) { case 0x01: - struct Elf32_Ehdr elf32_header = {0}; + Elf32_Ehdr elf32_header = {0}; if (parse_elf_header32(&elf32_header, elf_file)) { puts("Failed to parse 32-bit ELF header"); @@ -587,7 +479,7 @@ int main(int argc, char* argv[]) check_sec32(&elf32_header, elf_file); break; case 0x02: - struct Elf64_Ehdr elf64_header = {0}; + Elf64_Ehdr elf64_header = {0}; if (parse_elf_header64(&elf64_header, elf_file)) { puts("Failed to parse 64-bit ELF header");