From f0936e0d52bf7060f641e0589069edcbd950c3e2 Mon Sep 17 00:00:00 2001 From: gbrochar Date: Wed, 3 Apr 2024 14:45:17 +0200 Subject: [PATCH] wip: elf64 --- src/main.c | 2 +- src/nm.c | 264 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 225 insertions(+), 41 deletions(-) diff --git a/src/main.c b/src/main.c index 8b7f54e..dcdc37e 100644 --- a/src/main.c +++ b/src/main.c @@ -24,7 +24,7 @@ int main(int ac, char **av) { t_mapped_file mapped_file; - ft_printf("sds", "file size: ", stat.st_size, "\n"); +// ft_printf("sds", "file size: ", stat.st_size, "\n"); mapped_file.ptr = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); mapped_file.size = stat.st_size; if (mapped_file.ptr != MAP_FAILED) { diff --git a/src/nm.c b/src/nm.c index 8c0502a..f6f92b1 100644 --- a/src/nm.c +++ b/src/nm.c @@ -1,11 +1,14 @@ #include "ft_nm.h" -int nm32(t_mapped_file mapped_file) { - (void)mapped_file; - return FT_NM_SUCCESS; -} +void ppp(Elf64_Sym sym, Elf64_Shdr sec); +void print_section(Elf64_Shdr sec); +void print_symbol(Elf64_Sym sym); -char *get_sym_char(Elf64_Sym sym) { +char *get_sym_char(Elf64_Sym sym, Elf64_Shdr sec) { +// ppp(sym, sec); + if ((sec.sh_flags & SHF_COMPRESSED) == SHF_COMPRESSED) { + return ("N"); + } if (sym.st_shndx == SHN_ABS) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("a"); @@ -14,7 +17,127 @@ char *get_sym_char(Elf64_Sym sym) { return ("A"); } } - return ("T"); + if (ELF64_ST_TYPE(sym.st_info) == STT_GNU_IFUNC) { + return ("i"); + } + if (sec.sh_flags & SHF_EXECINSTR) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("t"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("T"); + } + } + if (sec.sh_type == SHT_NOBITS) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("b"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("B"); + } + } + if (sec.sh_type == SHT_PROGBITS && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("d"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("D"); + } + } + if (sec.sh_type == SHT_DYNAMIC && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("d"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("D"); + } + } + if (sec.sh_type == SHT_INIT_ARRAY && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("d"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("D"); + } + } + if (sec.sh_type == SHT_PREINIT_ARRAY && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("d"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("D"); + } + } + if (sec.sh_type == SHT_FINI_ARRAY && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("d"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("D"); + } + } + if (/*sec.sh_type == SHT_PROGBITS &&*/ sec.sh_flags & SHF_ALLOC) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("r"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("R"); + } + } + if (sec.sh_type == SHT_NOTE && sec.sh_flags == SHF_ALLOC) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("r"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("R"); + } + } + if (sym.st_shndx == SHN_COMMON) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("c"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("C"); + } + } + if (sym.st_shndx == SHN_UNDEF) { + if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { + return ("u"); + } + else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { + return ("U"); + } + } + if (ELF64_ST_BIND(sym.st_info) == STB_WEAK) { + if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT) { + if (sec.sh_type == SHT_NULL) { + return ("v"); + } + else { + return ("V"); + } + } else { + if (sec.sh_type == SHT_NULL) { + return ("w"); + } + else { + return ("W"); + } + } + } + if (ELF64_ST_BIND(sym.st_info) == STB_WEAK) { + if (sec.sh_type == SHT_NULL) { + return ("w"); + } + else { + print_symbol(sym); + print_section(sec); + return ("W"); + } + } + // if section name starts with .debug.... + // return ("N"); + return ("n"); } int nm64(t_mapped_file mapped_file) { @@ -22,23 +145,24 @@ int nm64(t_mapped_file mapped_file) { if (get_header64(mapped_file, &header) == FT_NM_FAILURE) { return FT_NM_FAILURE; } - printf("Header:\n"); - printf("Version: %d\n", header.e_version); - printf("Entry point: %ld\n", header.e_entry); - printf("Program header offset: "); - fflush(stdout); - ft_printf("X", header.e_phoff); - ft_putchar('\n'); - printf("Section header offset: "); - fflush(stdout); - ft_printf("X", header.e_shoff); - ft_putchar('\n'); - printf("Header size: %d\n", header.e_ehsize); - printf("Program header entry size: %d\n", header.e_phentsize); - printf("Program header num: %d\n", header.e_phnum); - printf("Section header entry size: %d\n", header.e_shentsize); - printf("Section header num: %d\n", header.e_shnum); - printf("Section header string table index: %d\n", header.e_shstrndx); + /* printf("Header:\n"); + printf("Version: %d\n", header.e_version); + printf("Entry point: %ld\n", header.e_entry); + printf("Program header offset: "); + fflush(stdout); + ft_printf("X", header.e_phoff); + ft_putchar('\n'); + printf("Section header offset: "); + fflush(stdout); + ft_printf("X", header.e_shoff); + ft_putchar('\n'); + printf("Header size: %d\n", header.e_ehsize); + printf("Program header entry size: %d\n", header.e_phentsize); + printf("Program header num: %d\n", header.e_phnum); + printf("Section header entry size: %d\n", header.e_shentsize); + printf("Section header num: %d\n", header.e_shnum); + printf("Section header string table index: %d\n", header.e_shstrndx); + */ /* for (int i = 0; i < header.e_phnum; i++) { uint64_t addr = header.e_phoff + header.e_phentsize * i; @@ -50,7 +174,7 @@ int nm64(t_mapped_file mapped_file) { ft_putstr(str); ft_putchar('\n'); } - */ + */ uint64_t addr = header.e_shoff + header.e_shentsize * header.e_shstrndx; //ft_printf("sX", "addr: ", addr); Elf64_Shdr shstrtb; @@ -64,24 +188,50 @@ int nm64(t_mapped_file mapped_file) { uint64_t addr2 = header.e_shoff + header.e_shentsize * sh.sh_link; Elf64_Shdr strtab; ft_memcpy(&strtab, mapped_file.ptr + addr2, header.e_shentsize); - ft_printf("sdsds", "SYMTAB Size: ", sh.sh_size, " Entity size: ", sh.sh_entsize, "\n"); - for (uint64_t j = 0; j < sh.sh_size; j += sh.sh_entsize) { + // ft_printf("sdsds", "SYMTAB Size: ", sh.sh_size, " Entity size: ", sh.sh_entsize, "\n"); + for (uint64_t j = sh.sh_entsize; j < sh.sh_size; j += sh.sh_entsize) { Elf64_Sym sym; + Elf64_Shdr sec; ft_memcpy(&sym, mapped_file.ptr + sh.sh_offset + j, sh.sh_entsize); - char *str = ft_strdup(mapped_file.ptr + strtab.sh_offset + sym.st_name); - //if (str[ft_strlen(str) - 1] == 'c') { - printf("st_name: %d\n", sym.st_name); - printf("st_info: %d\n", sym.st_info); - printf("st_other: %d\n", sym.st_other); - printf("st_shndx: %d\n", sym.st_shndx); - printf("st_value: %ld\n", sym.st_value); - printf("st_size: %ld\n", sym.st_size); - //} - if (sym.st_value) { - ft_printf("X s ss", sym.st_value, get_sym_char(sym), str, "\n"); - } else { - ft_printf("P s ss", get_sym_char(sym), mapped_file.ptr + strtab.sh_offset + sym.st_name, "\n"); + // printf("st_shndx: %d\n", sym.st_shndx); + if (sym.st_shndx < header.e_shnum) { + ft_memcpy(&sec, mapped_file.ptr + header.e_shoff + header.e_shentsize * sym.st_shndx, header.e_shentsize); } + char *str; + if (sym.st_name) { + str = ft_strdup(mapped_file.ptr + strtab.sh_offset + sym.st_name); + } + else { + //printf("good\n"); + Elf64_Shdr shdr; + //print_symbol(sym); + if (sym.st_shndx != SHN_ABS) { + ft_memcpy(&shdr, mapped_file.ptr + header.e_shoff + header.e_shentsize * sym.st_shndx, header.e_shentsize); + //print_section(shdr); + //ft_printf("sxs", "sh string table ", shstrtb.sh_offset, "\n"); + str = ft_strdup(mapped_file.ptr + shstrtb.sh_offset + shdr.sh_name); + //str = ft_strdup("TOTOTOTOTO"); + //str = ft_strdup(mapped_file.ptr + shdr.sh_offset + sec.sh_name); + } else { + str = ft_strdup(""); + } + } + //if (str[ft_strlen(str) - 1] == 'c') { + /* + */ + //} + char *sym_char = ft_strdup(get_sym_char(sym, sec)); + if (sym.st_value) { + ft_printf("X s ss", sym.st_value, sym_char, str, "\n"); + } else { + if (ft_strcmp(sym_char, "U") && ft_strcmp(sym_char, "w") && ft_strcmp(sym_char, "v")) { + ft_printf("X s ss", sym.st_value, sym_char, str, "\n"); + } else { + //ft_printf("P s ss", sym_char, mapped_file.ptr + strtab.sh_offset + sym.st_name, "\n"); + ft_printf("P s ss", sym_char, str, "\n"); + } + } + fflush(stdout); } } /*ft_printf("X", sh.sh_offset); @@ -90,10 +240,44 @@ int nm64(t_mapped_file mapped_file) { ft_putchar('\n');*/ char *str = ft_strdup(mapped_file.ptr + shstrtb.sh_offset + sh.sh_name); //ft_putstr(str); - ft_printf("x x x ss", sh.sh_name, sh.sh_offset, addr, str, "\n"); + // ft_printf("x x x ss", sh.sh_name, sh.sh_offset, addr, str, "\n"); free(str); //ft_putchar('\n'); } return FT_NM_SUCCESS; } +void print_symbol(Elf64_Sym sym) { + printf("st_name: %d\n", sym.st_name); + printf("st_info: %d\n", sym.st_info); + printf("st_other: %d\n", sym.st_other); + printf("st_shndx: %d\n", sym.st_shndx); + // printf("st_value: %ld\n", sym.st_value); + // printf("st_size: %ld\n", sym.st_size); + fflush(stdout); +} + +void print_section(Elf64_Shdr sec) { + printf("sh_name : %d\n", sec.sh_name); + printf("sh_type : %d\n", sec.sh_type); + printf("sh_flags : %ld\n", sec.sh_flags); + // printf("sh_addr : %ld\n", sec.sh_addr); + // printf("sh_offset : %ld\n", sec.sh_offset); + // printf("sh_size : %ld\n", sec.sh_size); + printf("sh_link : %d\n", sec.sh_link); + printf("sh_info : %d\n", sec.sh_info); + // printf("sh_addralign : %ld\n", sec.sh_addralign); + // printf("sh_entsize : %ld\n", sec.sh_entsize); + fflush(stdout); +} + +int nm32(t_mapped_file mapped_file) { + (void)mapped_file; + return FT_NM_SUCCESS; +} + +void ppp(Elf64_Sym sym, Elf64_Shdr sec) { + print_symbol(sym); + print_section(sec); +} +