Security
This commit is contained in:
121
main.c
121
main.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user