234 lines
7.0 KiB
C++
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);
|
|
}
|
|
}
|