Files
RElicAnalysis/RElicAnalysis/elf.cpp
T
2026-05-01 15:19:10 +02:00

234 lines
7.0 KiB
C++

#include <stdlib.h>
#include <stdio.h>
#include <elf.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
struct elf_ident{
unsigned char arch;
unsigned char endianess;
unsigned char version;
unsigned char abi;
unsigned char vers_abi;
unsigned char padding[7];
unsigned char len;
} __attribute__((packed));
static int getSignature(int);
static void elf32(int, off_t, Elf32_Ehdr*);
static void elf64(int, off_t, Elf64_Ehdr*);
static void elf64ProgramHdr(int, Elf64_Off, off_t);
static void elf32ProgramHdr(int, Elf32_Off, off_t);
static void elf64SectionHdr(int, Elf64_Off, off_t);
static void elf32SectionHdr(int, Elf32_Off, off_t);
int main(int argc, char *argv[]){
struct stat st;
struct elf_ident *sElfIdent = NULL;
char buffer_ident[12] = {0};
int fd_r;
size_t length;
int res;
if (argc < 2){
printf("Please, specify the ELF file\n");
exit(-1);
}
/* Get stat information */
stat(argv[1], &st);
if ((fd_r = open(argv[1], O_RDONLY)) == -1){
printf("Failed to read the file %s\n", argv[1]);
exit(-1);
}
/* Get th 4 first bytes to get the signature */
res = getSignature(fd_r);
if (res == -1 || res == 0){
printf("Failed to get the signature of the file\n");
exit(-1);
}
/* Now, we get the 12 first bytes for the ELF identification */
length = read(fd_r, buffer_ident, 12);
sElfIdent = (struct elf_ident*)buffer_ident;
printf("ELF header information:\n");
printf("Arch:\t\t%d\n", sElfIdent->arch);
printf("Endianess:\t%d\n", sElfIdent->endianess);
printf("Version:\t%d\n", sElfIdent->version);
printf("ABI:\t\t%d\n", sElfIdent->abi);
printf("Version ABI:\t%d\n", sElfIdent->vers_abi);
/*printf("Padding: ");
for(int i = 0; i < 7; i++)
printf("%d ", sElfIdent->padding[i]);
printf("\n");*/
printf("Length:\t\t%d\n", sElfIdent->len);
// Now, get all the Elf header
lseek(fd_r, 0, SEEK_SET);
if (sElfIdent->arch == 1) { // Arch x82
char buffer[sizeof(Elf32_Ehdr)]; // 52 bytes
length = read(fd_r, buffer, 52);
elf32(fd_r, st.st_size, (Elf32_Ehdr*)buffer);
}else if(sElfIdent->arch == 2) { // Arch x64
char buffer[sizeof(Elf64_Ehdr)]; // 64 bytes
length = read(fd_r, buffer, 64);
elf64(fd_r, st.st_size, (Elf64_Ehdr*)buffer);
}
close(fd_r);
}
/*
* This function get the signature to be sure if the file is a ELF
*/
static int getSignature(int fd) {
char buffer[4];
size_t length = read(fd, buffer, 4);
if (length == -1)
return -1;
/*if (strcmp(buffer, "\x7f\x45\x4c\x46") == 0){
printf("ELF\n");
}*/
if (buffer[0] == 0x7f && buffer[1] == 0x45 && buffer[2] == 0x4c && buffer[3] == 0x46)
return 1;
return 0;
}
static void elf64(int fd, off_t fileLen, Elf64_Ehdr *ehdr){
size_t len = fileLen - sizeof(Elf64_Ehdr);
char buffer[len];
printf("Type: %d\n", ehdr->e_type);
printf("Machine: %d\n", ehdr->e_machine);
printf("Version: %d\n", ehdr->e_version);
printf("entry: %d\n", ehdr->e_entry);
printf("Phoff: %d\n", ehdr->e_phoff);
printf("Shoff: %d\n", ehdr->e_shoff);
printf("Flags: %d\n", ehdr->e_flags);
printf("Ehsize: %d\n", ehdr->e_ehsize);
printf("Phentsize: %d\n", ehdr->e_phentsize);
printf("Phnum: %d\n", ehdr->e_phnum);
printf("ShEntSize: %d\n", ehdr->e_shentsize);
printf("ShNum: %d\n", ehdr->e_shnum);
printf("Shstrndx: %d\n", ehdr->e_shstrndx);
// Read the rest of the file
//printf("%d\n", len);
//read(fd, buffer, len);
/*for (int i = 0; i < len; i++)
printf("%02x ", buffer[i]);*/
// Get program headers
elf64ProgramHdr(fd, ehdr->e_phoff, ehdr->e_phnum);
// Get section headers
elf64SectionHdr(fd, ehdr->e_shoff, ehdr->e_phnum);
}
static void elf32(int fd, off_t fileLen, Elf32_Ehdr *ehdr){
size_t len = fileLen - sizeof(Elf32_Ehdr);
char buffer[len];
printf("Type: %d\n", ehdr->e_type);
printf("Machine: %d\n", ehdr->e_machine);
printf("Version: %d\n", ehdr->e_version);
printf("entry: %d\n", ehdr->e_entry);
printf("Phoff: %d\n", ehdr->e_phoff);
printf("Shoff: %d\n", ehdr->e_shoff);
printf("Flags: %d\n", ehdr->e_flags);
printf("Ehsize: %d\n", ehdr->e_ehsize);
printf("Phentsize: %d\n", ehdr->e_phentsize);
printf("Phnum: %d\n", ehdr->e_phnum);
printf("ShEntSize: %d\n", ehdr->e_shentsize);
printf("ShNum: %d\n", ehdr->e_shnum);
printf("Shstrndx: %d\n", ehdr->e_shstrndx);
// Get program headers
elf32ProgramHdr(fd, ehdr->e_phoff, ehdr->e_phnum);
}
static void elf64ProgramHdr(int fd, Elf64_Off phoff, off_t phnum){
printf("%ld\n", sizeof(Elf64_Phdr)); // 56 bytes
size_t len = sizeof(Elf64_Phdr);
char buf[len];
// Go to the program header part
lseek(fd, phoff, SEEK_SET);
for (int i = 0; i < phnum; i++){
read(fd, buf, len);
Elf64_Phdr *phdr = (Elf64_Phdr*)buf;
printf("\nProgram header\n");
printf("Type: %d\n", phdr->p_type);
printf("Offset: %d\n", phdr->p_offset);
printf("Vaddr: %d\n", phdr->p_vaddr);
printf("Paddr: %d\n", phdr->p_paddr);
printf("File size: %d\n", phdr->p_filesz);
printf("Mem size: %d\n", phdr->p_memsz);
printf("Flags: %d\n", phdr->p_flags);
printf("Align: %d\n", phdr->p_align);
memset(buf, 0, len);
}
}
static void elf32ProgramHdr(int fd, Elf32_Off phoff, off_t phnum){
size_t len = sizeof(Elf32_Phdr);
char buf[len];
// Go to the program header part
lseek(fd, phoff, SEEK_SET);
for (int i = 0; i < phnum; i++){
read(fd, buf, len);
Elf32_Phdr *phdr = (Elf32_Phdr*)buf;
printf("\nProgram header\n");
printf("Type: %d\n", phdr->p_type);
printf("Offset: %d\n", phdr->p_offset);
printf("Vaddr: %d\n", phdr->p_vaddr);
printf("Paddr: %d\n", phdr->p_paddr);
printf("File size: %d\n", phdr->p_filesz);
printf("Mem size: %d\n", phdr->p_memsz);
printf("Flags: %d\n", phdr->p_flags);
printf("Align: %d\n", phdr->p_align);
memset(buf, 0, len);
}
}
static void elf64SectionHdr(int fd, Elf64_Off phoff, off_t shnum){
size_t len = sizeof(Elf64_Shdr);
char buf[len];
// Go to the program header part
lseek(fd, phoff, SEEK_SET);
for (int i = 0; i < shnum; i++){
read(fd, buf, len);
Elf64_Shdr *shdr = (Elf64_Shdr*)buf;
printf("\nSection header\n");
printf("Name: %d\n", shdr->sh_name);
printf("Type: %d\n", shdr->sh_type);
memset(buf, 0, len);
}
}
static void elf32SectionHdr(int fd, Elf32_Off phoff, off_t shnum){
size_t len = sizeof(Elf32_Shdr);
char buf[len];
// Go to the program header part
lseek(fd, phoff, SEEK_SET);
for (int i = 0; i < shnum; i++){
read(fd, buf, len);
Elf32_Shdr *shdr = (Elf32_Shdr*)buf;
printf("\nSection header\n");
memset(buf, 0, len);
}
}