From dd68ed6846309537568671a12f4c07e8d4dd8074 Mon Sep 17 00:00:00 2001 From: Gregory Date: Sat, 13 Jul 2019 15:10:26 +0300 Subject: [PATCH] some refactoring --- src/main.c | 245 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 160 insertions(+), 85 deletions(-) diff --git a/src/main.c b/src/main.c index c9c8c8c..21859fd 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/13 14:52:27 by gtertysh #+# #+# */ +/* Updated: 2019/07/13 14:52:29 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "libft.h" #include #include @@ -5,7 +17,6 @@ #include #include - static void print_addr(void *addr) { size_t i; @@ -25,106 +36,170 @@ static void print_addr(void *addr) } } -int main(int argc, char **argv) +void open_file(const char *filename, int *fd, char **file) { - if (argc != 2) - { - ft_putstr("usage\n"); - return (1); - } - int fd = open(argv[1], O_RDONLY); - if (fd == -1) + struct stat stat_buff; + + *fd = open(filename, O_RDONLY); + if (*fd == -1) { ft_putstr("can't open file\n"); - return (1); + exit(1); } - struct stat stat_buff; - stat(argv[1], &stat_buff); + stat(filename, &stat_buff); if (!S_ISREG(stat_buff.st_mode)) { ft_putstr("not a regular file\n"); - return (1); + close(*fd); + exit(1); } - char *file; - file = malloc(stat_buff.st_size); - read(fd, file, stat_buff.st_size); - - uint32_t magic = *(uint32_t *)file; - - if (magic != MH_MAGIC && magic != MH_MAGIC_64) + *file = NULL; + *file = malloc(stat_buff.st_size); + if (!*file) { - ft_putstr("not a mach-o file\n"); - return (1); + ft_putstr("can't allocate memory\n"); + close(*fd); + exit(1); } + read(*fd, *file, stat_buff.st_size); +} - if (magic == MH_MAGIC) - ft_putstr("32 bit mach-o file\n"); +void close_file(int fd, char *file) +{ + close(fd); + free(file); +} + +void handle_64(char *file) +{ + struct mach_header_64 *hdr; + struct load_command *load_cmd; + struct symtab_command *symtab_cmd; + struct segment_command_64 *segment_cmd; - if (magic == MH_MAGIC_64) + hdr = (struct mach_header_64 *)file; + ft_putstr("64 bit mach-o file\n"); + ft_putstr("# of cmds: "); + ft_putnbr(hdr->ncmds); + ft_putstr("\n"); + ft_putstr("total cmds memory: "); + ft_putnbr(hdr->sizeofcmds); + ft_putstr("\n"); + + uint32_t load_cmd_offset = sizeof(struct mach_header_64); + uint32_t i = 0; + while (i < hdr->ncmds) { - struct mach_header_64 *hdr = (struct mach_header_64 *)file; - // ft_putstr("64 bit mach-o file\n"); - // ft_putstr("# of cmds: "); - // ft_putnbr(hdr->ncmds); - // ft_putstr("\n"); - // ft_putstr("total cmds memory: "); - // ft_putnbr(hdr->sizeofcmds); - // ft_putstr("\n"); - struct load_command *load_cmd; - struct symtab_command *symtab_cmd; - uint32_t load_cmd_offset = sizeof(struct mach_header_64); - uint32_t i = 0; - while (i < hdr->ncmds) + load_cmd = (struct load_command *)(file + load_cmd_offset); + if (load_cmd->cmd == LC_SEGMENT_64) { - load_cmd = (struct load_command *)(file + load_cmd_offset); - if (load_cmd->cmd == LC_SYMTAB) - { - symtab_cmd = (struct symtab_command *)load_cmd; - // ft_putstr("found symbol table load command\n"); - // ft_putstr("# of symbols: "); - // ft_putnbr(symtab_cmd->nsyms); - // ft_putstr("\n"); - - uint32_t j = 0; - struct nlist_64 *symbol_table = (struct nlist_64 *) - (file + symtab_cmd->symoff); - struct nlist_64 symbol; - char *str_table = file + symtab_cmd->stroff; - while(j < symtab_cmd->nsyms) - { - symbol = symbol_table[j]; - int type = symbol.n_type & N_TYPE; - int external = symbol.n_type & N_EXT; - int debug = (symbol.n_type & N_STAB) != 0; - int offset = external ? 0 : 32; - char *name = str_table + symbol.n_un.n_strx; - - if (debug) - { - j++; - continue; - } - - if (symbol.n_value) - print_addr((void *)symbol.n_value); - else - ft_putstr(" "); - ft_putchar(' '); - if (type == N_UNDF) - ft_putchar('U' + offset); - if (type == N_ABS) - ft_putchar('A' + offset); - if (type == N_SECT) - // lookup in which section symbol is located - ft_putchar('T' + offset); - ft_putchar(' '); - ft_putstr(name); - ft_putstr("\n"); - j++; - } - } + segment_cmd = (struct segment_command_64 *)load_cmd; + ft_putnbr(i); + ft_putchar(' '); + ft_putnbr(segment_cmd->nsects); + ft_putchar(' '); + ft_putstr(segment_cmd->segname); + ft_putchar('\n'); load_cmd_offset += load_cmd->cmdsize; i++; + continue; } + if (load_cmd->cmd == LC_SYMTAB) + { + symtab_cmd = (struct symtab_command *)load_cmd; + ft_putstr("found symbol table load command\n"); + ft_putstr("# of symbols: "); + ft_putnbr(symtab_cmd->nsyms); + ft_putstr("\n"); + + uint32_t j = 0; + struct nlist_64 *symbol_table = (struct nlist_64 *) + (file + symtab_cmd->symoff); + struct nlist_64 symbol; + char *str_table = file + symtab_cmd->stroff; + while(j < symtab_cmd->nsyms) + { + symbol = symbol_table[j]; + int type = symbol.n_type & N_TYPE; + int external = symbol.n_type & N_EXT; + int debug = (symbol.n_type & N_STAB) != 0; + int offset = external ? 0 : 32; + char *name = str_table + symbol.n_un.n_strx; + + if (debug) + { + j++; + continue; + } + + // some shit herustic should be used + // to determine to print address or not + if (symbol.n_value) + print_addr((void *)symbol.n_value); + else + ft_putstr(" "); + ft_putchar(' '); + if (type == N_UNDF) + ft_putchar('U' + offset); + if (type == N_ABS) + ft_putchar('A' + offset); + if (type == N_SECT) + { + // lookup in which section symbol is located + + ft_putchar('T' + offset); + ft_putchar(' '); + ft_putnbr(symbol.n_sect); + } + ft_putchar(' '); + ft_putstr(name); + ft_putstr("\n"); + j++; + } + } + load_cmd_offset += load_cmd->cmdsize; + i++; } } + +void handle_32(char *file) +{ + (void)file; + ft_putstr("TODO\n"); +} + +void hanldle_file(const char *filename) +{ + char *file; + int fd; + + open_file(filename, &fd, &file); + uint32_t magic; + + magic = *(uint32_t *)file; + + if (magic == MH_MAGIC_64) + handle_64(file); + else if (magic == MH_MAGIC) + handle_64(file); + else if (magic == MH_CIGAM || magic == MH_CIGAM_64) + ft_putstr("do not support big endian binaries."); + else + ft_putstr("invalid magic number."); + close_file(fd, file); +} + +int main(int argc, char **argv) +{ + int i; + + if (argc == 1) + hanldle_file("a.out"); + else + { + i = 1; + while (i < argc) + hanldle_file(argv[i++]); + } + return (0); +}