Remove useless data structures to use elf.h
This commit is contained in:
158
main.c
158
main.c
@@ -32,33 +32,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// 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 <elf.h>
|
||||
|
||||
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; i<header->e_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");
|
||||
|
||||
Reference in New Issue
Block a user