This commit is contained in:
2025-09-06 12:40:00 +02:00
parent f3496b103e
commit f2cf13b420
3 changed files with 101 additions and 22 deletions

BIN
a.out

Binary file not shown.

BIN
helpelf

Binary file not shown.

121
main.c
View File

@@ -172,7 +172,11 @@ int parse_elf_header64(struct Elf64_Ehdr* header, FILE* fp)
int read_elf_magic(FILE* fp)
{
char buf[5] = {0};
fread(buf, 1, 4, fp);
if (!fread(buf, 1, 4, fp))
{
puts("Read error.");
exit(-EIO);
}
if (memcmp(buf, "\177ELF", 4) == 0) return 1;
return 0;
}
@@ -206,7 +210,16 @@ void check_dynamic32(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));
fread(p_headers, sizeof(struct Elf32_Phdr), header->e_phnum, fp);
if (!p_headers)
{
puts("Memory allocation error.");
exit(-ENOMEM);
}
if (!fread(p_headers, sizeof(struct Elf32_Phdr), header->e_phnum, fp))
{
puts("Read error.");
exit(-EIO);
}
const char* interpstr = NULL;
@@ -218,8 +231,17 @@ void check_dynamic32(struct Elf32_Ehdr* header, FILE* fp)
// Get interpreter path
interpstr = malloc(p_headers[i].p_filesz);
if (!interpstr)
{
puts("Memory allocation error.");
exit(-ENOMEM);
}
fseek(fp, p_headers[i].p_offset, SEEK_SET);
fread((char*)interpstr, 1, p_headers[i].p_filesz, fp);
if (!fread((char*)interpstr, 1, p_headers[i].p_filesz, fp))
{
puts("Read error.");
exit(-EIO);
}
break;
}
}
@@ -309,11 +331,6 @@ void display_elf32(struct Elf32_Ehdr* header, FILE* fp)
}
}
void check_nx32(struct Elf32_Ehdr* header, FILE* fp)
{
}
void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
{
/* NX:
@@ -324,7 +341,11 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
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 (!fread(&p_header, 1, sizeof(struct Elf32_Phdr), fp))
{
puts("Read error.");
exit(-EIO);
}
if (p_header.p_type == PT_GNU_STACK)
{
if (p_header.p_flags & PF_X)
@@ -347,13 +368,31 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
// Read section headers
struct Elf32_Shdr *s_headers = malloc(header->e_shnum * sizeof(struct Elf32_Shdr));
fread(s_headers, sizeof(struct Elf32_Shdr), header->e_shnum, fp);
if (!s_headers)
{
puts("Memory allocation error.");
exit(-ENOMEM);
}
if (!fread(s_headers, sizeof(struct 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];
char* s_header_strtab = malloc(s_header_str.sh_size);
if (!s_header_strtab)
{
puts("Memory allocation error.");
exit(-ENOMEM);
}
fseek(fp, s_header_str.sh_offset, SEEK_SET);
fread(s_header_strtab, 1, s_header_str.sh_size, fp);
if (!fread(s_header_strtab, 1, s_header_str.sh_size, fp))
{
puts("Read error.");
exit(-EIO);
}
for (size_t i=0; i<header->e_shnum; i++)
{
@@ -365,14 +404,32 @@ 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);
if (!syms)
{
puts("Memory allocation error.");
exit(-EIO);
}
fseek(fp, s_headers[i].sh_offset, SEEK_SET);
fread(syms, s_headers[i].sh_size, 1, fp);
if (!fread(syms, s_headers[i].sh_size, 1, fp))
{
puts("Read error.");
exit(-EIO);
}
// load string table
struct Elf32_Shdr str_header = s_headers[s_headers[i].sh_link];
char* strtab = malloc(str_header.sh_size);
if (!strtab)
{
puts("Memory allocation error.");
exit(-ENOMEM);
}
fseek(fp, str_header.sh_offset, SEEK_SET);
fread(strtab, 1, str_header.sh_size, fp);
if (!fread(strtab, 1, str_header.sh_size, fp))
{
puts("Read error.");
exit(-EIO);
}
// iterate through symbols, check for __stack_chk_fail
for (size_t j=0; j<nsyms; j++)
@@ -393,7 +450,16 @@ 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));
fread (p_headers, sizeof(struct Elf32_Phdr), header->e_phnum, fp);
if (!p_headers)
{
puts("Memory allocation error.");
exit(-ENOMEM);
}
if (!fread (p_headers, sizeof(struct Elf32_Phdr), header->e_phnum, fp))
{
puts("Read error.");
exit(-EIO);
}
Elf32_Off dyn_off = 0;
Elf32_Word dyn_size = 0;
@@ -415,8 +481,17 @@ void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
{
int n = dyn_size / sizeof(struct Elf32_Dyn);
struct Elf32_Dyn *dyns = malloc(dyn_size);
if (!dyns)
{
puts("Memory allocation error.");
exit(-ENOMEM);
}
fseek(fp, dyn_off, SEEK_SET);
fread(dyns, sizeof(struct Elf32_Dyn), n, fp);
if (!fread(dyns, sizeof(struct Elf32_Dyn), n, fp))
{
puts("Read error.");
exit(-EIO);
}
for (int i=0; i<n; i++)
{
@@ -441,7 +516,11 @@ unsigned char read_elf_obj_size(FILE* fp)
{
unsigned char local_elf_obj_size = 0;
fseek(fp, 4, SEEK_SET);
fread(&local_elf_obj_size, 1, 1, fp);
if (!fread(&local_elf_obj_size, 1, 1, fp))
{
puts("Failed to read ELF object size");
exit(-EIO);
}
rewind(fp);
return local_elf_obj_size;
}
@@ -472,7 +551,7 @@ int main(int argc, char* argv[])
char* filename = argv[1];
if (!filename)
{
printf("Error parsing filename.\n");
puts("Error parsing filename.");
return -EINVAL;
}
@@ -486,7 +565,7 @@ int main(int argc, char* argv[])
int is_elf = read_elf_magic(elf_file);
if (!is_elf)
{
printf("Not a valid ELF file.\n");
puts("Not a valid ELF file.");
return -EINVAL;
}
@@ -501,7 +580,7 @@ int main(int argc, char* argv[])
struct Elf32_Ehdr elf32_header = {0};
if (parse_elf_header32(&elf32_header, elf_file))
{
printf("Failed to parse 32-bit ELF header\n");
puts("Failed to parse 32-bit ELF header");
return -EINVAL;
}
display_elf32(&elf32_header, elf_file);
@@ -511,13 +590,13 @@ int main(int argc, char* argv[])
struct Elf64_Ehdr elf64_header = {0};
if (parse_elf_header64(&elf64_header, elf_file))
{
printf("Failed to parse 64-bit ELF header\n");
puts("Failed to parse 64-bit ELF header");
return -EINVAL;
}
display_elf64(&elf64_header);
break;
default:
printf("Invalid ELF object size\n");
puts("Invalid ELF object size");
return -EINVAL;
}