Blame


1 928cc06f 2006-08-08 matthias> /*-
2 7d2c0d24 2012-09-11 matthias * Copyright (c) 2006 Matthias Schmidt <xhr @ giessen.ccc.de>
3 928cc06f 2006-08-08 matthias> *
4 928cc06f 2006-08-08 matthias> * Redistribution and use in source and binary forms, with or without
5 928cc06f 2006-08-08 matthias> * modification, are permitted provided that the following conditions
6 928cc06f 2006-08-08 matthias> * are met:
7 928cc06f 2006-08-08 matthias> *
8 928cc06f 2006-08-08 matthias> * 1. Redistributions of source code must retain the above copyright
9 928cc06f 2006-08-08 matthias> * notice, this list of conditions and the following disclaimer.
10 928cc06f 2006-08-08 matthias> * 2. Redistributions in binary form must reproduce the above copyright
11 928cc06f 2006-08-08 matthias> * notice, this list of conditions and the following disclaimer in the
12 928cc06f 2006-08-08 matthias> * documentation and/or other materials provided with the distribution.
13 928cc06f 2006-08-08 matthias> *
14 928cc06f 2006-08-08 matthias> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
15 928cc06f 2006-08-08 matthias> * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 928cc06f 2006-08-08 matthias> * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 928cc06f 2006-08-08 matthias> * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
18 928cc06f 2006-08-08 matthias> * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 928cc06f 2006-08-08 matthias> * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 928cc06f 2006-08-08 matthias> * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 928cc06f 2006-08-08 matthias> * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 928cc06f 2006-08-08 matthias> * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 928cc06f 2006-08-08 matthias> * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 928cc06f 2006-08-08 matthias> * THE POSSIBILITY OF SUCH DAMAGE.
25 928cc06f 2006-08-08 matthias> */
26 928cc06f 2006-08-08 matthias>
27 8f83b6ce 2006-08-15 matthias> /* $Id: dermob.c,v 1.28 2006/08/15 12:29:02 matthias Exp $ */
28 f72cd7f8 2006-08-08 matthias>
29 928cc06f 2006-08-08 matthias> #include "dermob.h"
30 f3cfd5fa 2006-08-10 matthias> #include "mach.h"
31 9d60efcf 2006-08-11 matthias> #include "defs.h"
32 8f83b6ce 2006-08-15 matthias> #include "list.h"
33 928cc06f 2006-08-08 matthias>
34 928cc06f 2006-08-08 matthias> /*
35 34755f48 2006-08-09 matthias> * Analyse a possible fat header or return silently
36 928cc06f 2006-08-08 matthias> */
37 680a6eb2 2006-08-09 matthias> int
38 9d60efcf 2006-08-11 matthias> analyse_fat_header(char *buffer, int *offset, struct fat_header *rfh)
39 928cc06f 2006-08-08 matthias> {
40 928cc06f 2006-08-08 matthias> struct fat_header *fh;
41 928cc06f 2006-08-08 matthias> char *ptr;
42 928cc06f 2006-08-08 matthias>
43 928cc06f 2006-08-08 matthias> fh = malloc(sizeof(*fh));
44 928cc06f 2006-08-08 matthias> ptr = buffer;
45 928cc06f 2006-08-08 matthias>
46 928cc06f 2006-08-08 matthias> memcpy(fh, ptr, sizeof(*fh));
47 928cc06f 2006-08-08 matthias>
48 680a6eb2 2006-08-09 matthias> /* No universal binary */
49 928cc06f 2006-08-08 matthias> if (fh->magic != FAT_CIGAM && fh->magic != FAT_MAGIC) {
50 928cc06f 2006-08-08 matthias> free(fh);
51 9d60efcf 2006-08-11 matthias> rfh = NULL;
52 9d60efcf 2006-08-11 matthias> return(-1);
53 928cc06f 2006-08-08 matthias> }
54 928cc06f 2006-08-08 matthias>
55 a27a8797 2006-08-09 matthias> if (fh->magic == FAT_MAGIC)
56 a27a8797 2006-08-09 matthias> bo_b = LE;
57 a27a8797 2006-08-09 matthias> else if (fh->magic == FAT_CIGAM)
58 a27a8797 2006-08-09 matthias> bo_b = BE;
59 928cc06f 2006-08-08 matthias>
60 9d60efcf 2006-08-11 matthias> *offset += sizeof(*fh);
61 9d60efcf 2006-08-11 matthias> memcpy(rfh, fh, sizeof(*fh));
62 9d60efcf 2006-08-11 matthias>
63 928cc06f 2006-08-08 matthias> free(fh);
64 9d60efcf 2006-08-11 matthias> return(1);
65 9d60efcf 2006-08-11 matthias> }
66 9d60efcf 2006-08-11 matthias>
67 9d60efcf 2006-08-11 matthias> int
68 9d60efcf 2006-08-11 matthias> analyse_fat_arch(char *buffer, int *offset, struct fat_arch *rfa)
69 9d60efcf 2006-08-11 matthias> {
70 9d60efcf 2006-08-11 matthias> char *ptr;
71 9d60efcf 2006-08-11 matthias> ptr = buffer;
72 9d60efcf 2006-08-11 matthias> ptr += *offset;
73 680a6eb2 2006-08-09 matthias>
74 9d60efcf 2006-08-11 matthias> memcpy(rfa, ptr, sizeof(*rfa));
75 9d60efcf 2006-08-11 matthias> *offset += sizeof(*rfa);
76 9d60efcf 2006-08-11 matthias>
77 9d60efcf 2006-08-11 matthias> return(0);
78 928cc06f 2006-08-08 matthias> }
79 928cc06f 2006-08-08 matthias>
80 4c34a127 2012-09-11 matthias int
81 4c34a127 2012-09-11 matthias determine_mo_arch(char *buffer)
82 4c34a127 2012-09-11 matthias {
83 4c34a127 2012-09-11 matthias struct mach_header_magic mhh;
84 4c34a127 2012-09-11 matthias char *ptr = buffer;
85 4c34a127 2012-09-11 matthias int ret = -1;
86 4c34a127 2012-09-11 matthias
87 4c34a127 2012-09-11 matthias memcpy(&mhh, ptr, sizeof(mhh));
88 4c34a127 2012-09-11 matthias
89 4c34a127 2012-09-11 matthias if (mhh.magic == MH_MAGIC_64)
90 4c34a127 2012-09-11 matthias ret = 0;
91 4c34a127 2012-09-11 matthias else if (mhh.magic == MH_CIGAM_64)
92 4c34a127 2012-09-11 matthias ret = 1;
93 4c34a127 2012-09-11 matthias else if (mhh.magic == MH_MAGIC)
94 4c34a127 2012-09-11 matthias ret = 2;
95 4c34a127 2012-09-11 matthias else if (mhh.magic == MH_CIGAM)
96 4c34a127 2012-09-11 matthias ret = 3;
97 4c34a127 2012-09-11 matthias
98 4c34a127 2012-09-11 matthias return ret;
99 4c34a127 2012-09-11 matthias }
100 4c34a127 2012-09-11 matthias
101 34755f48 2006-08-09 matthias> /*
102 34755f48 2006-08-09 matthias> * Parse the mach-o header, set the correct byte order ot the binary and
103 34755f48 2006-08-09 matthias> * determine the number of load commands.
104 34755f48 2006-08-09 matthias> */
105 680a6eb2 2006-08-09 matthias> int
106 9d60efcf 2006-08-11 matthias> analyse_mo_header(char *buffer, int *offset, struct mach_header *rmh)
107 928cc06f 2006-08-08 matthias> {
108 928cc06f 2006-08-08 matthias> struct mach_header *mh;
109 928cc06f 2006-08-08 matthias> char *ptr;
110 4c34a127 2012-09-11 matthias int moa;
111 9d60efcf 2006-08-11 matthias>
112 9d60efcf 2006-08-11 matthias> ptr = buffer;
113 928cc06f 2006-08-08 matthias> if (offset > 0)
114 928cc06f 2006-08-08 matthias> ptr += *offset;
115 928cc06f 2006-08-08 matthias>
116 4c34a127 2012-09-11 matthias moa = determine_mo_arch(buffer);
117 4c34a127 2012-09-11 matthias if (moa != 0 && moa != 1 && moa != 2 && moa != 3) {
118 4c34a127 2012-09-11 matthias printf("Cannot determine mach-o architecture\n");
119 4c34a127 2012-09-11 matthias return(1);
120 9d60efcf 2006-08-11 matthias> }
121 34755f48 2006-08-09 matthias>
122 4c34a127 2012-09-11 matthias /*
123 4c34a127 2012-09-11 matthias * There is no need to differentiate between 32 and 64bit here, as the
124 4c34a127 2012-09-11 matthias * headers are identical (I ignore the reserved field).
125 4c34a127 2012-09-11 matthias */
126 4c34a127 2012-09-11 matthias mh = malloc(sizeof(*mh));
127 4c34a127 2012-09-11 matthias if (mh == NULL) {
128 4c34a127 2012-09-11 matthias printf("Cannot allocate memory\n");
129 4c34a127 2012-09-11 matthias return(1);
130 4c34a127 2012-09-11 matthias }
131 4c34a127 2012-09-11 matthias memcpy(mh, ptr, sizeof(*mh));
132 4c34a127 2012-09-11 matthias
133 34755f48 2006-08-09 matthias> /* Determine the correct byte order */
134 4c34a127 2012-09-11 matthias if ((mh->magic == MH_MAGIC && bo_a == LE) ||
135 4c34a127 2012-09-11 matthias (mh->magic == MH_MAGIC_64 && bo_a == LE))
136 a27a8797 2006-08-09 matthias> bo_b = LE;
137 4c34a127 2012-09-11 matthias else if ((mh->magic == MH_CIGAM && bo_a == LE) ||
138 4c34a127 2012-09-11 matthias (mh->magic == MH_CIGAM_64 && bo_a == LE))
139 19f06de3 2006-08-10 matthias> bo_b = BE;
140 4c34a127 2012-09-11 matthias else if ((mh->magic == MH_MAGIC && bo_a != LE) ||
141 4c34a127 2012-09-11 matthias (mh->magic == MH_MAGIC_64 && bo_a != LE))
142 a27a8797 2006-08-09 matthias> bo_b = BE;
143 4c34a127 2012-09-11 matthias else if ((mh->magic == MH_CIGAM && bo_a != LE) ||
144 4c34a127 2012-09-11 matthias (mh->magic == MH_CIGAM_64 && bo_a != LE))
145 a27a8797 2006-08-09 matthias> bo_b = LE;
146 3dc682c0 2006-08-10 matthias>
147 3dc682c0 2006-08-10 matthias> offset_moh = *offset;
148 928cc06f 2006-08-08 matthias> *offset += sizeof(*mh);
149 928cc06f 2006-08-08 matthias>
150 9d60efcf 2006-08-11 matthias> memcpy(rmh, mh, sizeof(*rmh));
151 928cc06f 2006-08-08 matthias> free(mh);
152 680a6eb2 2006-08-09 matthias>
153 9d60efcf 2006-08-11 matthias> return(0);
154 928cc06f 2006-08-08 matthias> }
155 928cc06f 2006-08-08 matthias>
156 34755f48 2006-08-09 matthias> /*
157 34755f48 2006-08-09 matthias> * Analyse all load commands
158 34755f48 2006-08-09 matthias> */
159 928cc06f 2006-08-08 matthias> void
160 9d60efcf 2006-08-11 matthias> analyse_load_command(char *buffer, int *offset, struct load_command *rld)
161 928cc06f 2006-08-08 matthias> {
162 928cc06f 2006-08-08 matthias> char *ptr;
163 928cc06f 2006-08-08 matthias>
164 928cc06f 2006-08-08 matthias> ptr = buffer;
165 9d60efcf 2006-08-11 matthias> ptr += *offset;
166 928cc06f 2006-08-08 matthias>
167 9d60efcf 2006-08-11 matthias> memcpy(rld, ptr, sizeof(*rld));
168 928cc06f 2006-08-08 matthias> }
169 928cc06f 2006-08-08 matthias>
170 34755f48 2006-08-09 matthias> /*
171 34755f48 2006-08-09 matthias> * Examine the different sections and display various information.
172 34755f48 2006-08-09 matthias> */
173 928cc06f 2006-08-08 matthias> void
174 9d60efcf 2006-08-11 matthias> examine_section(char *buffer, int *offset, struct section *rsec)
175 928cc06f 2006-08-08 matthias> {
176 9d60efcf 2006-08-11 matthias> char *ptr;
177 928cc06f 2006-08-08 matthias>
178 9d60efcf 2006-08-11 matthias> ptr = buffer;
179 9d60efcf 2006-08-11 matthias> ptr += *offset;
180 9d60efcf 2006-08-11 matthias>
181 9d60efcf 2006-08-11 matthias> memcpy(rsec, ptr, sizeof(*rsec));
182 9d60efcf 2006-08-11 matthias> *offset += sizeof(*rsec);
183 928cc06f 2006-08-08 matthias> }
184 928cc06f 2006-08-08 matthias>
185 34755f48 2006-08-09 matthias> /*
186 34755f48 2006-08-09 matthias> * Examine the different segments and display various information.
187 34755f48 2006-08-09 matthias> */
188 928cc06f 2006-08-08 matthias> int
189 9d60efcf 2006-08-11 matthias> examine_segmet(char *buffer, int *offset, int cmd, int cmdsize, int *nofx)
190 928cc06f 2006-08-08 matthias> {
191 928cc06f 2006-08-08 matthias> struct segment_command *sc;
192 928cc06f 2006-08-08 matthias> struct symtab_command *symc;
193 928cc06f 2006-08-08 matthias> struct dylib_command *dly;
194 928cc06f 2006-08-08 matthias> struct dylinker_command *dlnk;
195 04bfbc9a 2006-08-09 matthias> struct dysymtab_command *dsym;
196 d3f3e663 2006-08-09 matthias> struct twolevel_hints_command *two;
197 928cc06f 2006-08-08 matthias> int ret = 0;
198 9d60efcf 2006-08-11 matthias> char *ptr;
199 928cc06f 2006-08-08 matthias>
200 9d60efcf 2006-08-11 matthias> ptr = buffer;
201 9d60efcf 2006-08-11 matthias> ptr += *offset;
202 9d60efcf 2006-08-11 matthias>
203 928cc06f 2006-08-08 matthias> switch(cmd) {
204 928cc06f 2006-08-08 matthias> case LC_SEGMENT:
205 928cc06f 2006-08-08 matthias> sc = malloc(sizeof(*sc));
206 928cc06f 2006-08-08 matthias> memcpy(sc, ptr, sizeof(*sc));
207 8f83b6ce 2006-08-15 matthias> list_insert_node(lst, sc, 0x6);
208 a27a8797 2006-08-09 matthias> *nofx = swapi(sc->nsects);
209 9d60efcf 2006-08-11 matthias> //*offset += sizeof(*sc);
210 928cc06f 2006-08-08 matthias> ret = sizeof(*sc);
211 928cc06f 2006-08-08 matthias> break;
212 928cc06f 2006-08-08 matthias> case LC_SYMTAB:
213 928cc06f 2006-08-08 matthias> symc = malloc(sizeof(*symc));
214 928cc06f 2006-08-08 matthias> memcpy(symc, ptr, sizeof(*symc));
215 8f83b6ce 2006-08-15 matthias> list_insert_node(lst, symc, 0x7);
216 9d60efcf 2006-08-11 matthias> //*offset += sizeof(*symc);
217 928cc06f 2006-08-08 matthias> ret = sizeof(*symc);
218 928cc06f 2006-08-08 matthias> break;
219 928cc06f 2006-08-08 matthias> case LC_LOAD_DYLIB:
220 680a6eb2 2006-08-09 matthias> dynamic = 1;
221 928cc06f 2006-08-08 matthias> dly = malloc(sizeof(*dly));
222 928cc06f 2006-08-08 matthias> memcpy(dly, ptr, sizeof(*dly));
223 8f83b6ce 2006-08-15 matthias> list_insert_node(lst, dly, 0x8);
224 9d60efcf 2006-08-11 matthias> //*offset += sizeof(*dly);
225 928cc06f 2006-08-08 matthias> ret = sizeof(*dly);
226 928cc06f 2006-08-08 matthias> break;
227 928cc06f 2006-08-08 matthias> case LC_LOAD_DYLINKER:
228 928cc06f 2006-08-08 matthias> dlnk = malloc(sizeof(*dlnk));
229 928cc06f 2006-08-08 matthias> memcpy(dlnk, ptr, sizeof(*dlnk));
230 8f83b6ce 2006-08-15 matthias> //mprintf(" Name: %s\n", ptr+swapi(dlnk->name.offset));
231 9d60efcf 2006-08-11 matthias> //*offset += sizeof(*dlnk);
232 928cc06f 2006-08-08 matthias> ret = sizeof(*dlnk);
233 928cc06f 2006-08-08 matthias> break;
234 928cc06f 2006-08-08 matthias> case LC_DYSYMTAB:
235 04bfbc9a 2006-08-09 matthias> dsym = malloc(sizeof(*dsym));
236 04bfbc9a 2006-08-09 matthias> memcpy(dsym, ptr, sizeof(*dsym));
237 8f83b6ce 2006-08-15 matthias> list_insert_node(lst, dsym, 0x9);
238 9d60efcf 2006-08-11 matthias> //*offset += sizeof(*dsym);
239 04bfbc9a 2006-08-09 matthias> ret = sizeof(*dsym);
240 928cc06f 2006-08-08 matthias> break;
241 d3f3e663 2006-08-09 matthias> case LC_TWOLEVEL_HINTS:
242 d3f3e663 2006-08-09 matthias> two = malloc(sizeof(*two));
243 d3f3e663 2006-08-09 matthias> memcpy(two, ptr, sizeof(*two));
244 8f83b6ce 2006-08-15 matthias> list_insert_node(lst, two, 0xa);
245 9d60efcf 2006-08-11 matthias> //*offset += sizeof(*two);
246 d3f3e663 2006-08-09 matthias> ret = sizeof(*two);
247 d3f3e663 2006-08-09 matthias> break;
248 928cc06f 2006-08-08 matthias> case LC_THREAD:
249 928cc06f 2006-08-08 matthias> case LC_UNIXTHREAD:
250 928cc06f 2006-08-08 matthias> break;
251 928cc06f 2006-08-08 matthias> case LC_ROUTINES:
252 680a6eb2 2006-08-09 matthias> mprintf("routines\n");
253 928cc06f 2006-08-08 matthias> break;
254 928cc06f 2006-08-08 matthias> case LC_ID_DYLIB:
255 680a6eb2 2006-08-09 matthias> mprintf("id dylib\n");
256 928cc06f 2006-08-08 matthias> break;
257 928cc06f 2006-08-08 matthias> default:
258 928cc06f 2006-08-08 matthias> break;
259 928cc06f 2006-08-08 matthias> }
260 928cc06f 2006-08-08 matthias>
261 928cc06f 2006-08-08 matthias> return (ret);
262 928cc06f 2006-08-08 matthias> }
263 928cc06f 2006-08-08 matthias>
264 34755f48 2006-08-09 matthias> /*
265 34755f48 2006-08-09 matthias> * Display the __TEXT,__text section (the actual machine code) as hexadecimal
266 34755f48 2006-08-09 matthias> * values on screen.
267 34755f48 2006-08-09 matthias> */
268 928cc06f 2006-08-08 matthias> void
269 3c99c35c 2006-08-10 matthias> display_buffer(char *buffer, int addr, int offset, int size)
270 928cc06f 2006-08-08 matthias> {
271 928cc06f 2006-08-08 matthias> char *ptr;
272 023c1dc6 2006-08-10 matthias> char line[17];
273 928cc06f 2006-08-08 matthias> int i, j=0;
274 928cc06f 2006-08-08 matthias>
275 3c99c35c 2006-08-10 matthias> if (offset < 0)
276 928cc06f 2006-08-08 matthias> return;
277 928cc06f 2006-08-08 matthias>
278 e5c4b07e 2006-08-12 matthias> printf("Starting at address 0x%x offset %d size %d\n", addr, offset, size);
279 928cc06f 2006-08-08 matthias>
280 928cc06f 2006-08-08 matthias> ptr = buffer;
281 928cc06f 2006-08-08 matthias> ptr += offset;
282 3dc682c0 2006-08-10 matthias> // Skip the fat header, if necessarry
283 3dc682c0 2006-08-10 matthias> ptr += offset_moh;
284 3dc682c0 2006-08-10 matthias> offset += offset_moh;
285 023c1dc6 2006-08-10 matthias>
286 7178c096 2006-08-12 matthias> memset(line, 0, sizeof(line));
287 7178c096 2006-08-12 matthias>
288 023c1dc6 2006-08-10 matthias> for (i = 0; i < size; i++) {
289 023c1dc6 2006-08-10 matthias> if (j == 0)
290 023c1dc6 2006-08-10 matthias> printf("%.08x ", offset+i);
291 928cc06f 2006-08-08 matthias> printf("%.02x ", (*ptr & 0xFF));
292 aefa6987 2006-08-09 matthias>
293 aefa6987 2006-08-09 matthias> if (isprint(*ptr & 0xFF))
294 023c1dc6 2006-08-10 matthias> line[j] = (*ptr & 0xFF);
295 aefa6987 2006-08-09 matthias> else
296 023c1dc6 2006-08-10 matthias> line[j] = '.';
297 023c1dc6 2006-08-10 matthias> j++;
298 928cc06f 2006-08-08 matthias> if (j == 16) {
299 3c99c35c 2006-08-10 matthias> printf(" %s\n", line);
300 928cc06f 2006-08-08 matthias> j = 0;
301 aefa6987 2006-08-09 matthias> } else if (j == 8)
302 aefa6987 2006-08-09 matthias> printf(" ");
303 023c1dc6 2006-08-10 matthias> ptr += 1;
304 928cc06f 2006-08-08 matthias> }
305 928cc06f 2006-08-08 matthias> printf("\n");
306 928cc06f 2006-08-08 matthias> }