275 lines
6 KiB
C
275 lines
6 KiB
C
#include <stdio.h>
|
|
|
|
#define BOOL int
|
|
#define true 1
|
|
#define false 0
|
|
|
|
#define ARCH32 1
|
|
#define ARCH64 2
|
|
|
|
#define ENDIANLITTLE 1
|
|
#define ENDIANBIG 2
|
|
|
|
#define ABI_UNDEFINED 0x00
|
|
#define ABI_HP_UX 0x01
|
|
#define ABI_NETBSD 0x02
|
|
#define ABI_LINUX 0x03
|
|
#define ABI_SOLARIS 0x06
|
|
#define ABI_AIX 0x07
|
|
#define ABI_IRIX 0x08
|
|
#define ABI_FREEBSD 0x09
|
|
#define ABI_OPENBSD 0x0C
|
|
#define ABI_OPENVMS 0x0D
|
|
#define ABI_NONSTOP_KERNEL 0x0E
|
|
#define ABI_AROS 0x0F
|
|
#define ABI_FENIX 0x10
|
|
#define ABI_CLOUDABI 0x11
|
|
#define ABI_SORTIX 0x53
|
|
|
|
#define TYPE_RELOCATABLE 1
|
|
#define TYPE_EXECUTABLE 2
|
|
#define TYPE_SHARED 3
|
|
#define TYPE_CORE 4
|
|
|
|
#define ISA_UNDEFINED 0x00
|
|
#define ISA_SPARC 0x02
|
|
#define ISA_X86 0x03
|
|
#define ISA_MIPS 0x08
|
|
#define ISA_POWERPC 0x14
|
|
#define ISA_ARM 0x28
|
|
#define ISA_SUPERH 0x2A
|
|
#define ISA_IA64 0x32
|
|
#define ISA_X86_64 0x3E
|
|
#define ISA_AARCH64 0xB7
|
|
|
|
unsigned char freadbyte(FILE* fd) {
|
|
unsigned char byte;
|
|
fread(&byte,1,1,fd);
|
|
return byte;
|
|
}
|
|
|
|
void fskip(FILE* fd, int num) {
|
|
fseek(fd, num, SEEK_CUR);
|
|
}
|
|
|
|
long freadword(FILE* fd, int arch) {
|
|
long word = 0;
|
|
if(arch == 64) {
|
|
word += (long)freadbyte(fd) << 56;
|
|
word += (long)freadbyte(fd) << 48;
|
|
word += (long)freadbyte(fd) << 40;
|
|
word += (long)freadbyte(fd) << 32;
|
|
}
|
|
word += (long)freadbyte(fd) << 24;
|
|
word += (long)freadbyte(fd) << 16;
|
|
word += (long)freadbyte(fd) << 8;
|
|
word += (long)freadbyte(fd);
|
|
return word;
|
|
}
|
|
|
|
BOOL check_magicnum(FILE* fd) {
|
|
if(freadbyte(fd) != 0x7F) return false;
|
|
if(freadbyte(fd) != 'E') return false;
|
|
if(freadbyte(fd) != 'L') return false;
|
|
if(freadbyte(fd) != 'F') return false;
|
|
return true;
|
|
}
|
|
|
|
short get_arch(FILE* fd) {
|
|
unsigned char byte = freadbyte(fd);
|
|
if(byte == ARCH32) {
|
|
printf("Arch: 32 bit\n");
|
|
} else if(byte == ARCH64) {
|
|
printf("Arch: 64 bit\n");
|
|
} else {
|
|
printf("Arch: unknown\n");
|
|
}
|
|
return byte;
|
|
}
|
|
|
|
void get_endian(FILE* fd) {
|
|
unsigned char byte = freadbyte(fd);
|
|
if(byte == ENDIANLITTLE) {
|
|
printf("Endian: Little\n");
|
|
} else if(byte == ENDIANBIG) {
|
|
printf("Endian: Big\n");
|
|
} else {
|
|
printf("Endian: Unknown\n");
|
|
}
|
|
}
|
|
|
|
void get_version(FILE* fd) {
|
|
unsigned char byte = freadbyte(fd);
|
|
printf("ELF-Version: %X\n",byte);
|
|
}
|
|
|
|
void get_abi(FILE* fd) {
|
|
unsigned char abi = freadbyte(fd);
|
|
printf("ABI: ");
|
|
switch(abi) {
|
|
case ABI_UNDEFINED:
|
|
printf("Not specified");
|
|
break;
|
|
case ABI_HP_UX:
|
|
printf("HP-UX");
|
|
break;
|
|
case ABI_NETBSD:
|
|
printf("NetBSD");
|
|
break;
|
|
case ABI_LINUX:
|
|
printf("Linux");
|
|
break;
|
|
case ABI_SOLARIS:
|
|
printf("Solaris");
|
|
break;
|
|
case ABI_AIX:
|
|
printf("AIX");
|
|
break;
|
|
case ABI_IRIX:
|
|
printf("IRIX");
|
|
break;
|
|
case ABI_FREEBSD:
|
|
printf("FreeBSD");
|
|
break;
|
|
case ABI_OPENBSD:
|
|
printf("OpenBSD");
|
|
break;
|
|
case ABI_OPENVMS:
|
|
printf("OpenVMS");
|
|
break;
|
|
case ABI_NONSTOP_KERNEL:
|
|
printf("NonStop Kernel");
|
|
break;
|
|
case ABI_AROS:
|
|
printf("AROS");
|
|
break;
|
|
case ABI_FENIX:
|
|
printf("Fenix OS");
|
|
break;
|
|
case ABI_CLOUDABI:
|
|
printf("CloudABI");
|
|
break;
|
|
case ABI_SORTIX:
|
|
printf("Sortix");
|
|
break;
|
|
default:
|
|
printf("Unknown");
|
|
break;
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
void get_type(FILE* fd) {
|
|
unsigned char type = freadbyte(fd);
|
|
printf("ELF Type: ");
|
|
switch(type) {
|
|
case TYPE_RELOCATABLE:
|
|
printf("Relocatable");
|
|
break;
|
|
case TYPE_EXECUTABLE:
|
|
printf("Executable");
|
|
break;
|
|
case TYPE_SHARED:
|
|
printf("Shared");
|
|
break;
|
|
case TYPE_CORE:
|
|
printf("Core");
|
|
break;
|
|
default:
|
|
printf("unknown");
|
|
break;
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void get_machine(FILE* fd) {
|
|
unsigned char machine = freadbyte(fd);
|
|
printf("ISA: ");
|
|
switch(machine) {
|
|
case ISA_UNDEFINED:
|
|
printf("Undefined");
|
|
break;
|
|
case ISA_SPARC:
|
|
printf("Sparc");
|
|
break;
|
|
case ISA_X86:
|
|
printf("x86");
|
|
break;
|
|
case ISA_MIPS:
|
|
printf("MIPS");
|
|
break;
|
|
case ISA_POWERPC:
|
|
printf("PowerPC");
|
|
break;
|
|
case ISA_ARM:
|
|
printf("ARM");
|
|
break;
|
|
case ISA_SUPERH:
|
|
printf("SuperH");
|
|
break;
|
|
case ISA_IA64:
|
|
printf("IA-64");
|
|
break;
|
|
case ISA_X86_64:
|
|
printf("x86_64");
|
|
break;
|
|
case ISA_AARCH64:
|
|
printf("AArch64");
|
|
break;
|
|
default:
|
|
printf("Unknown");
|
|
break;
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void get_entry_point(FILE* fd, int arch) {
|
|
long epoint = freadword(fd,arch);
|
|
printf("Entry Point: 0x%X\n",epoint);
|
|
}
|
|
|
|
void get_program_header(FILE* fd, int arch) {
|
|
long phoff = freadword(fd,arch);
|
|
printf("Program Header: 0x%X\n",phoff);
|
|
}
|
|
|
|
void get_section_header(FILE* fd, int arch) {
|
|
long shoff = freadword(fd,arch);
|
|
printf("Section Header: 0x%X\n",shoff);
|
|
}
|
|
|
|
void read_elf(FILE* fd) {
|
|
short arch = get_arch(fd);
|
|
get_endian(fd);
|
|
get_version(fd);
|
|
get_abi(fd);
|
|
fskip(fd,8);
|
|
get_type(fd);
|
|
get_machine(fd);
|
|
fskip(fd,4);
|
|
get_entry_point(fd,arch);
|
|
get_program_header(fd,arch);
|
|
get_section_header(fd,arch);
|
|
}
|
|
|
|
int main( int argc, char *argv[] ) {
|
|
if(argc <= 1) {
|
|
printf("Usage: %s <exacutable>\n",argv[0]);
|
|
return 1;
|
|
}
|
|
char* filename = argv[1];
|
|
|
|
FILE* fd = fopen(filename,"rb");
|
|
|
|
if(!check_magicnum(fd)) {
|
|
printf("Error: not a ELF-File\n");
|
|
} else {
|
|
printf("-- ELF Format detected\n");
|
|
read_elf(fd);
|
|
}
|
|
|
|
fclose(fd);
|
|
|
|
return 0;
|
|
}
|