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 "libft.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -5,7 +17,6 @@
|
||||||
#include <mach-o/loader.h>
|
#include <mach-o/loader.h>
|
||||||
#include <mach-o/nlist.h>
|
#include <mach-o/nlist.h>
|
||||||
|
|
||||||
|
|
||||||
static void print_addr(void *addr)
|
static void print_addr(void *addr)
|
||||||
{
|
{
|
||||||
size_t i;
|
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)
|
struct stat stat_buff;
|
||||||
{
|
|
||||||
ft_putstr("usage\n");
|
*fd = open(filename, O_RDONLY);
|
||||||
return (1);
|
if (*fd == -1)
|
||||||
}
|
|
||||||
int fd = open(argv[1], O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
{
|
{
|
||||||
ft_putstr("can't open file\n");
|
ft_putstr("can't open file\n");
|
||||||
return (1);
|
exit(1);
|
||||||
}
|
}
|
||||||
struct stat stat_buff;
|
stat(filename, &stat_buff);
|
||||||
stat(argv[1], &stat_buff);
|
|
||||||
if (!S_ISREG(stat_buff.st_mode))
|
if (!S_ISREG(stat_buff.st_mode))
|
||||||
{
|
{
|
||||||
ft_putstr("not a regular file\n");
|
ft_putstr("not a regular file\n");
|
||||||
return (1);
|
close(*fd);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
char *file;
|
*file = NULL;
|
||||||
file = malloc(stat_buff.st_size);
|
*file = malloc(stat_buff.st_size);
|
||||||
read(fd, file, stat_buff.st_size);
|
if (!*file)
|
||||||
|
|
||||||
uint32_t magic = *(uint32_t *)file;
|
|
||||||
|
|
||||||
if (magic != MH_MAGIC && magic != MH_MAGIC_64)
|
|
||||||
{
|
{
|
||||||
ft_putstr("not a mach-o file\n");
|
ft_putstr("can't allocate memory\n");
|
||||||
return (1);
|
close(*fd);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
read(*fd, *file, stat_buff.st_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (magic == MH_MAGIC)
|
void close_file(int fd, char *file)
|
||||||
ft_putstr("32 bit mach-o file\n");
|
{
|
||||||
|
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;
|
load_cmd = (struct load_command *)(file + load_cmd_offset);
|
||||||
// ft_putstr("64 bit mach-o file\n");
|
if (load_cmd->cmd == LC_SEGMENT_64)
|
||||||
// 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);
|
segment_cmd = (struct segment_command_64 *)load_cmd;
|
||||||
if (load_cmd->cmd == LC_SYMTAB)
|
ft_putnbr(i);
|
||||||
{
|
ft_putchar(' ');
|
||||||
symtab_cmd = (struct symtab_command *)load_cmd;
|
ft_putnbr(segment_cmd->nsects);
|
||||||
// ft_putstr("found symbol table load command\n");
|
ft_putchar(' ');
|
||||||
// ft_putstr("# of symbols: ");
|
ft_putstr(segment_cmd->segname);
|
||||||
// ft_putnbr(symtab_cmd->nsyms);
|
ft_putchar('\n');
|
||||||
// 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
load_cmd_offset += load_cmd->cmdsize;
|
load_cmd_offset += load_cmd->cmdsize;
|
||||||
i++;
|
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…
Reference in a new issue