ft_otool first working version, need to work on the formatting and usage with libraries and fat binaries

This commit is contained in:
Jack Halford 2017-02-20 15:47:57 +01:00
parent 54425a0aa5
commit d8fe7600a2
7 changed files with 293 additions and 42 deletions

View file

@ -6,11 +6,11 @@
# By: jhalford <jack@crans.org> +#+ +:+ +#+ # # By: jhalford <jack@crans.org> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2017/02/19 03:29:38 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 CC = gcc
MKDIR = mkdir -p MKDIR = mkdir -p
@ -31,34 +31,54 @@ SRC_DIR = src/
INC_DIR = includes/ INC_DIR = includes/
OBJ_DIR = objs/ OBJ_DIR = objs/
FT_NM_OBJ = $(OBJ_DIR)ft_nm.o
FT_OTOOL_OBJ= $(OBJ_DIR)ft_otool.o
SRC_BASE = \ SRC_BASE = \
ft_nm.c dump_symtab.c\
ft_nm.c\
ft_otool.c\
hexdump.c
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))
NB = $(words $(SRC_BASE)) NB = $(words $(SRC_BASE) $(NAME))
INDEX = 0 INDEX = 0
all: OBJS := $(filter-out $(FT_NM_OBJ), $(OBJS))
@make -j $(NAME) 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) \ @$(CC) $(FLAGS) $(D_FLAGS) \
-I $(INC_DIR) \ -I $(INC_DIR) \
-I $(LIBFT_INC) \ -I $(LIBFT_INC) \
$(LIBS) \ $(LIBS) \
$(LIBFT_LIB) $(OBJS) \ $(LIBFT_LIB) $(OBJS) $(FT_NM_OBJ) \
-o $(NAME) -o $@
@$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) @$(eval INDEX=$(shell echo $$(($(INDEX)+1))))
@strip -x $(NAME) @strip -x $@
@printf "\r\e[48;5;15;38;5;25m✅ MAKE $(NAME)\e[0m\e[K\n" @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) $(OBJ_DIR)%.o: $(SRC_DIR)%.c | $(OBJ_DIR)
@$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB)))))
@$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB))))) @$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB)))))
@$(eval COLOR=$(shell echo $$(($(PERCENT)%35+196)))) @$(eval COLOR=$(shell echo $$(($(PERCENT)%35+196))))
@$(eval TO_DO=$(shell echo $$((20-$(INDEX)*20/$(NB))))) @$(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 $@\ @$(CC) $(FLAGS) -MMD -c $< -o $@\
-I $(INC_DIR) \ -I $(INC_DIR) \
-I $(LIBFT_INC) -I $(LIBFT_INC)

View file

@ -1,27 +1,33 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* ft_nm.h :+: :+: :+: */ /* ft_nm_otool.h :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/19 03:09:10 by jhalford #+# #+# */ /* Created: 2017/02/20 14:36:10 by jhalford #+# #+# */
/* Updated: 2017/02/19 03:32:51 by jhalford ### ########.fr */ /* Updated: 2017/02/20 15:33:32 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#ifndef FT_NM_H #ifndef FT_NM_OTOOL_H
# define FT_NM_H # define FT_NM_OTOOL_H
# include "libft.h" # include "libft.h"
# include <stdio.h> # include <stdio.h>
# include <sys/mman.h> # include <sys/mman.h>
# include <mach-o/loader.h> # include <mach-o/loader.h>
# include <mach-o/nlist.h> # include <mach-o/nlist.h>
# include <mach-o/fat.h>
# include <mach/machine.h>
# include <fcntl.h> # include <fcntl.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <stdlib.h> # include <stdlib.h>
# define IS_MAGIC_64(x) (x == MH_MAGIC_64 || x == MH_CIGAM_64) # 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 #endif

@ -1 +1 @@
Subproject commit 5e978382fff27082681383029d99f76ae5a25ddc Subproject commit 0ca8ca817f32fc0345ef93ef74a3abe2583bd89c

View file

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* dump_symtab.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

View file

@ -6,11 +6,11 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/19 03:09:12 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) 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) void dump_mach_header_64(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)
{ {
uint32_t ncmds; uint32_t ncmds;
uint32_t i; uint32_t i;
@ -58,24 +43,48 @@ void dump_load_commands(void *file)
ncmds = header->ncmds; ncmds = header->ncmds;
lc = (void*)(header + 1); lc = (void*)(header + 1);
ft_printf("{blu}{inv}mach_header_64 w/ [%d] load_commands{eoc}\n", ncmds);
for (i = 0; i < ncmds; i++) for (i = 0; i < ncmds; i++)
{ {
ft_printf("{yel}load_command #%d: %i{eoc}\n", i, lc->cmd); ft_printf("{yel}{inv}load_command #%d: %#x{eoc}\n", i, lc->cmd);
if (lc->cmd == LC_SYMTAB) if (lc->cmd & LC_SYMTAB)
dump_symtab((struct symtab_command*)lc, file); 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); dump_segment_64((struct segment_command_64*)lc, file);
lc = (void*)lc + lc->cmdsize; 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; uint32_t magic = *(int *)file;
int is_fat = IS_FAT(magic);
int is_64 = IS_MAGIC_64(magic); int is_64 = IS_MAGIC_64(magic);
ft_printf("{gre}I'm %s a 64 bit binary{eoc}\n", is_64 ? "" : "not"); if (is_fat)
dump_load_commands(file); 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) int main(int ac, char **av)

82
nm-otool/src/ft_otool.c Normal file
View file

@ -0,0 +1,82 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_otool.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

106
nm-otool/src/hexdump.c Normal file
View file

@ -0,0 +1,106 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* hexdump.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}