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 }