diff --git a/a.out b/a.out new file mode 100755 index 0000000..f722c30 Binary files /dev/null and b/a.out differ diff --git a/helpelf b/helpelf index d32093b..37b3d93 100755 Binary files a/helpelf and b/helpelf differ diff --git a/main.c b/main.c index aebcc84..e7c0d53 100644 --- a/main.c +++ b/main.c @@ -31,10 +31,13 @@ #include #include #include +#include #define MAX_FILENAME 256 #define EI_NIDENT 16 #define MAX_HEADER_LEN 2048 +#define PF_X 1 +#define PT_GNU_STACK 0x6474e551 #define Elf32_Half uint16_t #define Elf32_Word uint32_t @@ -46,6 +49,10 @@ #define Elf64_Addr uint64_t #define Elf64_Off uint64_t +bool verbose = false; +bool pie = false; +bool nx = false; + struct Elf32_Ehdr { unsigned char e_ident[EI_NIDENT]; @@ -64,6 +71,18 @@ struct Elf32_Ehdr 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 Elf64_Ehdr { unsigned char e_ident[EI_NIDENT]; @@ -108,30 +127,132 @@ int read_elf_magic(FILE* fp) return 0; } -void display_elf_common(unsigned char e_ident[EI_NIDENT]) -{ - // EI_DATA - switch(e_ident[5]) + void display_elf_common(unsigned char e_ident[EI_NIDENT]) { - case 0x01: - printf("(LSB) "); - break; - case 0x02: - printf("(MSB) "); - break; - default: - printf("\nInvalid data encoding!\n"); - exit(-EINVAL); - } + // EI_DATA + switch(e_ident[5]) + { + case 0x01: + printf("(LSB) "); + break; + case 0x02: + printf("(MSB) "); + break; + default: + printf("\nInvalid data encoding!\n"); + exit(-EINVAL); + } - // EI_VERSION - printf("version %d", e_ident[6]); + + if (verbose) + { + // EI_VERSION + printf("version %d ", e_ident[6]); + } } void display_elf32(struct Elf32_Ehdr* header) { printf("32-bit ELF "); display_elf_common(header->e_ident); + + switch (header->e_type) + { + case 0x00: + printf("(no file type),"); + break; + case 0x01: + printf("(relocatable file),"); + break; + case 0x02: + printf("(executable file),"); + break; + case 0x03: // (ET_DYN, prob means PIE) + printf("(shared object file),"); + pie = true; + break; + case 0x04: + printf("(core file),"); + break; + default: + printf("(unknown),"); + break; + } + + switch (header->e_machine) + { + case 0x00: + printf("No architecture"); + break; + case 0x01: + printf("AT&T WE 32100"); + break; + case 0x02: + printf("SPARC"); + break; + case 0x03: + printf("i386"); + break; + case 0x04: + printf("Motorola 68000"); + break; + case 0x05: + printf("Motorola 88000"); + break; + case 0x07: + printf("Intel 80860"); + break; + case 0x08: + printf("MIPS RS3000"); + break; + case 0x09: + printf("MIPS RS4000"); + break; + default: + printf("Unknown architecture"); + break; + } + + if (verbose) + { + printf("\ne_version: %d\n", header->e_version); + printf("e_entry: 0x%08x\n", header->e_entry); + printf("e_phoff: 0x%08x\n", header->e_phoff); + printf("e_shoff: 0x%08x\n", header->e_shoff); + printf("e_flags: 0x%08x\n", header->e_flags); + printf("e_ehsize: 0x%08x\n", header->e_ehsize); + printf("e_phentsize: 0x%08x\n", header->e_phentsize); + printf("e_phnum: 0x%08x\n", header->e_phnum); + printf("e_shentsize: 0x%08x\n", header->e_shentsize); + printf("e_shnum: 0x%08x\n", header->e_shnum); + printf("e_shstrndx: 0x%08x\n", header->e_shstrndx); + } +} + +void check_sec32(struct Elf32_Ehdr* header, FILE* fp) +{ + fseek(fp, header->e_phoff, SEEK_SET); + + /* + * Browse thru program header table (e_phnum items) from e_phoff (program header offset) + * if its stack and has executable bit then we know NX isnt there + */ + for (size_t i=0; i < header->e_phnum; i++) + { + struct Elf32_Phdr p_header; + fread (&p_header, 1, sizeof(struct Elf32_Phdr), fp); + if (p_header.p_type == PT_GNU_STACK) + { + if (p_header.p_flags & PF_X) + { + nx = false; + } + else + { + nx = true; + } + } + } } void display_elf64(struct Elf64_Ehdr* header) @@ -149,6 +270,12 @@ unsigned char read_elf_obj_size(FILE* fp) return local_elf_obj_size; } +void display_sec_common() +{ + printf("\nNX %s\n", nx ? "enabled" : "disabled"); + printf("PIE %s\n", pie ? "enabled" : "disabled"); +} + int main(int argc, char* argv[]) { // Argument processing @@ -192,6 +319,7 @@ int main(int argc, char* argv[]) return -EINVAL; } display_elf32(&elf32_header); + check_sec32(&elf32_header, elf_file); break; case 0x02: struct Elf64_Ehdr elf64_header = {0}; @@ -207,5 +335,7 @@ int main(int argc, char* argv[]) return -EINVAL; } + display_sec_common(); + return EXIT_SUCCESS; } diff --git a/makefile b/makefile index 33629db..5f5a248 100644 --- a/makefile +++ b/makefile @@ -4,5 +4,10 @@ all: install: sudo cp helpelf /usr/bin/helpelf +test: + make + gcc -m32 main.c + ./helpelf a.out + clean: rm helpelf