# HG changeset patch # User taiki # Date 1360045585 -32400 # Node ID 1b796d0dd763566ca60b9f46a79720324de3c8e4 # Parent 075d70197fc2a87701b24aba62dac22e45041366 display segment command and section in Mach-O executable. diff -r 075d70197fc2 -r 1b796d0dd763 Makefile --- a/Makefile Sat Feb 02 22:15:35 2013 +0900 +++ b/Makefile Tue Feb 05 15:26:25 2013 +0900 @@ -2,7 +2,7 @@ TARGET = loader -CFLAGES = -Wall -O2 -g -o +CFLAGES = -Wall -O0 -g -std=c99 -o $(TARGET): loader.c $(CC) $(CFLAGES) $(TARGET) loader.c diff -r 075d70197fc2 -r 1b796d0dd763 loader.c --- a/loader.c Sat Feb 02 22:15:35 2013 +0900 +++ b/loader.c Tue Feb 05 15:26:25 2013 +0900 @@ -7,68 +7,237 @@ #include #include -#define NAME_MAX_LENGTH 128 -#define MAX_SEGMENT_NUM 128 +#define NAME_MAX_LENGTH 256 +#define MAX_SEGMENT_NUM 256 + +struct mach_o_data { + int mh64_size; + int sc64_size; + int sect64_size; +}; + +struct data_count { + int nsects_count; + int sc_count; +}; + +/* prototype */ + +__code analyze_mach_o(struct mach_o_data md, struct mach_header_64 *mh64, struct segment_command_64 *sc64, struct section_64 *sect64, struct data_count dc, char *head, int fp, int j); + +/* end */ +__code finish(int fp, struct segment_command_64 *sc64, struct section_64 *sect64) +{ + close(fp); + free(sc64); + free(sect64); + printf("close \n"); +} -void option_reader(int argc, char *argv[], char *filename) +__code make_section( + struct mach_o_data md, + struct mach_header_64 *mh64, + struct segment_command_64 *sc64, + struct section_64 *sect64, + struct data_count dc, + char *head, + char *c_sect64, + int fp, + int scsect_count, + int sectsize_count, + int cmd_count) { - int i; - for (i=0; insects) { + if(sectsize_count < md.sect64_size) { + c_sect64[sectsize_count] = head[md.mh64_size + md.sc64_size * dc.sc_count + (dc.nsects_count + scsect_count) * md.sect64_size + sectsize_count]; + sectsize_count++; + goto make_section(md, mh64, sc64, sect64, dc, head, c_sect64, fp, scsect_count, sectsize_count, cmd_count); } + sect64 = (struct section_64 *)c_sect64; + printf("%s %s \n", sect64->segname, sect64->sectname); + sect64 = NULL; + scsect_count++; + sectsize_count = 0; + goto make_section(md, mh64, sc64, sect64, dc, head, c_sect64, fp, scsect_count, sectsize_count, cmd_count); + } + free(c_sect64); + dc.nsects_count += sc64->nsects; + cmd_count++; + goto analyze_mach_o(md, mh64, sc64, sect64, dc, head, fp, cmd_count); +} + +__code check_segment( + struct mach_o_data md, + struct mach_header_64 *mh64, + struct segment_command_64 *sc64, + struct section_64 *sect64, + struct data_count dc, + char *head, + int fp, + int scsect_count, + int cmd_count) +{ + if (LC_SEGMENT_64 == sc64->cmd) { + printf("segment command :LC_SEGMENT_64"); + printf("\tsegname :%s \n", sc64->segname); + printf("\tvmaddr :%#llx \n", sc64->vmaddr); + printf("\tvmsize :%lld \n", sc64->vmsize); + printf("\tfileoff :%#llx \n", sc64->fileoff); + printf("\tnumber of section :%d\n", sc64->nsects); + dc.sc_count++; + char *c_sect64 = (char *)malloc(sizeof(struct section_64 *)); + int sectsize_count = 0; + goto make_section(md, mh64, sc64, sect64, dc, head, c_sect64, fp, scsect_count , sectsize_count, cmd_count); + } + goto finish(fp, sc64, sect64); +} + +__code make_segment_command( + struct mach_o_data md, + struct mach_header_64 *mh64, + struct segment_command_64 *sc64, + struct section_64 *sect64, + struct data_count dc, + char *head, + char *c_sc64, + int fp, + int scsize_count, + int cmd_count) +{ + if (cmd_count < mh64->ncmds) { + if (scsize_count < md.sc64_size) { + c_sc64[scsize_count] = head[md.mh64_size + md.sc64_size * dc.sc_count + dc.nsects_count * md.sect64_size + scsize_count]; + scsize_count++; + goto make_segment_command(md, mh64, sc64, sect64, dc, head, c_sc64,fp, scsize_count, cmd_count); + } + sc64 = (struct segment_command_64 *)c_sc64; + int scsect_count = 0; + goto check_segment(md, mh64, sc64, sect64, dc, head, fp, scsect_count ,cmd_count); + } else { + free(c_sc64); + goto finish(fp, sc64, sect64); } } -int main(int argc, char*argv[]) + +__code analyze_mach_o( + struct mach_o_data md, + struct mach_header_64 *mh64, + struct segment_command_64 *sc64, + struct section_64 *sect64, + struct data_count dc, + char *head, + int fp, + int cmd_count) +{ + int scsize_count = 0; + char *c_sc64 = (char *)malloc(sizeof(struct segment_command_64)); + goto make_segment_command(md, mh64, sc64, sect64, dc, head, c_sc64, fp, scsize_count, cmd_count); +} + +__code ready_analyzing(struct mach_header_64 *mh64, char *head, int fp) +{ + struct mach_o_data md; + md.mh64_size = sizeof(struct mach_header_64); + md.sc64_size = sizeof(struct segment_command_64); + md.sect64_size = sizeof(struct section_64); + + struct segment_command_64 *sc64 = (struct segment_command_64 *)malloc(sizeof(struct segment_command_64)); + struct section_64 *sect64 = (struct section_64 *)malloc(sizeof(struct section_64)); + + struct data_count dc; + dc.nsects_count = 0; + dc.sc_count = 0; + int cmd_count = 0; + goto analyze_mach_o(md, mh64, sc64, sect64, dc, head,fp, cmd_count); +} + +__code judge_mach_o_file(struct mach_header_64 *mh64, char *head, char *filename, int fp) { - char filename[NAME_MAX_LENGTH]; - option_reader(argc, argv, filename); + printf("%s is executable file.\n", filename); + printf("number of load commands : %d\n", mh64->ncmds); + printf("size of cmds : %d\n", mh64->sizeofcmds); + + free(filename); + + if (CPU_TYPE_X86_64 == mh64->cputype) printf("CPU : x86_64\n"); + goto ready_analyzing(mh64, head, fp); +} + +__code judge_filetype(struct mach_header_64 *mh64 , char *head, char *filename, int fp) +{ + if (MH_EXECUTE != mh64->filetype) { + fprintf(stderr, "This is not executable file.\n"); + return; + } + goto judge_mach_o_file(mh64, head, filename, fp); +} + +__code judge_header(int fp, struct stat sb, char *head, char *filename) +{ + struct mach_header_64 *mh64 = (struct mach_header_64 *)head; + if (MH_MAGIC_64 != mh64->magic) { + fprintf(stderr, "This is not mach header 64.\n"); + return; + } + if (MH_MAGIC_64 == mh64->magic) + printf("%s is 64bit Mach-O file.\n", filename); + + goto judge_filetype(mh64, head, filename, fp); +} + +__code file_map(int fp, struct stat sb, char *filename) +{ + char *head = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fp, 0); + goto judge_header(fp, sb, head, filename); +} + +__code get_fstat(int fp, char *filename) +{ + struct stat sb; + fstat(fp, &sb); + goto file_map(fp, sb, filename); +} + +__code file_open(char *filename) +{ int fp; if ((fp = open(filename, O_RDONLY)) < 0) { fprintf(stderr, "can not open file\t: %s\n", filename); exit(1); } - - struct stat sb; - fstat(fp, &sb); - - char *head = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fp, 0); - - struct mach_header_64 *mh64 = (struct mach_header_64 *)head; - - if (MH_MAGIC_64 != mh64->magic) { - fprintf(stderr, "This is not mach header 64.\n"); - return 0; - } - - printf("%s is 64bit Mach-O file.\n", filename); + goto get_fstat(fp, filename); +} - if (MH_EXECUTE != mh64->filetype) { - fprintf(stderr, "This is not executable file.\n"); - return 0; +__code option_reader(int argc, char *argv[], char filename[NAME_MAX_LENGTH], int i) +{ + if (i < argc) { + if(argv[i][0] == '-') { + if(strcmp(argv[i], "-name")==0) { + strncpy(filename, argv[i], NAME_MAX_LENGTH); + } + } else { + strncpy(filename, argv[i], NAME_MAX_LENGTH); + } + printf("read %s\n", filename); + i++; + goto option_reader(argc, argv, filename, i); } - - printf("%s is executable file.\n", filename); - - if (CPU_TYPE_X86_64 == mh64->cputype) printf("CPU : x86_64\n"); + printf("use %s \n", filename); + goto file_open(filename); +} - int i = 0; - int mh64_size = sizeof(struct mach_header_64); - int lc_size = sizeof(struct load_command); - for (;i < mh64->ncmds; i++) { - struct load_command * lc = (struct load_command*)head + lc_size * i; - } +void mach_o_loader(int argc, char *argv[]) +{ + int argv_count = 0; + char *filename = (char *)malloc(sizeof(char)*NAME_MAX_LENGTH); + goto option_reader(argc, argv, filename, argv_count); +} - close(fp); - +int main(int argc, char*argv[]) +{ + mach_o_loader(argc, argv); return 0; }