some refactoring
This commit is contained in:
		
							parent
							
								
									de74e299cc
								
							
						
					
					
						commit
						dd68ed6846
					
				
					 1 changed files with 160 additions and 85 deletions
				
			
		
							
								
								
									
										245
									
								
								src/main.c
									
										
									
									
									
								
							
							
						
						
									
										245
									
								
								src/main.c
									
										
									
									
									
								
							|  | @ -1,3 +1,15 @@ | |||
| /* ************************************************************************** */ | ||||
| /*                                                                            */ | ||||
| /*                                                        :::      ::::::::   */ | ||||
| /*   main.c                                             :+:      :+:    :+:   */ | ||||
| /*                                                    +:+ +:+         +:+     */ | ||||
| /*   By: gtertysh <marvin@42.fr>                    +#+  +:+       +#+        */ | ||||
| /*                                                +#+#+#+#+#+   +#+           */ | ||||
| /*   Created: 2019/07/13 14:52:27 by gtertysh          #+#    #+#             */ | ||||
| /*   Updated: 2019/07/13 14:52:29 by gtertysh         ###   ########.fr       */ | ||||
| /*                                                                            */ | ||||
| /* ************************************************************************** */ | ||||
| 
 | ||||
| #include "libft.h" | ||||
| #include <fcntl.h> | ||||
| #include <sys/stat.h> | ||||
|  | @ -5,7 +17,6 @@ | |||
| #include <mach-o/loader.h> | ||||
| #include <mach-o/nlist.h> | ||||
| 
 | ||||
| 
 | ||||
| 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); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue