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