123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- /*
- * Name: elfinfo
- * Version: 0.1.2
- * Description: Utility to print information about ELF files
- * Dependencies: bzbutil, bzbfile
- */
- #include "balzebub.h"
- #include <unistd.h>
- using namespace bzbterm;
- using namespace bzbio;
- using namespace bzbshell;
- using namespace bzbfile;
- EscSeq TITLE_COLOR = fg::bright_yellow;
- EscSeq DATA_COLOR = fg::bright_cyan;
- EscSeq HEADER_COLOR = fg::blue;
- constexpr int VERSION_MAJOR = 0;
- constexpr int VERSION_MINOR = 1;
- constexpr int VERSION_PATCH = 3;
- const char* PROGNAME = "elfinfo";
- void print_version_exit() {
- std::cout << PROGNAME << " v";
- std::cout << VERSION_MAJOR << "." <<
- VERSION_MINOR << "." <<
- VERSION_PATCH << std::endl;
- std::cout << "This program is part of the Balzebub project." << std::endl;
- exit(0);
- }
- void print_help_exit(int err = 0) {
- println("Usage: ", PROGNAME, " <filename> [ -no-color ]");
- println("Show information about an ELF file");
- println("-no-color\tPrint information without color escape codes");
- exit(err);
- }
- template<typename T>
- void print_elf_info(T elf_file) {
- print(TITLE_COLOR, "Class: ");
- if(elf_file.e_ident[ELF_EI_CLASS] == ELF_CLASS_32) {
- println(DATA_COLOR, "ELF32");
- } else if(elf_file.e_ident[ELF_EI_CLASS] == ELF_CLASS_64) {
- println(DATA_COLOR, "ELF64");
- } else {
- println(DATA_COLOR, "Unknown");
- }
- print(TITLE_COLOR, "Endianness: ");
- print(DATA_COLOR);
- if(elf_file.e_ident[ELF_EI_DATA] == ELF_LITTLE_ENDIAN) {
- print("Little Endian");
- } else if (elf_file.e_ident[ELF_EI_DATA] == ELF_BIG_ENDIAN) {
- print("Big Endian");
- } else {
- print("Unknown");
- }
- c_println();
- print(TITLE_COLOR, "ELF version: ");
- println(DATA_COLOR, (uint32_t) elf_file.e_ident[ELF_EI_VERSION]);
- print(TITLE_COLOR, "Target system: ");
- print(DATA_COLOR);
- switch(elf_file.e_ident[ELF_EI_OSABI]) {
- case ELF_ABI_SYSTEM_V: print("UNIX - System V (default)"); break;
- case ELF_ABI_HP_UX: print("HP-UX"); break;
- case ELF_ABI_NETBSD: print("NetBSD"); break;
- case ELF_ABI_LINUX: print("Linux"); break;
- case ELF_ABI_GNUHURD: print("GNU Hurd"); break;
- case ELF_ABI_SOLARIS: print("Solaris"); break;
- case ELF_ABI_AIX: print("AIX"); break;
- case ELF_ABI_IRIX: print("IRIX"); break;
- case ELF_ABI_FREEBSD: print("FreeBSD"); break;
- case ELF_ABI_TRU64: print("Tru64"); break;
- case ELF_ABI_NOVELL_MODESTO: print("Novell Modesto"); break;
- case ELF_ABI_OPENBSD: print("OpenBSD"); break;
- case ELF_ABI_OPENVMS: print("OpenVMS"); break;
- case ELF_ABI_NONSTOP_KERNEL: print("NonStop Kernel"); break;
- case ELF_ABI_AROS: print("AROS"); break;
- case ELF_ABI_FENIXOS: print("FenixOS"); break;
- case ELF_ABI_CLOUDABI: print("CloudABI"); break;
- default: print("Unknown"); break;
- }
- c_println();
- print(TITLE_COLOR, "ABI version: ");
- println(DATA_COLOR, (uint32_t) elf_file.e_ident[ELF_EI_ABIVERSION]);
- print(TITLE_COLOR, "Type:", " ");
- print(DATA_COLOR);
- switch(elf_file.e_type) {
- case ELF_ET_NONE: print("NONE (None)"); break;
- case ELF_ET_REL: print("REL (Relocatable file)"); break;
- case ELF_ET_EXEC: print("EXEC (Executable file)"); break;
- case ELF_ET_DYN: print("DYN (Shared object file)"); break;
- case ELF_ET_CORE: print("CORE (Core file)"); break;
- case ELF_ET_LOOS: print("LOOS (Operating system-specific)"); break;
- case ELF_ET_HIOS: print("HIOS (Operating system-specific)"); break;
- case ELF_ET_LOPROC: print("LOPROC (Processor-specific)"); break;
- case ELF_ET_HIPROC: print("HIPROC (Processor-specific)"); break;
- default: print("Unknown "); break;
- }
- c_println();
- print(TITLE_COLOR, "Target machine: ");
- print(DATA_COLOR);
- switch(elf_file.e_machine) {
- case ELF_ARCH_UNSPECIFIED: print("Unspecified"); break;
- case ELF_ARCH_SPARC: print("SPARC"); break;
- case ELF_ARCH_X86: print("x86"); break;
- case ELF_ARCH_MIPS: print("MIPS"); break;
- case ELF_ARCH_POWERPC: print("PowerPC"); break;
- case ELF_ARCH_S390: print("S390"); break;
- case ELF_ARCH_ARM: print("ARM"); break;
- case ELF_ARCH_SUPERH: print("SuperH"); break;
- case ELF_ARCH_IA_64: print("IA-64"); break;
- case ELF_ARCH_X86_64: print("x86-64"); break;
- case ELF_ARCH_AARCH64: print("AArch64"); break;
- case ELF_ARCH_RISC_V: print("RISC-V"); break;
- default: print("Unknown (0x", std::hex,
- elf_file.e_machine,
- std::dec, ")");
- }
- c_println();
- print(TITLE_COLOR, "Version: ");
- if(elf_file.e_version == 1) {
- println(DATA_COLOR, "1 (current)");
- } else {
- println(DATA_COLOR, elf_file.e_version, " (invalid)");
- }
- print(TITLE_COLOR, "Entry point: ");
- println(DATA_COLOR, "0x", std::hex, elf_file.e_entry, std::dec);
- print(TITLE_COLOR, "Program header offset: ");
- println(DATA_COLOR, elf_file.e_phoff);
- print(TITLE_COLOR, "Section header offset: ");
- println(DATA_COLOR, elf_file.e_shoff);
- print(TITLE_COLOR, "Flags: ");
- println(DATA_COLOR, std::hex, "0x", elf_file.e_flags, std::dec);
- print(TITLE_COLOR, "ELF header size: ");
- println(DATA_COLOR, elf_file.e_ehsize);
- print(TITLE_COLOR, "Program header entry size: ");
- println(DATA_COLOR, elf_file.e_phentsize);
- print(TITLE_COLOR, "Number of program headers: ");
- println(DATA_COLOR, elf_file.e_phnum);
- print(TITLE_COLOR, "Section header entry size: ");
- println(DATA_COLOR, elf_file.e_shentsize);
- print(TITLE_COLOR, "Number of section headers: ");
- println(DATA_COLOR, elf_file.e_shnum);
- print(TITLE_COLOR, "Section headers string table index: ");
- println(DATA_COLOR, elf_file.e_shstrndx);
- println(TITLE_COLOR, "Interpreter: ", DATA_COLOR, elf_file.interpreter);
- for(size_t i = 0; i < elf_file.prog_headers.size(); i++) {
- println(HEADER_COLOR, "\nProgram header number ", i);
- print(TITLE_COLOR, "Type:", " ");
- print(DATA_COLOR);
- switch(elf_file.prog_headers[i].p_type) {
- case ELF_PT_NULL: print("NULL (Unused)"); break;
- case ELF_PT_LOAD: print("LOAD (Loadable segment)"); break;
- case ELF_PT_DYNAMIC: print("DYNAMIC (Dynamic linking information)"); break;
- case ELF_PT_INTERP: print("INTERP (Interpreter)"); break;
- case ELF_PT_NOTE: print("NOTE (Notes)"); break;
- case ELF_PT_SHLIB: print("SHLIB (Invalid)"); break;
- case ELF_PT_PHDR: print("PHDR (Program header pointer)"); break;
- case ELF_PT_LOOS: print("LOOS (System specific)"); break;
- case ELF_PT_HIOS: print("HIOS (System specific)"); break;
- case ELF_PT_LOPROC: print("LOPROC (Processor specific)"); break;
- case ELF_PT_HIPROC: print("HIPROC (Processor specific)"); break;
- case ELF_PT_GNU_EH_FRAME: print("GNU_EH_FRAME"); break;
- case ELF_PT_GNU_STACK: print("GNU_STACK"); break;
- case ELF_PT_GNU_RELRO: print("GNU_RELRO"); break;
- default: print("Unknown (0x", std::hex,
- elf_file.prog_headers[i].p_type,
- std::dec, ")");
- }
- c_println();
- print(TITLE_COLOR, "Offset: ");
- println(DATA_COLOR, elf_file.prog_headers[i].p_offset);
- print(TITLE_COLOR, "Virtual Address: ");
- println(DATA_COLOR, "0x", std::hex, elf_file.prog_headers[i].p_vaddr, std::dec);
- print(TITLE_COLOR, "Physical Address: ");
- println(DATA_COLOR, "0x", std::hex, elf_file.prog_headers[i].p_paddr, std::dec);
- print(TITLE_COLOR, "Segment size in the image file (may be 0): ");
- println(DATA_COLOR, elf_file.prog_headers[i].p_filesz);
- print(TITLE_COLOR, "Segment size in memory (may be 0): ");
- println(DATA_COLOR, elf_file.prog_headers[i].p_memsz);
- print(TITLE_COLOR, "Alignment: ");
- println(DATA_COLOR, "0x", std::hex, elf_file.prog_headers[i].p_align, std::dec);
- print(TITLE_COLOR, "Flags: ");
- print(DATA_COLOR);
- if(elf_file.prog_headers[i].p_flags & ELF_PH_FLAG_READ) {
- print("R");
- } else {
- print("-");
- }
- if(elf_file.prog_headers[i].p_flags & ELF_PH_FLAG_WRITE) {
- print("W");
- } else {
- print("-");
- }
- if(elf_file.prog_headers[i].p_flags & ELF_PH_FLAG_EXEC) {
- print("X");
- } else {
- print("-");
- }
- c_println();
- }
- for(size_t i = 0; i < elf_file.sec_headers.size(); i++) {
- println(HEADER_COLOR, "\nSection header number ", i);
- println(TITLE_COLOR, "Name: ", DATA_COLOR, elf_file.sec_headers[i].name);
- println(TITLE_COLOR, "Name offset inside shstrtab: ", DATA_COLOR,
- "0x", std::hex, elf_file.sec_headers[i].sh_name, std::dec);
- print(TITLE_COLOR, "Type: ");
- print(DATA_COLOR);
- switch(elf_file.sec_headers[i].sh_type) {
- case ELF_SHT_NULL: print("NULL (Unused)"); break;
- case ELF_SHT_PROGBITS: print("PROGBITS (Program data)"); break;
- case ELF_SHT_SYMTAB: print("SYMTAB (Symbol table)"); break;
- case ELF_SHT_STRTAB: print("STRTAB (String table)"); break;
- case ELF_SHT_RELA: print("RELA (Relocation entries with addends)"); break;
- case ELF_SHT_HASH: print("HASH (Symbol hash table)"); break;
- case ELF_SHT_DYNAMIC: print("DYNAMIC (Dynamic linking information)"); break;
- case ELF_SHT_NOTE: print("NOTE (Notes)"); break;
- case ELF_SHT_NOBITS: print("NOBITS (Program space with no data, BSS)"); break;
- case ELF_SHT_REL: print("REL (Relocation entries without addends)"); break;
- case ELF_SHT_SHLIB: print("SHLIB (Reserved)"); break;
- case ELF_SHT_DYNSYM: print("DYNSYM (Dynamic linker symbol table)"); break;
- case ELF_SHT_INIT_ARRAY: print("INIT_ARRAY (Array of constructors)"); break;
- case ELF_SHT_FINI_ARRAY: print("FINI_ARRAY (Array of destructors)"); break;
- case ELF_SHT_PREINIT_ARRAY: print("PREINIT_ARRAY (// Array of pre-constructors)"); break;
- case ELF_SHT_GROUP: print("GROUP (Section group)"); break;
- case ELF_SHT_SYMTAB_SHNDX: print("SYMTAB_SHNDX (Extended section indices)"); break;
- case ELF_SHT_NUM: print("NUM (Number of defined types)"); break;
- case ELF_SHT_LOOS: print("LOOS (System specific)"); break;
- case ELF_SHT_HIOS: print("HIOS (System specific) or VERSYM (GNU)"); break;
- case ELF_SHT_LOPROC: print("LOPROC (Processor specific)"); break;
- case ELF_SHT_HIPROC: print("HIPROC (Processor specific)"); break;
- case ELF_SHT_LOUSER: print("LOUSER (Application specific)"); break;
- case ELF_SHT_HIUSER: print("HIUSER (Application specific)"); break;
- case ELF_SHT_GNU_HASH: print("GNU_HASH"); break;
- case ELF_SHT_VERNEED: print("VERNEED"); break;
- default: print("Unknown (0x", std::hex,
- elf_file.sec_headers[i].sh_type,
- std::dec, ")");
- }
- c_println();
- print(TITLE_COLOR, "Flags: ", DATA_COLOR);
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_WRITE) {
- print("W");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_ALLOC) {
- print("A");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_EXECINSTR) {
- print("X");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_MERGE) {
- print("M");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_STRINGS) {
- print("S");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_INFO_LINK) {
- print("I");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_LINK_ORDER) {
- print("L");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_OS_NONCONFORMING) {
- print("O");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_GROUP) {
- print("G");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_TLS) {
- print("T");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_COMPRESSED) {
- print("C");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_MASKOS) {
- print("o");
- }
- if(elf_file.sec_headers[i].sh_flags & ELF_SHF_MASKPROC) {
- print("p");
- }
- c_println();
- println(TITLE_COLOR, "Address: ",
- DATA_COLOR, "0x", std::hex, elf_file.sec_headers[i].sh_addr,
- std::dec);
- println(TITLE_COLOR, "Offset: ",
- DATA_COLOR, "0x", std::hex, elf_file.sec_headers[i].sh_offset,
- std::dec);
- println(TITLE_COLOR, "Size: ",
- DATA_COLOR, elf_file.sec_headers[i].sh_size);
- println(TITLE_COLOR, "Link: ",
- DATA_COLOR, elf_file.sec_headers[i].sh_link);
- println(TITLE_COLOR, "Info: ",
- DATA_COLOR, elf_file.sec_headers[i].sh_info);
- println(TITLE_COLOR, "Address alignment: ",
- DATA_COLOR, "0x", std::hex, elf_file.sec_headers[i].sh_addralign,
- std::dec);
- println(TITLE_COLOR, "Entry size: ",
- DATA_COLOR, elf_file.sec_headers[i].sh_entsize);
- }
- }
- int main(int argc, char const *argv[]) {
- if(argc < 2) {
- print_help_exit(1);
- }
- if(argc == 3) {
- std::string arg3 = argv[2];
- if(arg3 == "-no-color") {
- TITLE_COLOR = EscSeq("");
- DATA_COLOR = EscSeq("");
- HEADER_COLOR = EscSeq("");
- }
- }
- std::string filename = argv[1];
- if(filename == "--help" || filename == "-h") {
- print_help_exit(0);
- }
- if(filename == "--version" || filename == "-v") {
- print_version_exit();
- }
- if(!bzbfile::exists(filename)) {
- println(fg::red, "ERROR This file does not exist");
- exit(2);
- }
- uint8_t arch = bzbfile::get_elf_class(filename);
- if(arch == ELF_CLASS_32) {
- ELF32 elf_file(filename);
- print_elf_info(elf_file);
- } else if(arch == ELF_CLASS_64) {
- ELF64 elf_file(filename);
- print_elf_info(elf_file);
- } else {
- println(fg::red, "ERROR Malformed ELF file (EI_CLASS is uncorrect)");
- exit(3);
- }
- return 0;
- }
|