changeset 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 747f68297ba5
files Makefile loader.c
diffstat 2 files changed, 215 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- 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 
--- 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 <sys/mman.h>
 #include <mach-o/loader.h>
 
-#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; i<argc; i++) {
-        if(argv[i][0] == '-') {
-            if(strcmp(argv[i], "-name")==0) {
-                i++;
-                strncpy(filename ,argv[i], NAME_MAX_LENGTH);
-                printf("read %s\n", filename);
-            }
-        } else {
-            strncpy(filename ,argv[i], NAME_MAX_LENGTH);
+    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);
     }
 }
 
-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;
 }