Mercurial > hg > Members > taiki > Mach-OLoader
view loader.c @ 1:1b796d0dd763
display segment command and section in Mach-O executable.
author | taiki |
---|---|
date | Tue, 05 Feb 2013 15:26:25 +0900 |
parents | 075d70197fc2 |
children |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <sys/mman.h> #include <mach-o/loader.h> #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"); } __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) { if(scsect_count < sc64->nsects) { 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); } } __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) { 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); } goto get_fstat(fp, filename); } __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("use %s \n", filename); goto file_open(filename); } 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); } int main(int argc, char*argv[]) { mach_o_loader(argc, argv); return 0; }