diff --git a/nm-otool/Makefile b/nm-otool/Makefile index ee406d01..1c1dfcce 100644 --- a/nm-otool/Makefile +++ b/nm-otool/Makefile @@ -6,11 +6,11 @@ # By: jhalford +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2017/02/19 03:29:38 by jhalford #+# #+# # -# Updated: 2017/02/19 03:59:47 by jhalford ### ########.fr # +# Updated: 2017/02/20 15:38:45 by jhalford ### ########.fr # # # # **************************************************************************** # -NAME = ft_nm +NAME = ft_nm ft_otool CC = gcc MKDIR = mkdir -p @@ -31,34 +31,54 @@ SRC_DIR = src/ INC_DIR = includes/ OBJ_DIR = objs/ +FT_NM_OBJ = $(OBJ_DIR)ft_nm.o +FT_OTOOL_OBJ= $(OBJ_DIR)ft_otool.o + SRC_BASE = \ -ft_nm.c +dump_symtab.c\ +ft_nm.c\ +ft_otool.c\ +hexdump.c SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) -NB = $(words $(SRC_BASE)) +NB = $(words $(SRC_BASE) $(NAME)) INDEX = 0 -all: - @make -j $(NAME) +OBJS := $(filter-out $(FT_NM_OBJ), $(OBJS)) +OBJS := $(filter-out $(FT_OTOOL_OBJ), $(OBJS)) -$(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) +all: $(NAME) + +ft_nm: $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(FT_NM_OBJ) @$(CC) $(FLAGS) $(D_FLAGS) \ -I $(INC_DIR) \ -I $(LIBFT_INC) \ $(LIBS) \ - $(LIBFT_LIB) $(OBJS) \ - -o $(NAME) + $(LIBFT_LIB) $(OBJS) $(FT_NM_OBJ) \ + -o $@ @$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) - @strip -x $(NAME) - @printf "\r\e[48;5;15;38;5;25m✅ MAKE $(NAME)\e[0m\e[K\n" + @strip -x $@ + @printf "\r\e[48;5;15;38;5;25m✅ MAKE $@\e[0m\e[K\n" + +ft_otool: $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(FT_OTOOL_OBJ) + @$(CC) $(FLAGS) $(D_FLAGS) \ + -I $(INC_DIR) \ + -I $(LIBFT_INC) \ + $(LIBS) \ + $(LIBFT_LIB) $(OBJS) $(FT_OTOOL_OBJ) \ + -o $@ + @$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) + @strip -x $@ + @printf "\r\e[48;5;15;38;5;25m✅ MAKE $@\e[0m\e[K\n" + $(OBJ_DIR)%.o: $(SRC_DIR)%.c | $(OBJ_DIR) @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) @$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB))))) @$(eval COLOR=$(shell echo $$(($(PERCENT)%35+196)))) @$(eval TO_DO=$(shell echo $$((20-$(INDEX)*20/$(NB))))) - @printf "\r\e[38;5;11m⌛ MAKE %10.10s : %2d%% \e[48;5;%dm%*s\e[0m%*s\e[48;5;255m \e[0m \e[38;5;11m %*s\e[0m\e[K" $(NAME) $(PERCENT) $(COLOR) $(DONE) "" $(TO_DO) "" $(DELTA) "$@" + @printf "\r\e[38;5;11m⌛ MAKE %10.10s : %2d%% \e[48;5;%dm%*s\e[0m%*s\e[48;5;255m \e[0m \e[38;5;11m %*s\e[0m\e[K" $@ $(PERCENT) $(COLOR) $(DONE) "" $(TO_DO) "" $(DELTA) "$@" @$(CC) $(FLAGS) -MMD -c $< -o $@\ -I $(INC_DIR) \ -I $(LIBFT_INC) diff --git a/nm-otool/includes/ft_nm.h b/nm-otool/includes/ft_nm_otool.h similarity index 67% rename from nm-otool/includes/ft_nm.h rename to nm-otool/includes/ft_nm_otool.h index 0bf96765..909db434 100644 --- a/nm-otool/includes/ft_nm.h +++ b/nm-otool/includes/ft_nm_otool.h @@ -1,27 +1,33 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_nm.h :+: :+: :+: */ +/* ft_nm_otool.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2017/02/19 03:09:10 by jhalford #+# #+# */ -/* Updated: 2017/02/19 03:32:51 by jhalford ### ########.fr */ +/* Created: 2017/02/20 14:36:10 by jhalford #+# #+# */ +/* Updated: 2017/02/20 15:33:32 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef FT_NM_H -# define FT_NM_H +#ifndef FT_NM_OTOOL_H +# define FT_NM_OTOOL_H # include "libft.h" # include # include # include # include +# include +# include # include # include # include # define IS_MAGIC_64(x) (x == MH_MAGIC_64 || x == MH_CIGAM_64) +# define IS_FAT(x) (x == FAT_MAGIC || x == FAT_CIGAM) + +void dump_symtab(struct symtab_command *sym, void *file); +void *hexdump(void *addr, unsigned int size, int option); #endif diff --git a/nm-otool/libft b/nm-otool/libft index 5e978382..0ca8ca81 160000 --- a/nm-otool/libft +++ b/nm-otool/libft @@ -1 +1 @@ -Subproject commit 5e978382fff27082681383029d99f76ae5a25ddc +Subproject commit 0ca8ca817f32fc0345ef93ef74a3abe2583bd89c diff --git a/nm-otool/src/dump_symtab.c b/nm-otool/src/dump_symtab.c new file mode 100644 index 00000000..9bc878d1 --- /dev/null +++ b/nm-otool/src/dump_symtab.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dump_symtab.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/20 13:20:22 by jhalford #+# #+# */ +/* Updated: 2017/02/20 15:03:38 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_nm_otool.h" + +void dump_symtab(struct symtab_command *sym, void *file) +{ + int i; + int nsyms; + char *stringtable; + struct nlist_64 *array; + + nsyms = sym->nsyms; + array = file + sym->symoff; + stringtable = (void*)file + sym->stroff; + ft_printf("{und}LC_SYMTAB w/ [%d] symbols:{eoc}\n", sym->nsyms); + for (i = 0; i < nsyms; ++i) + ft_printf("%s\n", stringtable + array[i].n_un.n_strx); +} diff --git a/nm-otool/src/ft_nm.c b/nm-otool/src/ft_nm.c index 5fe5fb2f..c6a4b519 100644 --- a/nm-otool/src/ft_nm.c +++ b/nm-otool/src/ft_nm.c @@ -6,11 +6,11 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/02/19 03:09:12 by jhalford #+# #+# */ -/* Updated: 2017/02/19 05:32:56 by jhalford ### ########.fr */ +/* Updated: 2017/02/20 15:18:30 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#include "ft_nm.h" +#include "ft_nm_otool.h" void dump_section_64(struct section_64 *sect) { @@ -34,22 +34,7 @@ void dump_segment_64(struct segment_command_64 *seg, void *file) } } -void dump_symtab(struct symtab_command *sym, void *file) -{ - int i; - int nsyms; - char *stringtable; - struct nlist_64 *array; - - nsyms = sym->nsyms; - array = file + sym->symoff; - stringtable = (void*)file + sym->stroff; - ft_printf("{und}LC_SYMTAB with %d symbols:{eoc}\n", sym->nsyms); - for (i = 0; i < nsyms; ++i) - ft_printf("%s\n", stringtable + array[i].n_un.n_strx); -} - -void dump_load_commands(void *file) +void dump_mach_header_64(void *file) { uint32_t ncmds; uint32_t i; @@ -58,24 +43,48 @@ void dump_load_commands(void *file) ncmds = header->ncmds; lc = (void*)(header + 1); + ft_printf("{blu}{inv}mach_header_64 w/ [%d] load_commands{eoc}\n", ncmds); for (i = 0; i < ncmds; i++) { - ft_printf("{yel}load_command #%d: %i{eoc}\n", i, lc->cmd); - if (lc->cmd == LC_SYMTAB) + ft_printf("{yel}{inv}load_command #%d: %#x{eoc}\n", i, lc->cmd); + if (lc->cmd & LC_SYMTAB) dump_symtab((struct symtab_command*)lc, file); - else if (lc->cmd == LC_SEGMENT_64) + else if (lc->cmd & LC_SEGMENT_64) dump_segment_64((struct segment_command_64*)lc, file); lc = (void*)lc + lc->cmdsize; } } -void nm(char *file) +void dump_fat_header(void *file) +{ + struct fat_header *header = file; + struct fat_arch *arch; + int i; + int nfat_arch; + + nfat_arch = header->nfat_arch; + arch = (void*)(header + 1); + ft_printf("{yel}{inv}FAT header w/ [%i] architures{eoc}\n", nfat_arch); + for (i = 0; i < nfat_arch; i++) + { + ft_printf("CPU type=[%i]", arch->cputype); + dump_mach_header_64(file + arch->offset); + arch += 1; + } +} + +void nm(void *file) { uint32_t magic = *(int *)file; + int is_fat = IS_FAT(magic); int is_64 = IS_MAGIC_64(magic); - ft_printf("{gre}I'm %s a 64 bit binary{eoc}\n", is_64 ? "" : "not"); - dump_load_commands(file); + if (is_fat) + dump_fat_header(file); + else if (is_64) + dump_mach_header_64(file); + else + ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic); } int main(int ac, char **av) diff --git a/nm-otool/src/ft_otool.c b/nm-otool/src/ft_otool.c new file mode 100644 index 00000000..554de701 --- /dev/null +++ b/nm-otool/src/ft_otool.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_otool.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/20 14:08:14 by jhalford #+# #+# */ +/* Updated: 2017/02/20 15:27:00 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_nm_otool.h" + +void *get_text_section(void *file) +{ + uint32_t i; + struct load_command *lc; + struct mach_header_64 *header = file; + struct segment_command_64 *seg; + struct section_64 *sect; + + lc = (void*)(header + 1); + for (i = 0; i < header->ncmds; i++) + { + if (lc->cmd & LC_SEGMENT_64) + { + seg = (struct segment_command_64*)lc; + sect = (void*)(seg + 1); + for (i = 0; i < seg->nsects; i++) + { + if (ft_strcmp(sect->sectname, "__text") == 0) + return (sect); + sect = sect + 1; + } + } + lc = (void*)lc + lc->cmdsize; + } + return (NULL); +} + +void otool(void *file) +{ + uint32_t magic = *(int *)file; + int is_fat = IS_FAT(magic); + int is_64 = IS_MAGIC_64(magic); + struct section_64 *sect; + + sect = NULL; + if (is_fat) + ft_printf("fat binary: not supported yet.\n"); + else if (is_64) + sect = get_text_section(file); + else + ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic); + ft_printf("Contents of (__TEXT,__text) section\n"); + hexdump(file + sect->offset, sect->size, 0); +} + +int main(int ac, char **av) +{ + int fd; + char *file; + struct stat buf; + + if (ac != 2) + { + ft_dprintf(2, "Please give me an arg\n"); + return (1); + } + if ((fd = open(av[1], O_RDONLY)) < 0) + return (1); + if ((fstat(fd, &buf)) < 0) + return (1); + if ((file = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) + == MAP_FAILED) + return (1); + otool(file); + if (munmap(file, buf.st_size)) + return (1); + return (0); +} diff --git a/nm-otool/src/hexdump.c b/nm-otool/src/hexdump.c new file mode 100644 index 00000000..de67eaac --- /dev/null +++ b/nm-otool/src/hexdump.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hexdump.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/20 15:14:33 by jhalford #+# #+# */ +/* Updated: 2017/02/20 15:47:08 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_nm_otool.h" + +void ft_putnbr_base16(int nbr, int format) +{ + int base_size; + int i; + int result[100]; + + base_size = 16; + i = 0; + if (base_size > 1) + { + if (nbr < 0) + { + ft_putchar('-'); + nbr = -nbr; + } + while (nbr) + { + result[i] = nbr % base_size; + nbr = nbr / base_size; + i++; + } + while (format-- > i) + ft_putchar('0'); + while (--i >= 0) + ft_putchar("0123456789abcdef"[result[i]]); + } +} + +static void print_contents(void *addr, unsigned int size) +{ + void *a; + + a = addr; + ft_putstr(" |"); + while (a - addr < 16) + { + if ((a - addr) >= size) + break ; + else if (*(char *)a < 32 || *(char *)a > 126) + ft_putchar('.'); + else + ft_putchar(*(char *)a); + a++; + } + ft_putchar('|'); +} + +static void print_hex_contents(void *addr, unsigned int size, int option) +{ + void *a; + + a = addr; + (void)option; + while (a - addr < 16) + { + if ((a - addr) >= size) + break ; + if (option && FT_IS_DIV((a - addr), 8)) + ft_putchar(' '); + else + /* ft_putnbr_base16(*(unsigned char *)a, 2); */ + ft_printf("%02x", *(unsigned char*)a); + ft_putchar(' '); + a++; + } +} + +void *hexdump(void *addr, unsigned int size, int option) +{ + void *a; + + a = addr; + if (addr == NULL) + return (addr); + while ((a - addr) < size) + { + /* ft_putnbr_base16((int)(a - addr), 7 + option); */ + ft_printf("%0*x\t", 16, (a - addr)); + print_hex_contents(a, (size - (a - addr)), option); + if (option) + print_contents(a, (size - (a - addr))); + ft_putchar('\n'); + a += 16; + /* if (!ft_strncmp((char *)a, (char *)(a - 16), 16)) */ + /* { */ + /* ft_putstr("*\n"); */ + /* while (!ft_strncmp((char *)a, (char *)(a - 16), 16)) */ + /* a += 16; */ + /* } */ + } + return (addr); +}