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 <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <elf.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
|
|
||||||
|
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool pie = false;
|
bool pie = false;
|
||||||
@@ -69,100 +43,18 @@ bool bind_now = false;
|
|||||||
bool stripped = true;
|
bool stripped = true;
|
||||||
bool interp = false;
|
bool interp = false;
|
||||||
|
|
||||||
struct Elf32_Ehdr
|
int parse_elf_header32(Elf32_Ehdr* header, FILE* fp)
|
||||||
{
|
{
|
||||||
unsigned char e_ident[EI_NIDENT];
|
if (!fread(header, sizeof(Elf32_Ehdr), 1, fp))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
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;
|
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?)
|
// Is dynamically linked? (has PT_INTERP program header?)
|
||||||
// read program headers
|
// read program headers
|
||||||
fseek(fp, header->e_phoff, SEEK_SET);
|
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)
|
if (!p_headers)
|
||||||
{
|
{
|
||||||
puts("Memory allocation error.");
|
puts("Memory allocation error.");
|
||||||
exit(-ENOMEM);
|
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.");
|
puts("Read error.");
|
||||||
exit(-EIO);
|
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 ");
|
printf("32-bit ELF ");
|
||||||
display_elf_common(header->e_ident);
|
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:
|
/* NX:
|
||||||
* Browse thru program header table (e_phnum items) from e_phoff (program header offset)
|
* 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);
|
fseek(fp, header->e_phoff, SEEK_SET);
|
||||||
for (size_t i=0; i<header->e_phnum; i++)
|
for (size_t i=0; i<header->e_phnum; i++)
|
||||||
{
|
{
|
||||||
struct Elf32_Phdr p_header;
|
Elf32_Phdr p_header;
|
||||||
if (!fread(&p_header, 1, sizeof(struct Elf32_Phdr), fp))
|
if (!fread(&p_header, 1, sizeof(Elf32_Phdr), fp))
|
||||||
{
|
{
|
||||||
puts("Read error.");
|
puts("Read error.");
|
||||||
exit(-EIO);
|
exit(-EIO);
|
||||||
@@ -367,20 +259,20 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
|
|||||||
fseek(fp, header->e_shoff, SEEK_SET);
|
fseek(fp, header->e_shoff, SEEK_SET);
|
||||||
|
|
||||||
// Read section headers
|
// 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)
|
if (!s_headers)
|
||||||
{
|
{
|
||||||
puts("Memory allocation error.");
|
puts("Memory allocation error.");
|
||||||
exit(-ENOMEM);
|
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.");
|
puts("Read error.");
|
||||||
exit(-EIO);
|
exit(-EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find section name string table (at e_shstrndx) and read it
|
// 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);
|
char* s_header_strtab = malloc(s_header_str.sh_size);
|
||||||
if (!s_header_strtab)
|
if (!s_header_strtab)
|
||||||
{
|
{
|
||||||
@@ -403,7 +295,7 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
|
|||||||
{
|
{
|
||||||
// load symbol table
|
// load symbol table
|
||||||
unsigned int nsyms = s_headers[i].sh_size / s_headers[i].sh_entsize;
|
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)
|
if (!syms)
|
||||||
{
|
{
|
||||||
puts("Memory allocation error.");
|
puts("Memory allocation error.");
|
||||||
@@ -417,7 +309,7 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load string table
|
// 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);
|
char* strtab = malloc(str_header.sh_size);
|
||||||
if (!strtab)
|
if (!strtab)
|
||||||
{
|
{
|
||||||
@@ -449,13 +341,13 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
|
|||||||
|
|
||||||
// Read program headers
|
// Read program headers
|
||||||
fseek(fp, header->e_phoff, SEEK_SET);
|
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)
|
if (!p_headers)
|
||||||
{
|
{
|
||||||
puts("Memory allocation error.");
|
puts("Memory allocation error.");
|
||||||
exit(-ENOMEM);
|
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.");
|
puts("Read error.");
|
||||||
exit(-EIO);
|
exit(-EIO);
|
||||||
@@ -479,15 +371,15 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
|
|||||||
|
|
||||||
if (dyn_off && dyn_size)
|
if (dyn_off && dyn_size)
|
||||||
{
|
{
|
||||||
int n = dyn_size / sizeof(struct Elf32_Dyn);
|
int n = dyn_size / sizeof(Elf32_Dyn);
|
||||||
struct Elf32_Dyn *dyns = malloc(dyn_size);
|
Elf32_Dyn *dyns = malloc(dyn_size);
|
||||||
if (!dyns)
|
if (!dyns)
|
||||||
{
|
{
|
||||||
puts("Memory allocation error.");
|
puts("Memory allocation error.");
|
||||||
exit(-ENOMEM);
|
exit(-ENOMEM);
|
||||||
}
|
}
|
||||||
fseek(fp, dyn_off, SEEK_SET);
|
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.");
|
puts("Read error.");
|
||||||
exit(-EIO);
|
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 ");
|
printf("64-bit ELF ");
|
||||||
display_elf_common(header->e_ident);
|
display_elf_common(header->e_ident);
|
||||||
@@ -577,7 +469,7 @@ int main(int argc, char* argv[])
|
|||||||
switch(elf_obj_size)
|
switch(elf_obj_size)
|
||||||
{
|
{
|
||||||
case 0x01:
|
case 0x01:
|
||||||
struct Elf32_Ehdr elf32_header = {0};
|
Elf32_Ehdr elf32_header = {0};
|
||||||
if (parse_elf_header32(&elf32_header, elf_file))
|
if (parse_elf_header32(&elf32_header, elf_file))
|
||||||
{
|
{
|
||||||
puts("Failed to parse 32-bit ELF header");
|
puts("Failed to parse 32-bit ELF header");
|
||||||
@@ -587,7 +479,7 @@ int main(int argc, char* argv[])
|
|||||||
check_sec32(&elf32_header, elf_file);
|
check_sec32(&elf32_header, elf_file);
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
struct Elf64_Ehdr elf64_header = {0};
|
Elf64_Ehdr elf64_header = {0};
|
||||||
if (parse_elf_header64(&elf64_header, elf_file))
|
if (parse_elf_header64(&elf64_header, elf_file))
|
||||||
{
|
{
|
||||||
puts("Failed to parse 64-bit ELF header");
|
puts("Failed to parse 64-bit ELF header");
|
||||||
|
|||||||
Reference in New Issue
Block a user