Security
This commit is contained in:
123
main.c
123
main.c
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -305,15 +327,10 @@ void display_elf32(struct Elf32_Ehdr* header, FILE* fp)
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
check_dynamic32(header, fp);
|
||||
check_dynamic32(header, 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user