ELF32: NX/PIE check

This commit is contained in:
2025-09-04 17:30:16 +02:00
parent f4361e77dc
commit 495b5a4d76
4 changed files with 151 additions and 16 deletions

BIN
a.out Executable file

Binary file not shown.

BIN
helpelf

Binary file not shown.

136
main.c
View File

@@ -31,10 +31,13 @@
#include <errno.h> #include <errno.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#define MAX_FILENAME 256 #define MAX_FILENAME 256
#define EI_NIDENT 16 #define EI_NIDENT 16
#define MAX_HEADER_LEN 2048 #define MAX_HEADER_LEN 2048
#define PF_X 1
#define PT_GNU_STACK 0x6474e551
#define Elf32_Half uint16_t #define Elf32_Half uint16_t
#define Elf32_Word uint32_t #define Elf32_Word uint32_t
@@ -46,6 +49,10 @@
#define Elf64_Addr uint64_t #define Elf64_Addr uint64_t
#define Elf64_Off uint64_t #define Elf64_Off uint64_t
bool verbose = false;
bool pie = false;
bool nx = false;
struct Elf32_Ehdr struct Elf32_Ehdr
{ {
unsigned char e_ident[EI_NIDENT]; unsigned char e_ident[EI_NIDENT];
@@ -64,6 +71,18 @@ struct Elf32_Ehdr
Elf32_Half e_shstrndx; 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 Elf64_Ehdr struct Elf64_Ehdr
{ {
unsigned char e_ident[EI_NIDENT]; unsigned char e_ident[EI_NIDENT];
@@ -108,8 +127,8 @@ int read_elf_magic(FILE* fp)
return 0; return 0;
} }
void display_elf_common(unsigned char e_ident[EI_NIDENT]) void display_elf_common(unsigned char e_ident[EI_NIDENT])
{ {
// EI_DATA // EI_DATA
switch(e_ident[5]) switch(e_ident[5])
{ {
@@ -124,14 +143,116 @@ void display_elf_common(unsigned char e_ident[EI_NIDENT])
exit(-EINVAL); exit(-EINVAL);
} }
if (verbose)
{
// EI_VERSION // EI_VERSION
printf("version %d", e_ident[6]); printf("version %d ", e_ident[6]);
}
} }
void display_elf32(struct Elf32_Ehdr* header) void display_elf32(struct Elf32_Ehdr* header)
{ {
printf("32-bit ELF "); printf("32-bit ELF ");
display_elf_common(header->e_ident); display_elf_common(header->e_ident);
switch (header->e_type)
{
case 0x00:
printf("(no file type),");
break;
case 0x01:
printf("(relocatable file),");
break;
case 0x02:
printf("(executable file),");
break;
case 0x03: // (ET_DYN, prob means PIE)
printf("(shared object file),");
pie = true;
break;
case 0x04:
printf("(core file),");
break;
default:
printf("(unknown),");
break;
}
switch (header->e_machine)
{
case 0x00:
printf("No architecture");
break;
case 0x01:
printf("AT&T WE 32100");
break;
case 0x02:
printf("SPARC");
break;
case 0x03:
printf("i386");
break;
case 0x04:
printf("Motorola 68000");
break;
case 0x05:
printf("Motorola 88000");
break;
case 0x07:
printf("Intel 80860");
break;
case 0x08:
printf("MIPS RS3000");
break;
case 0x09:
printf("MIPS RS4000");
break;
default:
printf("Unknown architecture");
break;
}
if (verbose)
{
printf("\ne_version: %d\n", header->e_version);
printf("e_entry: 0x%08x\n", header->e_entry);
printf("e_phoff: 0x%08x\n", header->e_phoff);
printf("e_shoff: 0x%08x\n", header->e_shoff);
printf("e_flags: 0x%08x\n", header->e_flags);
printf("e_ehsize: 0x%08x\n", header->e_ehsize);
printf("e_phentsize: 0x%08x\n", header->e_phentsize);
printf("e_phnum: 0x%08x\n", header->e_phnum);
printf("e_shentsize: 0x%08x\n", header->e_shentsize);
printf("e_shnum: 0x%08x\n", header->e_shnum);
printf("e_shstrndx: 0x%08x\n", header->e_shstrndx);
}
}
void check_sec32(struct Elf32_Ehdr* header, FILE* fp)
{
fseek(fp, header->e_phoff, SEEK_SET);
/*
* Browse thru program header table (e_phnum items) from e_phoff (program header offset)
* if its stack and has executable bit then we know NX isnt there
*/
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 (p_header.p_type == PT_GNU_STACK)
{
if (p_header.p_flags & PF_X)
{
nx = false;
}
else
{
nx = true;
}
}
}
} }
void display_elf64(struct Elf64_Ehdr* header) void display_elf64(struct Elf64_Ehdr* header)
@@ -149,6 +270,12 @@ unsigned char read_elf_obj_size(FILE* fp)
return local_elf_obj_size; return local_elf_obj_size;
} }
void display_sec_common()
{
printf("\nNX %s\n", nx ? "enabled" : "disabled");
printf("PIE %s\n", pie ? "enabled" : "disabled");
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
// Argument processing // Argument processing
@@ -192,6 +319,7 @@ int main(int argc, char* argv[])
return -EINVAL; return -EINVAL;
} }
display_elf32(&elf32_header); display_elf32(&elf32_header);
check_sec32(&elf32_header, elf_file);
break; break;
case 0x02: case 0x02:
struct Elf64_Ehdr elf64_header = {0}; struct Elf64_Ehdr elf64_header = {0};
@@ -207,5 +335,7 @@ int main(int argc, char* argv[])
return -EINVAL; return -EINVAL;
} }
display_sec_common();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@@ -4,5 +4,10 @@ all:
install: install:
sudo cp helpelf /usr/bin/helpelf sudo cp helpelf /usr/bin/helpelf
test:
make
gcc -m32 main.c
./helpelf a.out
clean: clean:
rm helpelf rm helpelf