|
|
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.