Remove useless data structures to use elf.h

This commit is contained in:
2025-09-06 12:45:47 +02:00
parent f2cf13b420
commit 97bcd5eda7
3 changed files with 25 additions and 133 deletions

BIN
a.out

Binary file not shown.

BIN
helpelf

Binary file not shown.

158
main.c
View File

@@ -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");