Mercurial > hg > Members > taiki > Mach-OLoader
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:075d70197fc2 | 1:1b796d0dd763 |
---|---|
5 #include <unistd.h> | 5 #include <unistd.h> |
6 #include <sys/stat.h> | 6 #include <sys/stat.h> |
7 #include <sys/mman.h> | 7 #include <sys/mman.h> |
8 #include <mach-o/loader.h> | 8 #include <mach-o/loader.h> |
9 | 9 |
10 #define NAME_MAX_LENGTH 128 | 10 #define NAME_MAX_LENGTH 256 |
11 #define MAX_SEGMENT_NUM 128 | 11 #define MAX_SEGMENT_NUM 256 |
12 | 12 |
13 | 13 struct mach_o_data { |
14 void option_reader(int argc, char *argv[], char *filename) | 14 int mh64_size; |
15 { | 15 int sc64_size; |
16 int i; | 16 int sect64_size; |
17 for (i=0; i<argc; i++) { | 17 }; |
18 if(argv[i][0] == '-') { | 18 |
19 if(strcmp(argv[i], "-name")==0) { | 19 struct data_count { |
20 i++; | 20 int nsects_count; |
21 strncpy(filename ,argv[i], NAME_MAX_LENGTH); | 21 int sc_count; |
22 printf("read %s\n", filename); | 22 }; |
23 } | 23 |
24 } else { | 24 /* prototype */ |
25 strncpy(filename ,argv[i], NAME_MAX_LENGTH); | 25 |
26 __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); | |
27 | |
28 /* end */ | |
29 | |
30 __code finish(int fp, struct segment_command_64 *sc64, struct section_64 *sect64) | |
31 { | |
32 close(fp); | |
33 free(sc64); | |
34 free(sect64); | |
35 printf("close \n"); | |
36 } | |
37 | |
38 __code make_section( | |
39 struct mach_o_data md, | |
40 struct mach_header_64 *mh64, | |
41 struct segment_command_64 *sc64, | |
42 struct section_64 *sect64, | |
43 struct data_count dc, | |
44 char *head, | |
45 char *c_sect64, | |
46 int fp, | |
47 int scsect_count, | |
48 int sectsize_count, | |
49 int cmd_count) | |
50 { | |
51 if(scsect_count < sc64->nsects) { | |
52 if(sectsize_count < md.sect64_size) { | |
53 c_sect64[sectsize_count] = head[md.mh64_size + md.sc64_size * dc.sc_count + (dc.nsects_count + scsect_count) * md.sect64_size + sectsize_count]; | |
54 sectsize_count++; | |
55 goto make_section(md, mh64, sc64, sect64, dc, head, c_sect64, fp, scsect_count, sectsize_count, cmd_count); | |
26 } | 56 } |
27 } | 57 sect64 = (struct section_64 *)c_sect64; |
28 } | 58 printf("%s %s \n", sect64->segname, sect64->sectname); |
29 | 59 sect64 = NULL; |
30 int main(int argc, char*argv[]) | 60 scsect_count++; |
31 { | 61 sectsize_count = 0; |
32 char filename[NAME_MAX_LENGTH]; | 62 goto make_section(md, mh64, sc64, sect64, dc, head, c_sect64, fp, scsect_count, sectsize_count, cmd_count); |
33 option_reader(argc, argv, filename); | 63 } |
34 | 64 free(c_sect64); |
65 dc.nsects_count += sc64->nsects; | |
66 cmd_count++; | |
67 goto analyze_mach_o(md, mh64, sc64, sect64, dc, head, fp, cmd_count); | |
68 } | |
69 | |
70 __code check_segment( | |
71 struct mach_o_data md, | |
72 struct mach_header_64 *mh64, | |
73 struct segment_command_64 *sc64, | |
74 struct section_64 *sect64, | |
75 struct data_count dc, | |
76 char *head, | |
77 int fp, | |
78 int scsect_count, | |
79 int cmd_count) | |
80 { | |
81 if (LC_SEGMENT_64 == sc64->cmd) { | |
82 printf("segment command :LC_SEGMENT_64"); | |
83 printf("\tsegname :%s \n", sc64->segname); | |
84 printf("\tvmaddr :%#llx \n", sc64->vmaddr); | |
85 printf("\tvmsize :%lld \n", sc64->vmsize); | |
86 printf("\tfileoff :%#llx \n", sc64->fileoff); | |
87 printf("\tnumber of section :%d\n", sc64->nsects); | |
88 dc.sc_count++; | |
89 char *c_sect64 = (char *)malloc(sizeof(struct section_64 *)); | |
90 int sectsize_count = 0; | |
91 goto make_section(md, mh64, sc64, sect64, dc, head, c_sect64, fp, scsect_count , sectsize_count, cmd_count); | |
92 } | |
93 goto finish(fp, sc64, sect64); | |
94 } | |
95 | |
96 __code make_segment_command( | |
97 struct mach_o_data md, | |
98 struct mach_header_64 *mh64, | |
99 struct segment_command_64 *sc64, | |
100 struct section_64 *sect64, | |
101 struct data_count dc, | |
102 char *head, | |
103 char *c_sc64, | |
104 int fp, | |
105 int scsize_count, | |
106 int cmd_count) | |
107 { | |
108 if (cmd_count < mh64->ncmds) { | |
109 if (scsize_count < md.sc64_size) { | |
110 c_sc64[scsize_count] = head[md.mh64_size + md.sc64_size * dc.sc_count + dc.nsects_count * md.sect64_size + scsize_count]; | |
111 scsize_count++; | |
112 goto make_segment_command(md, mh64, sc64, sect64, dc, head, c_sc64,fp, scsize_count, cmd_count); | |
113 } | |
114 sc64 = (struct segment_command_64 *)c_sc64; | |
115 int scsect_count = 0; | |
116 goto check_segment(md, mh64, sc64, sect64, dc, head, fp, scsect_count ,cmd_count); | |
117 } else { | |
118 free(c_sc64); | |
119 goto finish(fp, sc64, sect64); | |
120 } | |
121 } | |
122 | |
123 | |
124 __code analyze_mach_o( | |
125 struct mach_o_data md, | |
126 struct mach_header_64 *mh64, | |
127 struct segment_command_64 *sc64, | |
128 struct section_64 *sect64, | |
129 struct data_count dc, | |
130 char *head, | |
131 int fp, | |
132 int cmd_count) | |
133 { | |
134 int scsize_count = 0; | |
135 char *c_sc64 = (char *)malloc(sizeof(struct segment_command_64)); | |
136 goto make_segment_command(md, mh64, sc64, sect64, dc, head, c_sc64, fp, scsize_count, cmd_count); | |
137 } | |
138 | |
139 __code ready_analyzing(struct mach_header_64 *mh64, char *head, int fp) | |
140 { | |
141 struct mach_o_data md; | |
142 md.mh64_size = sizeof(struct mach_header_64); | |
143 md.sc64_size = sizeof(struct segment_command_64); | |
144 md.sect64_size = sizeof(struct section_64); | |
145 | |
146 struct segment_command_64 *sc64 = (struct segment_command_64 *)malloc(sizeof(struct segment_command_64)); | |
147 struct section_64 *sect64 = (struct section_64 *)malloc(sizeof(struct section_64)); | |
148 | |
149 struct data_count dc; | |
150 dc.nsects_count = 0; | |
151 dc.sc_count = 0; | |
152 int cmd_count = 0; | |
153 goto analyze_mach_o(md, mh64, sc64, sect64, dc, head,fp, cmd_count); | |
154 } | |
155 | |
156 __code judge_mach_o_file(struct mach_header_64 *mh64, char *head, char *filename, int fp) | |
157 { | |
158 printf("%s is executable file.\n", filename); | |
159 printf("number of load commands : %d\n", mh64->ncmds); | |
160 printf("size of cmds : %d\n", mh64->sizeofcmds); | |
161 | |
162 free(filename); | |
163 | |
164 if (CPU_TYPE_X86_64 == mh64->cputype) printf("CPU : x86_64\n"); | |
165 goto ready_analyzing(mh64, head, fp); | |
166 } | |
167 | |
168 __code judge_filetype(struct mach_header_64 *mh64 , char *head, char *filename, int fp) | |
169 { | |
170 if (MH_EXECUTE != mh64->filetype) { | |
171 fprintf(stderr, "This is not executable file.\n"); | |
172 return; | |
173 } | |
174 goto judge_mach_o_file(mh64, head, filename, fp); | |
175 } | |
176 | |
177 __code judge_header(int fp, struct stat sb, char *head, char *filename) | |
178 { | |
179 struct mach_header_64 *mh64 = (struct mach_header_64 *)head; | |
180 | |
181 if (MH_MAGIC_64 != mh64->magic) { | |
182 fprintf(stderr, "This is not mach header 64.\n"); | |
183 return; | |
184 } | |
185 if (MH_MAGIC_64 == mh64->magic) | |
186 printf("%s is 64bit Mach-O file.\n", filename); | |
187 | |
188 goto judge_filetype(mh64, head, filename, fp); | |
189 } | |
190 | |
191 __code file_map(int fp, struct stat sb, char *filename) | |
192 { | |
193 char *head = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fp, 0); | |
194 goto judge_header(fp, sb, head, filename); | |
195 } | |
196 | |
197 __code get_fstat(int fp, char *filename) | |
198 { | |
199 struct stat sb; | |
200 fstat(fp, &sb); | |
201 goto file_map(fp, sb, filename); | |
202 } | |
203 | |
204 __code file_open(char *filename) | |
205 { | |
35 int fp; | 206 int fp; |
36 if ((fp = open(filename, O_RDONLY)) < 0) { | 207 if ((fp = open(filename, O_RDONLY)) < 0) { |
37 fprintf(stderr, "can not open file\t: %s\n", filename); | 208 fprintf(stderr, "can not open file\t: %s\n", filename); |
38 exit(1); | 209 exit(1); |
39 } | 210 } |
40 | 211 goto get_fstat(fp, filename); |
41 struct stat sb; | 212 } |
42 fstat(fp, &sb); | 213 |
43 | 214 __code option_reader(int argc, char *argv[], char filename[NAME_MAX_LENGTH], int i) |
44 char *head = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fp, 0); | 215 { |
45 | 216 if (i < argc) { |
46 struct mach_header_64 *mh64 = (struct mach_header_64 *)head; | 217 if(argv[i][0] == '-') { |
47 | 218 if(strcmp(argv[i], "-name")==0) { |
48 if (MH_MAGIC_64 != mh64->magic) { | 219 strncpy(filename, argv[i], NAME_MAX_LENGTH); |
49 fprintf(stderr, "This is not mach header 64.\n"); | 220 } |
50 return 0; | 221 } else { |
51 } | 222 strncpy(filename, argv[i], NAME_MAX_LENGTH); |
52 | 223 } |
53 printf("%s is 64bit Mach-O file.\n", filename); | 224 printf("read %s\n", filename); |
54 | 225 i++; |
55 if (MH_EXECUTE != mh64->filetype) { | 226 goto option_reader(argc, argv, filename, i); |
56 fprintf(stderr, "This is not executable file.\n"); | 227 } |
57 return 0; | 228 printf("use %s \n", filename); |
58 } | 229 goto file_open(filename); |
59 | 230 } |
60 printf("%s is executable file.\n", filename); | 231 |
61 | 232 void mach_o_loader(int argc, char *argv[]) |
62 if (CPU_TYPE_X86_64 == mh64->cputype) printf("CPU : x86_64\n"); | 233 { |
63 | 234 int argv_count = 0; |
64 int i = 0; | 235 char *filename = (char *)malloc(sizeof(char)*NAME_MAX_LENGTH); |
65 int mh64_size = sizeof(struct mach_header_64); | 236 goto option_reader(argc, argv, filename, argv_count); |
66 int lc_size = sizeof(struct load_command); | 237 } |
67 for (;i < mh64->ncmds; i++) { | 238 |
68 struct load_command * lc = (struct load_command*)head + lc_size * i; | 239 int main(int argc, char*argv[]) |
69 } | 240 { |
70 | 241 mach_o_loader(argc, argv); |
71 close(fp); | |
72 | |
73 return 0; | 242 return 0; |
74 } | 243 } |