|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 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 1.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: #import "RegionManager.h"
25:
26: #import <stdlib.h>
27: #import <string.h>
28: #import <sys/loader.h>
29:
30: @implementation RegionManager
31:
32: -initialize: (vm_task_t)theTask
33: {
34: regions = [Storage newCount: 0
35: elementSize: sizeof(Region)
36: description: @encode(Region)];
37: task = theTask;
38: return self;
39: }
40: +newTask: (vm_task_t)theTask
41: {
42: return [[super new] initialize: theTask];
43: }
44:
45: -free
46: {
47: int count;
48: Region *region;
49: for (count = [regions count]; count; count--) {
50: region = [regions elementAt: (count - 1)];
51: vm_deallocate(task_self(), region->data, region->dataCount);
52: }
53: [regions free];
54: return [super free];
55: }
56:
57: -(Region *)regionFor: (void *)pointer
58: {
59: Region newRegion;
60: kern_return_t error = NO;
61: Region *region = NULL;
62: int count;
63: BOOL found;
64: for (count = [regions count], found = NO; count && !found; count--) {
65: region = [regions elementAt: (count - 1)];
66: if ( (region->address <= (pointer_t)pointer)
67: && ((pointer_t)pointer < (region->maxAddress)))
68: found = YES;
69: }
70: if (!found) {
71: newRegion.address = (vm_address_t)pointer;
72: error = vm_region( task,
73: &newRegion.address,
74: &newRegion.size,
75: &newRegion.protection,
76: &newRegion.maxProtection,
77: &newRegion.inheritance,
78: &newRegion.shared,
79: &newRegion.objectName,
80: &newRegion.offset);
81: if (!error && (newRegion.protection & VM_PROT_READ)) {
82: error = vm_read( task,
83: newRegion.address,
84: newRegion.size,
85: &newRegion.data,
86: &newRegion.dataCount);
87: if (!error) {
88: newRegion.maxAddress = newRegion.address + newRegion.size;
89: newRegion.maxData = newRegion.data + newRegion.size;
90: newRegion.displacement = newRegion.data - newRegion.address;
91: [regions addElement: &newRegion];
92: region = &newRegion;
93: } else
94: region = NULL;
95: } else
96: region = NULL;
97: }
98: return region;
99: }
100:
101: -invalidate
102: {
103: int count;
104: Region *region;
105: for (count = [regions count]; count; count--) {
106: region = [regions elementAt: (count - 1)];
107: vm_deallocate(task_self(), region->data, region->dataCount);
108: }
109: [regions empty];
110: return self;
111: }
112:
113: -(Region *)oldRegionFor: (void *)pointer
114: {
115: Region *region = NULL;
116: int count;
117: BOOL found;
118: for (count = [regions count], found = NO; count && !found; count--) {
119: region = [regions elementAt: (count - 1)];
120: if ((region->data <= (pointer_t)pointer)
121: && ((pointer_t)pointer < region->maxData))
122: found = YES;
123: }
124: if (found)
125: return region;
126: else
127: return NULL;
128: }
129:
130: -(void *)originalPointerFor: (void *)pointer
131: {
132: Region *region = [self oldRegionFor: pointer];
133: if (region)
134: return (region->address + (pointer - region->data));
135: else
136: return NULL;
137: }
138:
139: -(void *)pointerFor: (void *)pointer
140: {
141: Region *region;
142: if (pointer && (region = [self regionFor: pointer]))
143: return (void *)((pointer_t)pointer + region->displacement);
144: else
145: return NULL;
146: }
147:
148: -(void *)pointerFor: (void *)pointer withSize: (int)size
149: {
150: Region *region;
151: pointer_t newPointer;
152: if (pointer && (region = [self regionFor: pointer])) {
153: newPointer = (pointer_t)pointer + region->displacement;
154: if ((newPointer + size) < region->maxData)
155: return (void *)newPointer;
156: else
157: return NULL;
158: } else
159: return NULL;
160: }
161:
162: -(id)pointerForID: (id)pointer
163: {
164: Region *region;
165: pointer_t newID;
166: Class theClass;
167: if (pointer && (region = [self regionFor: pointer])) {
168: newID = (pointer_t)pointer + region->displacement;
169: if ( ((newID + sizeof(id)) < region->maxData)
170: && (theClass = [self pointerFor: ((id)newID)->isa withSize: sizeof(Class)])
171: && ((newID + theClass->instance_size) < region->maxData))
172: return (id)newID;
173: else
174: return NULL;
175: } else
176: return NULL;
177: }
178:
179:
180: -(BOOL)getDataAt: (void *)start for: (int)numBytes into: (void *)data
181: {
182: Region *region = [self regionFor: start];
183: if (region) {
184: if (((pointer_t)start + numBytes) < (region->address + region->size)) {
185: memcpy(data, (void *)(region->data + ((pointer_t)start - region->address)), numBytes);
186: return YES;
187: } else
188: return NO;
189: } else
190: return NO;
191: }
192:
193: -(struct mach_header *)getMachHeader
194: {
195: BOOL found;
196: Region *region;
197: Region newRegion;
198: struct mach_header *myHeader = NULL, *hisHeader;
199: for ( found = NO, hisHeader = 0x0000;
200: !found;
201: hisHeader = (struct mach_header *)(region->address + region->size)) {
202: region = [self regionFor: hisHeader];
203: if (region) {
204: myHeader = (struct mach_header *)(region->data + ((pointer_t)hisHeader - region->address));
205: if (myHeader->magic == MH_MAGIC)
206: found = YES;
207: } else {
208: newRegion.address = (vm_address_t) hisHeader;
209: vm_region( task,
210: &newRegion.address,
211: &newRegion.size,
212: &newRegion.protection,
213: &newRegion.maxProtection,
214: &newRegion.inheritance,
215: &newRegion.shared,
216: &newRegion.objectName,
217: &newRegion.offset);
218: region = &newRegion;
219: }
220: }
221: return myHeader;
222: }
223:
224: -(struct mach_header **)getMachHeaders
225: {
226: struct mach_header *myHeader, **headers;
227: struct fvmlib_command *loadCmd;
228: int numHeaders, i, headerIndex;
229: myHeader = [self getMachHeader];
230: for ( i = 0, numHeaders = 0, loadCmd = (struct fvmlib_command *)(myHeader + 1);
231: i < myHeader->ncmds;
232: i++, loadCmd = (struct fvmlib_command *)((char *)loadCmd + loadCmd->cmdsize)) {
233: if (loadCmd->cmd == LC_LOADFVMLIB)
234: numHeaders++;
235: }
236: headers = malloc((numHeaders + 2) * sizeof(*headers));
237: headers[0] = myHeader;
238: for ( headerIndex = 1, loadCmd = (struct fvmlib_command *)(myHeader + 1);
239: headerIndex <= numHeaders;
240: loadCmd = (struct fvmlib_command *)((char *)loadCmd + loadCmd->cmdsize)) {
241: if (loadCmd->cmd == LC_LOADFVMLIB) {
242: headers[headerIndex] = [self pointerFor: (void *)(loadCmd->fvmlib.header_addr)];
243: /* snaroff */
244: headers[headerIndex]->flags =
245: (char *)[self originalPointerFor:loadCmd] +
246: loadCmd->fvmlib.name.offset;
247: headerIndex++;
248: }
249: }
250: headers[headerIndex] = NULL;
251: return headers;
252: }
253:
254: -(void *) getSectData: (STR)segName
255: section: (STR)sectName
256: size: (int *)pSize
257: forHeader: (struct mach_header *)header
258: {
259: void *data = getsectdatafromheader(header, segName, sectName, pSize);
260: return [self pointerFor: data];
261: }
262:
263: -(void *) getSectData: (STR)segName
264: section: (STR)sectName
265: size: (int *)pSize
266: {
267: return [self getSectData: segName section: sectName size: pSize forHeader: [self getMachHeader]];
268: }
269:
270: @end
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.