2 * Copyright (c) 2006 Matthias Schmidt <xhr @ giessen.ccc.de>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
27 /* $Id: dermob.c,v 1.28 2006/08/15 12:29:02 matthias Exp $ */
35 * Analyse a possible fat header or return silently
38 analyse_fat_header(char *buffer, int *offset, struct fat_header *rfh)
40 struct fat_header *fh;
43 fh = malloc(sizeof(*fh));
46 memcpy(fh, ptr, sizeof(*fh));
48 /* No universal binary */
49 if (fh->magic != FAT_CIGAM && fh->magic != FAT_MAGIC) {
55 if (fh->magic == FAT_MAGIC)
57 else if (fh->magic == FAT_CIGAM)
60 *offset += sizeof(*fh);
61 memcpy(rfh, fh, sizeof(*fh));
68 analyse_fat_arch(char *buffer, int *offset, struct fat_arch *rfa)
74 memcpy(rfa, ptr, sizeof(*rfa));
75 *offset += sizeof(*rfa);
81 determine_mo_arch(char *buffer)
83 struct mach_header_magic mhh;
87 memcpy(&mhh, ptr, sizeof(mhh));
89 if (mhh.magic == MH_MAGIC_64)
91 else if (mhh.magic == MH_CIGAM_64)
93 else if (mhh.magic == MH_MAGIC)
95 else if (mhh.magic == MH_CIGAM)
102 * Parse the mach-o header, set the correct byte order ot the binary and
103 * determine the number of load commands.
106 analyse_mo_header(char *buffer, int *offset, struct mach_header *rmh)
108 struct mach_header *mh;
116 moa = determine_mo_arch(buffer);
117 if (moa != 0 && moa != 1 && moa != 2 && moa != 3) {
118 printf("Cannot determine mach-o architecture\n");
123 * There is no need to differentiate between 32 and 64bit here, as the
124 * headers are identical (I ignore the reserved field).
126 mh = malloc(sizeof(*mh));
128 printf("Cannot allocate memory\n");
131 memcpy(mh, ptr, sizeof(*mh));
133 /* Determine the correct byte order */
134 if ((mh->magic == MH_MAGIC && bo_a == LE) ||
135 (mh->magic == MH_MAGIC_64 && bo_a == LE))
137 else if ((mh->magic == MH_CIGAM && bo_a == LE) ||
138 (mh->magic == MH_CIGAM_64 && bo_a == LE))
140 else if ((mh->magic == MH_MAGIC && bo_a != LE) ||
141 (mh->magic == MH_MAGIC_64 && bo_a != LE))
143 else if ((mh->magic == MH_CIGAM && bo_a != LE) ||
144 (mh->magic == MH_CIGAM_64 && bo_a != LE))
147 offset_moh = *offset;
148 *offset += sizeof(*mh);
150 memcpy(rmh, mh, sizeof(*rmh));
157 * Analyse all load commands
160 analyse_load_command(char *buffer, int *offset, struct load_command *rld)
167 memcpy(rld, ptr, sizeof(*rld));
171 * Examine the different sections and display various information.
174 examine_section(char *buffer, int *offset, struct section *rsec)
181 memcpy(rsec, ptr, sizeof(*rsec));
182 *offset += sizeof(*rsec);
186 * Examine the different segments and display various information.
189 examine_segmet(char *buffer, int *offset, int cmd, int cmdsize, int *nofx)
191 struct segment_command *sc;
192 struct symtab_command *symc;
193 struct dylib_command *dly;
194 struct dylinker_command *dlnk;
195 struct dysymtab_command *dsym;
196 struct twolevel_hints_command *two;
205 sc = malloc(sizeof(*sc));
206 memcpy(sc, ptr, sizeof(*sc));
207 list_insert_node(lst, sc, 0x6);
208 *nofx = swapi(sc->nsects);
209 //*offset += sizeof(*sc);
213 symc = malloc(sizeof(*symc));
214 memcpy(symc, ptr, sizeof(*symc));
215 list_insert_node(lst, symc, 0x7);
216 //*offset += sizeof(*symc);
221 dly = malloc(sizeof(*dly));
222 memcpy(dly, ptr, sizeof(*dly));
223 list_insert_node(lst, dly, 0x8);
224 //*offset += sizeof(*dly);
227 case LC_LOAD_DYLINKER:
228 dlnk = malloc(sizeof(*dlnk));
229 memcpy(dlnk, ptr, sizeof(*dlnk));
230 //mprintf(" Name: %s\n", ptr+swapi(dlnk->name.offset));
231 //*offset += sizeof(*dlnk);
235 dsym = malloc(sizeof(*dsym));
236 memcpy(dsym, ptr, sizeof(*dsym));
237 list_insert_node(lst, dsym, 0x9);
238 //*offset += sizeof(*dsym);
241 case LC_TWOLEVEL_HINTS:
242 two = malloc(sizeof(*two));
243 memcpy(two, ptr, sizeof(*two));
244 list_insert_node(lst, two, 0xa);
245 //*offset += sizeof(*two);
252 mprintf("routines\n");
255 mprintf("id dylib\n");
265 * Display the __TEXT,__text section (the actual machine code) as hexadecimal
269 display_buffer(char *buffer, int addr, int offset, int size)
278 printf("Starting at address 0x%x offset %d size %d\n", addr, offset, size);
282 // Skip the fat header, if necessarry
284 offset += offset_moh;
286 memset(line, 0, sizeof(line));
288 for (i = 0; i < size; i++) {
290 printf("%.08x ", offset+i);
291 printf("%.02x ", (*ptr & 0xFF));
293 if (isprint(*ptr & 0xFF))
294 line[j] = (*ptr & 0xFF);
299 printf(" %s\n", line);