Root/
Source at commit HEAD created 5 years 6 days ago. By ifabio, Few update to kernelPatcher (Credits to CrazyBirdy) | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights␊ |
7 | * Reserved. This file contains Original Code and/or Modifications of␊ |
8 | * Original Code as defined in and that are subject to the Apple Public␊ |
9 | * Source License Version 2.0 (the "License"). You may not use this file␊ |
10 | * except in compliance with the License. Please obtain a copy of the␊ |
11 | * License at http://www.apple.com/publicsource and read it before using␊ |
12 | * this file.␊ |
13 | * ␊ |
14 | * The Original Code and all software distributed under the License are␊ |
15 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the␊ |
19 | * License for the specific language governing rights and limitations␊ |
20 | * under the License.␊ |
21 | * ␊ |
22 | * @APPLE_LICENSE_HEADER_END@␊ |
23 | */␊ |
24 | ␊ |
25 | #include <stdio.h>␊ |
26 | #include <stdlib.h>␊ |
27 | #include <stdbool.h>␊ |
28 | #include <mach/mach.h>␊ |
29 | #include <mach/mach_error.h>␊ |
30 | #include <sys/file.h>␊ |
31 | #include <mach-o/loader.h>␊ |
32 | #include <libkern/OSByteOrder.h>␊ |
33 | #include <unistd.h>␊ |
34 | ␊ |
35 | int␉infile, outfile;␊ |
36 | ␊ |
37 | void *cmds;␊ |
38 | ␊ |
39 | struct mach_header␉mh;␊ |
40 | ␊ |
41 | static bool␉swap_ends;␊ |
42 | ␊ |
43 | //==============================================================================␊ |
44 | ␊ |
45 | static unsigned long swap(unsigned long x)␊ |
46 | {␊ |
47 | ␉if (swap_ends)␊ |
48 | ␉{␊ |
49 | ␉␉return OSSwapInt32(x);␊ |
50 | ␉}␊ |
51 | ␉else␊ |
52 | ␉{␊ |
53 | ␉␉return x;␊ |
54 | ␉}␊ |
55 | }␊ |
56 | ␊ |
57 | ␊ |
58 | //==============================================================================␊ |
59 | ␊ |
60 | int main(int argc, char *argv[])␊ |
61 | {␊ |
62 | ␉kern_return_t␉result;␊ |
63 | ␉vm_address_t␉data;␊ |
64 | ␉int␉␉␉nc, ncmds;␊ |
65 | ␉char *␉␉cp;␊ |
66 | ␊ |
67 | ␉if (argc == 2)␊ |
68 | ␉{␊ |
69 | ␉␉infile = open(argv[1], O_RDONLY);␊ |
70 | ␊ |
71 | ␉␉if (infile < 0)␊ |
72 | ␉␉{␊ |
73 | ␉␉␉goto filenotfound;␊ |
74 | ␉␉}␊ |
75 | ␊ |
76 | ␉␉outfile = fileno(stdout);␊ |
77 | ␉}␊ |
78 | ␉else if (argc == 3)␊ |
79 | ␉{␊ |
80 | ␉␉infile = open(argv[1], O_RDONLY);␊ |
81 | ␊ |
82 | ␉␉if (infile < 0)␊ |
83 | ␉␉{␊ |
84 | ␉␉␉goto filenotfound;␊ |
85 | ␉␉}␊ |
86 | ␊ |
87 | ␉␉outfile = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);␊ |
88 | ␊ |
89 | ␉␉if (outfile < 0)␊ |
90 | ␉␉{␊ |
91 | ␉␉␉goto openerror;␊ |
92 | ␉␉}␊ |
93 | ␉}␊ |
94 | ␉else␊ |
95 | ␉{␊ |
96 | ␉␉fprintf(stderr, "Usage: machOconv inputfile [outputfile]\n");␊ |
97 | ␉␉exit(1);␊ |
98 | ␊ |
99 | ␉␉filenotfound:␊ |
100 | ␉␉␉fprintf(stderr, "Error: File Not Found\n");␊ |
101 | ␉␉␉exit(1);␊ |
102 | ␊ |
103 | ␉␉openerror:␊ |
104 | ␉␉␉fprintf(stderr, "Error: Open Failed\n");␊ |
105 | ␉␉␉exit(1);␊ |
106 | ␉}␊ |
107 | ␊ |
108 | ␉nc = read(infile, &mh, sizeof (mh));␊ |
109 | ␊ |
110 | ␉if (nc < 0)␊ |
111 | ␉{␊ |
112 | ␉␉perror("read mach header");␊ |
113 | ␉␉exit(1);␊ |
114 | ␉}␊ |
115 | ␊ |
116 | ␉if (nc < (int)sizeof (mh))␊ |
117 | ␉{␊ |
118 | ␉␉fprintf(stderr, "Error: read mach header: premature EOF %d\n", nc);␊ |
119 | ␉␉exit(1);␊ |
120 | ␉}␊ |
121 | ␊ |
122 | ␉if (mh.magic == MH_MAGIC)␊ |
123 | ␉{␊ |
124 | ␉␉swap_ends = false;␊ |
125 | ␉}␊ |
126 | ␉else if (mh.magic == MH_CIGAM)␊ |
127 | ␉{␊ |
128 | ␉␉swap_ends = true;␊ |
129 | ␉}␊ |
130 | ␉else␊ |
131 | ␉{␊ |
132 | ␉␉fprintf(stderr, "Error: bad magic number %lx\n", (unsigned long)mh.magic);␊ |
133 | ␉␉exit(1);␊ |
134 | ␉}␊ |
135 | ␊ |
136 | ␉cmds = calloc(swap(mh.sizeofcmds), sizeof (char));␊ |
137 | ␊ |
138 | ␉if (cmds == 0)␊ |
139 | ␉{␊ |
140 | ␉␉fprintf(stderr, "Error: alloc load commands: no memory\n");␊ |
141 | ␉␉exit(1);␊ |
142 | ␉}␊ |
143 | ␊ |
144 | ␉nc = read(infile, cmds, swap(mh.sizeofcmds));␊ |
145 | ␊ |
146 | ␉if (nc < 0)␊ |
147 | ␉{␊ |
148 | ␉␉perror("read load commands");␊ |
149 | ␉␉exit(1);␊ |
150 | ␉}␊ |
151 | ␊ |
152 | ␉if (nc < (int)swap(mh.sizeofcmds))␊ |
153 | ␉{␊ |
154 | ␉␉fprintf(stderr, "Error: read load commands: premature EOF %d\n", nc);␊ |
155 | ␉␉exit(1);␊ |
156 | ␉}␊ |
157 | ␊ |
158 | ␉unsigned long vmstart = (unsigned long) -1;␊ |
159 | ␊ |
160 | ␉// First pass: determine actual load address␊ |
161 | ␉for (ncmds = swap(mh.ncmds), cp = cmds; ncmds > 0; ncmds--)␊ |
162 | ␉{␊ |
163 | #define lcp␉((struct load_command *)cp)␊ |
164 | #define scp␉((struct segment_command *)cp)␊ |
165 | ␊ |
166 | ␉␉switch(swap(lcp->cmd))␊ |
167 | ␉␉{␊ |
168 | ␉␉␉case LC_SEGMENT:␊ |
169 | ␉␉␉␉if (vmstart > swap(scp->vmaddr)) ␊ |
170 | ␉␉␉␉{␊ |
171 | ␉␉␉␉␉vmstart = swap(scp->vmaddr);␊ |
172 | ␉␉␉␉}␊ |
173 | ␉␉}␊ |
174 | ␉␉cp += swap(lcp->cmdsize);␊ |
175 | ␊ |
176 | ␉}␊ |
177 | ␊ |
178 | ␉// Second pass: output to file.␊ |
179 | ␉for (ncmds = swap(mh.ncmds), cp = cmds; ncmds > 0; ncmds--)␊ |
180 | ␉{␊ |
181 | #define lcp␉((struct load_command *)cp)␊ |
182 | #define scp␉((struct segment_command *)cp)␊ |
183 | ␊ |
184 | ␉␉bool␉isDATA;␊ |
185 | ␉␉unsigned␉vmsize;␊ |
186 | ␊ |
187 | ␉␉switch(swap(lcp->cmd))␊ |
188 | ␉␉{␊ |
189 | ␉␉␉case LC_SEGMENT:␊ |
190 | ␉␉␉␉isDATA = (strncmp(scp->segname, "__DATA", sizeof("__DATA")) == 0);␊ |
191 | ␊ |
192 | ␉␉␉␉if (isDATA)␊ |
193 | ␉␉␉␉{␊ |
194 | ␉␉␉␉␉vmsize = swap(scp->filesize);␊ |
195 | ␉␉␉␉}␊ |
196 | ␉␉␉␉else␊ |
197 | ␉␉␉␉{␊ |
198 | ␉␉␉␉␉vmsize = swap(scp->vmsize);␊ |
199 | ␉␉␉␉}␊ |
200 | ␊ |
201 | ␉␉␉␉result = vm_allocate(mach_task_self(), &data, vmsize, true);␊ |
202 | ␊ |
203 | ␉␉␉␉if (result != KERN_SUCCESS)␊ |
204 | ␉␉␉␉{␊ |
205 | ␉␉␉␉␉mach_error("vm_allocate segment data", result);␊ |
206 | ␉␉␉␉␉exit(1);␊ |
207 | ␉␉␉␉}␊ |
208 | ␊ |
209 | ␉␉␉␉lseek(infile, swap(scp->fileoff), L_SET);␊ |
210 | ␉␉␉␉nc = read(infile, (void *)data, swap(scp->filesize));␊ |
211 | ␊ |
212 | ␉␉␉␉if (nc < 0)␊ |
213 | ␉␉␉␉{␊ |
214 | ␉␉␉␉␉perror("read segment data");␊ |
215 | ␉␉␉␉␉exit(1);␊ |
216 | ␉␉␉␉}␊ |
217 | ␊ |
218 | ␉␉␉␉if (nc < (int)swap(scp->filesize))␊ |
219 | ␉␉␉␉{␊ |
220 | ␉␉␉␉␉fprintf(stderr, "read segment data: premature EOF %d\n", nc);␊ |
221 | ␉␉␉␉␉exit(1);␊ |
222 | ␉␉␉␉}␊ |
223 | ␊ |
224 | ␉␉␉␉lseek(outfile, swap(scp->vmaddr) - vmstart, L_SET);␊ |
225 | ␉␉␉␉nc = write(outfile, (void *)data, vmsize);␊ |
226 | ␊ |
227 | ␉␉␉␉if (nc < (int)vmsize)␊ |
228 | ␉␉␉␉{␊ |
229 | ␉␉␉␉␉perror("write segment data");␊ |
230 | ␉␉␉␉␉exit(1);␊ |
231 | ␉␉␉␉}␊ |
232 | ␊ |
233 | ␉␉␉␉vm_deallocate(mach_task_self(), data, vmsize);␊ |
234 | ␉␉␉␉break;␊ |
235 | ␉␉}␊ |
236 | ␊ |
237 | ␉␉cp += swap(lcp->cmdsize);␊ |
238 | ␉}␊ |
239 | ␉␊ |
240 | ␉exit(0);␊ |
241 | }␊ |
242 |