UInt32 IOFireWirePCRSpace::doWrite(UInt16 nodeID, IOFWSpeed &speed, FWAddress addr, UInt32 len, const void *buf, IOFWRequestRefCon refcon) { //IOLog( "IOFireWirePCRSpace::doWrite (0x%08X)\n",(int) this); if(addr.addressHi != kCSRRegisterSpaceBaseAddressHi) return kFWResponseAddressError; if((addr.addressLo < kPCRBaseAddress) || (addr.addressLo + len > kPCRBaseAddress + 64*4)) return kFWResponseAddressError; //IOLog("PCRSpace write, addr %x len %d\n", addr.addressLo, len); // Writes to Plug Control registers not allowed. if(!fControl->isLockRequest(refcon)) return kFWResponseTypeError; // Only allow update of one register. if(len != 4 || (addr.addressLo & 3)) return kFWResponseTypeError; UInt32 newVal = *(const UInt32 *)buf; UInt32 offset = (addr.addressLo - kPCRBaseAddress)/4; UInt32 oldVal = OSSwapBigToHostInt32(fBuf[offset]); fBuf[offset] = newVal; if(fClients[offset].func) (fClients[offset].func)(fClients[offset].refcon, nodeID, (offset-1) & 31, oldVal, OSSwapBigToHostInt32(newVal)); // Notify target space object of plug value modification if ((fAVCTargetSpace) && (offset > 0) && (offset < 32)) fAVCTargetSpace->pcrModified(IOFWAVCPlugIsochOutputType,(offset-1),OSSwapBigToHostInt32(newVal)); else if ((fAVCTargetSpace) && (offset > 32) && (offset < 64)) fAVCTargetSpace->pcrModified(IOFWAVCPlugIsochInputType,(offset-33),OSSwapBigToHostInt32(newVal)); return kFWResponseComplete; }
static void preload(const char *file) { ScopedMMap buf(file); char *base = buf; if (!base) return; // An OSX binary might either be a fat (universal) binary or a // Mach-O binary. A fat binary actually embeds several Mach-O // binaries. If we have a fat binary, find the offset where the // Mach-O binary for our CPU type can be found. struct fat_header *fh = (struct fat_header *)base; if (OSSwapBigToHostInt32(fh->magic) == FAT_MAGIC) { uint32_t nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); struct fat_arch *arch = (struct fat_arch *)&buf[sizeof(struct fat_header)]; for (; nfat_arch; arch++, nfat_arch--) { if (OSSwapBigToHostInt32(arch->cputype) == CPU_TYPE) { base += OSSwapBigToHostInt32(arch->offset); break; } } if (base == buf) return; } // Check Mach-O magic in the Mach header struct cpu_mach_header *mh = (struct cpu_mach_header *)base; if (mh->magic != MH_MAGIC) return; // The Mach header is followed by a sequence of load commands. // Each command has a header containing the command type and the // command size. LD_SEGMENT commands describes how the dynamic // loader is going to map the file in memory. We use that // information to find the biggest offset from the library that // will be mapped in memory. char *cmd = &base[sizeof(struct cpu_mach_header)]; off_t end = 0; for (uint32_t ncmds = mh->ncmds; ncmds; ncmds--) { struct segment_command *sh = (struct segment_command *)cmd; if (sh->cmd != LC_SEGMENT) continue; if (end < sh->fileoff + sh->filesize) end = sh->fileoff + sh->filesize; cmd += sh->cmdsize; } // Let the kernel read ahead what the dynamic loader is going to // map in memory soon after. The F_RDADVISE fcntl is equivalent // to Linux' readahead() system call. if (end > 0) { struct radvisory ra; ra.ra_offset = (base - buf); ra.ra_count = end; fcntl(buf.getFd(), F_RDADVISE, &ra); } }
long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { long ret; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; u_int32_t uncompressed_size, size; void *buffer; #if 0 printf("kernel header:\n"); printf("signature: 0x%x\n", kernel_header->signature); printf("compress_type: 0x%x\n", kernel_header->compress_type); printf("adler32: 0x%x\n", kernel_header->adler32); printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size); printf("compressed_size: 0x%x\n", kernel_header->compressed_size); getc(); #endif if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) { error("kernel compression is bad\n"); return -1; } #if NOTDEF if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name)) return -1; if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path)) return -1; #endif uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size); binary = buffer = malloc(uncompressed_size); size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); if (uncompressed_size != size) { error("size mismatch from lzss: %x\n", size); return -1; } if (OSSwapBigToHostInt32(kernel_header->adler32) != Alder32(binary, uncompressed_size)) { printf("adler mismatch\n"); return -1; } } ThinFatFile(&binary, 0); ret = DecodeMachO(binary, rentry, raddr, rsize); return ret; }
bool IOConfigDirectory::initWithOffset(int start, int type) { IOReturn status = kIOReturnSuccess; const UInt32 *data; if( !OSObject::init() ) { status = kIOReturnError; } if( status == kIOReturnSuccess ) { fStart = start; fType = type; status = updateROMCache( start, 1 ); } if( status == kIOReturnSuccess ) { data = lockData(); fNumEntries = (OSSwapBigToHostInt32(data[start]) & kConfigLeafDirLength) >> kConfigLeafDirLengthPhase; unlockData(); if( fNumEntries > 256 ) // 1k request { status = kIOReturnNoMemory; } }
static int __fat_iterator_init( struct __fat_iterator * iter, const void * file_data, const void * file_end, int macho_only) { int result = -1; size_t length = file_end - file_data; uint32_t magic; if (length < sizeof(magic)) { goto finish; } iter->file_start = (void *)file_data; iter->file_end = (void *)file_end; magic = MAGIC32(file_data); if (ISFAT(magic)) { void * arches_end; if (length < sizeof(struct fat_header)) { goto finish; } iter->fat_header = (struct fat_header *)file_data; iter->fat_arches = (struct fat_arch *)((char *)iter->fat_header + sizeof(struct fat_header)); iter->num_arches = OSSwapBigToHostInt32( iter->fat_header->nfat_arch); arches_end = (void *)iter->fat_arches + (iter->num_arches * sizeof(struct fat_arch)); if (arches_end > iter->file_end) { goto finish; } iter->iterable = 1; } else if (ISMACHO(magic)) { if (length < sizeof(struct mach_header)) { goto finish; } iter->iterable = 1; iter->num_arches = 1; iter->arch_index = 0; } else if (macho_only) { goto finish; } result = 0; finish: return result; }
void IODCLTranslator::TalkingDCLPingPongProc(DCLCommand* pDCLCommand) { IODCLTranslator * me; DCLCommand* pCurrentDCLCommand; DCLTransferPacket* pDCLTransferPacket; UInt8 * packetBuffer; UInt32 packetHeader; UInt32 packetSize; UInt32 packetNum; bool getNextPacket; me = (IODCLTranslator *)((DCLCallProc*)pDCLCommand)->procData; pCurrentDCLCommand = me->fCurrentDCLCommand; pDCLTransferPacket = &me->fTransfers[me->fPingCount * kNumPacketsPerPingPong]; // Run all packets through DCL program. for (packetNum = 0; ((packetNum < kNumPacketsPerPingPong) && (pCurrentDCLCommand != NULL)); packetNum++) { // Compute packet size. packetBuffer = (UInt8 *)pDCLTransferPacket->buffer; packetSize = sizeof (UInt32); // Run this packet through DCL program. getNextPacket = false; while ((!getNextPacket) && (pCurrentDCLCommand != NULL)) { RunTalkingDCLEngine (&(me->fPacketHeader), &pCurrentDCLCommand, &packetBuffer, &packetSize, &getNextPacket); } // Update packet header. packetSize -= 4;//zzz not the best way packetHeader = (packetSize << kFWIsochDataLengthPhase) | (OSSwapBigToHostInt32(me->fPacketHeader) & ~(kFWIsochDataLength)); *((UInt32 *) packetBuffer) = OSSwapHostToBigInt32(packetHeader); // Update send packet DCL. packetSize += 4;//zzz really, not the best way // Change the transfer packet command. pDCLTransferPacket->size = packetSize; // Send notification to DCL compiler. me->fHWProgram->notify(kFWDCLModifyNotification, (DCLCommand**) pDCLTransferPacket, 1); // Update for next packet. pDCLTransferPacket++; } // Update DCL translation data. me->fCurrentDCLCommand = pCurrentDCLCommand; me->fPingCount++; if(me->fPingCount > kNumPingPongs) me->fPingCount = 0; }
void * fat_iterator_next_arch( fat_iterator iter, void ** file_end) { void * result = NULL; if (!iter->fat_header) { if (iter->arch_index == 0) { result = iter->file_start; if (file_end) { *file_end = iter->file_end; } iter->arch_index++; } } else { if (iter->arch_index < iter->num_arches) { struct fat_arch * arch_start; void * arch_end; arch_start = (struct fat_arch *)((void *)iter->fat_arches + (iter->arch_index * sizeof(struct fat_arch))); result = ((void *)iter->file_start + OSSwapBigToHostInt32(arch_start->offset)); arch_end = (void *)result + OSSwapBigToHostInt32(arch_start->size); if (arch_end > iter->file_end) { result = NULL; iter->arch_index = iter->num_arches; goto finish; } if (file_end) { *file_end = arch_end; } iter->arch_index++; } } finish: return result; }
UInt32 IOFireWirePCRSpace::readPlug(UInt32 plug) { //IOLog( "IOFireWirePCRSpace::readPlug (0x%08X)\n",(int) this); UInt32 val; fControl->closeGate(); val = OSSwapBigToHostInt32(fBuf[plug]); fControl->openGate(); return val; }
static ObjectFile::Reader* createReader(const char* path, const ObjectFile::ReaderOptions& options) { struct stat stat_buf; int fd = ::open(path, O_RDONLY, 0); if ( fd == -1 ) throwf("cannot open file: %s", path); ::fstat(fd, &stat_buf); uint8_t* p = (uint8_t*)::mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); ::close(fd); const mach_header* mh = (mach_header*)p; if ( mh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { const struct fat_header* fh = (struct fat_header*)p; const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header)); for (unsigned long i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) { if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)sPreferredArch ) { if ( ((uint32_t)sPreferredSubArch == 0xFFFFFFFF) || ((uint32_t)sPreferredSubArch == OSSwapBigToHostInt32(archs[i].cpusubtype)) ) { p = p + OSSwapBigToHostInt32(archs[i].offset); mh = (struct mach_header*)p; break; } } } } if ( mach_o::relocatable::Reader<x86>::validFile(p) ) return new mach_o::relocatable::Reader<x86>::Reader(p, path, 0, options, 0); else if ( mach_o::relocatable::Reader<ppc>::validFile(p) ) return new mach_o::relocatable::Reader<ppc>::Reader(p, path, 0, options, 0); else if ( mach_o::relocatable::Reader<ppc64>::validFile(p) ) return new mach_o::relocatable::Reader<ppc64>::Reader(p, path, 0, options, 0); else if ( mach_o::relocatable::Reader<x86_64>::validFile(p) ) return new mach_o::relocatable::Reader<x86_64>::Reader(p, path, 0, options, 0); else if ( mach_o::relocatable::Reader<arm>::validFile(p) ) return new mach_o::relocatable::Reader<arm>::Reader(p, path, 0, options, 0); #if LTO_SUPPORT if ( lto::Reader::validFile(p, stat_buf.st_size, 0) ) { return new lto::Reader(p, stat_buf.st_size, path, 0, options, 0); } #endif throwf("not a mach-o object file: %s", path); }
/* * external representation, portable system endianity -> acl_t * * Unlike acl_copy_ext, we can't mung the buffer as it doesn't belong to us. */ acl_t acl_copy_int(const void *buf) { struct kauth_filesec *ext = (struct kauth_filesec *)buf; acl_t ap; int i; if (ext->fsec_magic != OSSwapHostToBigInt32(KAUTH_FILESEC_MAGIC)) { errno = EINVAL; return(NULL); } if ((ap = acl_init(OSSwapBigToHostInt32(ext->fsec_entrycount))) != NULL) { /* copy useful header fields */ ap->a_flags = OSSwapBigToHostInt32(ext->fsec_flags); ap->a_entries = OSSwapBigToHostInt32(ext->fsec_entrycount); /* copy ACEs */ for (i = 0; i < ap->a_entries; i++) { /* ACE contents are literally identical */ ap->a_ace[i].ae_magic = _ACL_ENTRY_MAGIC; ap->a_ace[i].ae_applicable = ext->fsec_ace[i].ace_applicable; ap->a_ace[i].ae_flags = OSSwapBigToHostInt32(ext->fsec_ace[i].ace_flags) & ~KAUTH_ACE_KINDMASK; ap->a_ace[i].ae_tag = OSSwapBigToHostInt32(ext->fsec_ace[i].ace_flags) & KAUTH_ACE_KINDMASK; ap->a_ace[i].ae_perms = OSSwapBigToHostInt32(ext->fsec_ace[i].ace_rights); } } return(ap); }
void IODCLTranslator::ListeningDCLPingPongProc(DCLCommand* pDCLCommand) { IODCLTranslator * me; DCLCommand* pCurrentDCLCommand; DCLTransferPacket* pDCLTransferPacket; UInt8 * packetBuffer; UInt32 packetHeader; UInt32 packetSize; UInt32 packetNum; bool getNextPacket; me = (IODCLTranslator *)((DCLCallProc*)pDCLCommand)->procData; pCurrentDCLCommand = me->fCurrentDCLCommand; pDCLTransferPacket = &me->fTransfers[me->fPingCount * kNumPacketsPerPingPong]; // Run all packets through DCL program. for (packetNum = 0; ((packetNum < kNumPacketsPerPingPong) && (pCurrentDCLCommand != NULL)); packetNum++) { // Compute packet size. packetBuffer = (UInt8 *)pDCLTransferPacket->buffer; packetHeader = *((UInt32 *) packetBuffer); packetBuffer += sizeof (UInt32); packetSize = (OSSwapBigToHostInt32(packetHeader) & kFWIsochDataLength) >> kFWIsochDataLengthPhase; // Run this packet through DCL program. getNextPacket = false; while ((!getNextPacket) && (pCurrentDCLCommand != NULL)) { RunListeningDCLEngine ( &pCurrentDCLCommand, packetHeader, &packetBuffer, &packetSize, &getNextPacket); } // Update for next packet. pDCLTransferPacket++; } // Update DCL translation data. me->fCurrentDCLCommand = pCurrentDCLCommand; me->fPingCount++; if(me->fPingCount > kNumPingPongs) me->fPingCount = 0; }
int findIndex(const UInt32* base, int size, int key, UInt32 type) { int i; UInt32 mask, test; test = (UInt32)key << kConfigEntryKeyValuePhase; mask = kConfigEntryKeyValue; if(type != kInvalidConfigROMEntryType) { test |= type << kConfigEntryKeyTypePhase; mask |= kConfigEntryKeyType; } // OR test into mask, in case key was more than just the key value mask |= test; for(i=0; i<size; i++) { if( (OSSwapBigToHostInt32(base[i]) & mask) == test ) break; } if(i >= size) i = -1; return i; }
void IOFireWirePCRSpace::clearAllP2PConnections(void) { int i; UInt32 oldVal; //IOLog( "IOFireWirePCRSpace::clearAllP2PConnections (0x%08X)\n",(int) this); // Handle oPCRs for(i=0; i<32; i++) { fControl->closeGate(); oldVal = OSSwapBigToHostInt32(fBuf[i+1]); if ((oldVal & 0x3F000000) != 0) { fBuf[i+1] &= OSSwapHostToBigInt32(0xC0FFFFFF); // Clear P2P field // If this plug has a client, notify it if(fClients[i+1].func) (fClients[i+1].func)(fClients[i+1].refcon, 0xFFFF, i, oldVal, OSSwapBigToHostInt32(fBuf[i+1])); // Notify the AVC Target Space Object of the change if (fAVCTargetSpace) fAVCTargetSpace->pcrModified(IOFWAVCPlugIsochOutputType,i,OSSwapBigToHostInt32(fBuf[i+1])); } fControl->openGate(); } // Handle iPCRs for(i=0; i<32; i++) { fControl->closeGate(); oldVal = OSSwapBigToHostInt32(fBuf[i+33]); if ((oldVal & 0x3F000000) != 0) { fBuf[i+33] &= OSSwapHostToBigInt32(0xC0FFFFFF); // Clear P2P field // If this plug has a client, notify it if(fClients[i+33].func) (fClients[i+33].func)(fClients[i+33].refcon, 0xFFFF, i, oldVal, OSSwapBigToHostInt32(fBuf[i+33])); // Notify the AVC Target Space Object of the change if (fAVCTargetSpace) fAVCTargetSpace->pcrModified(IOFWAVCPlugIsochInputType,i,OSSwapBigToHostInt32(fBuf[i+33])); } fControl->openGate(); } return; }
void IOFireWireIRM::allocateBroadcastChannel( void ) { IOReturn status = kIOReturnSuccess; FWLOCALKLOG(( "IOFireWireIRM::allocateBroadcastChannel() - attempting to allocate broadcast channel\n" )); FWAddress address( kCSRRegisterSpaceBaseAddressHi, kCSRChannelsAvailable31_0 ); address.nodeID = fIRMNodeID; UInt32 host_channels_available = OSSwapBigToHostInt32( fOldChannelsAvailable31_0 ); host_channels_available &= ~kChannel31Mask; fNewChannelsAvailable31_0 = OSSwapHostToBigInt32( host_channels_available ); fLockCmd->reinit( fGeneration, address, &fOldChannelsAvailable31_0, &fNewChannelsAvailable31_0, 1, IOFireWireIRM::lockCompleteStatic, this ); // the standard async commands call complete with an error before // returning an error from submit. fLockCmdInUse = true; status = fLockCmd->submit(); }
IOReturn IOFireWirePCRSpace::updatePlug(UInt32 plug, UInt32 oldVal, UInt32 newVal) { //IOLog( "IOFireWirePCRSpace::updatePlug (0x%08X)\n",(int) this); IOReturn res; fControl->closeGate(); if(oldVal == OSSwapBigToHostInt32(fBuf[plug])) { fBuf[plug] = OSSwapHostToBigInt32(newVal); res = kIOReturnSuccess; // Notify target space object of plug value modification if ((fAVCTargetSpace) && (plug > 0) && (plug < 32)) fAVCTargetSpace->pcrModified(IOFWAVCPlugIsochOutputType,(plug-1),newVal); else if ((fAVCTargetSpace) && (plug > 32) && (plug < 64)) fAVCTargetSpace->pcrModified(IOFWAVCPlugIsochInputType,(plug-33),newVal); } else res = kIOReturnCannotLock; fControl->openGate(); return res; }
long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { long ret; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; u_int32_t uncompressed_size, size; void *buffer; unsigned long len; #if 0 printf("kernel header:\n"); printf("signature: 0x%x\n", kernel_header->signature); printf("compress_type: 0x%x\n", kernel_header->compress_type); printf("adler32: 0x%x\n", kernel_header->adler32); printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size); printf("compressed_size: 0x%x\n", kernel_header->compressed_size); getchar(); #endif if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) { error("kernel compression is bad\n"); return -1; } #if NOTDEF if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name)) return -1; if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path)) return -1; #endif uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size); binary = buffer = malloc(uncompressed_size); size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); if (uncompressed_size != size) { error("size mismatch from lzss: %x\n", size); return -1; } if (OSSwapBigToHostInt32(kernel_header->adler32) != Adler32(binary, uncompressed_size)) { printf("adler mismatch\n"); return -1; } } ret = ThinFatFile(&binary, &len); if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64) { archCpuType=CPU_TYPE_I386; ret = ThinFatFile(&binary, &len); } // Notify modules that the kernel has been decompressed, thinned and is about to be decoded execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL); ret = DecodeMachO(binary, rentry, raddr, rsize); if (ret<0 && archCpuType==CPU_TYPE_X86_64) { archCpuType=CPU_TYPE_I386; ret = DecodeMachO(binary, rentry, raddr, rsize); } return ret; }
/* Accept a new piece of media, doing whatever's necessary to make it * show up properly to the system. */ IOReturn IODVDBlockStorageDriver::acceptNewMedia(void) { IOReturn result; if (getMediaType() < kDVDMediaTypeMin || getMediaType() > kDVDMediaTypeMax) { return super::acceptNewMedia(); } /* Obtain disc status: */ switch (getMediaType()) { case kDVDMediaTypeR: case kDVDMediaTypeRW: { bool checkIsWritable = false; DVDDiscInfo discInfo; DVDRZoneInfo rzoneInfo; result = reportDiscInfo(&discInfo); if (result != kIOReturnSuccess) { break; } switch (discInfo.discStatus) { case 0x01: /* is disc incomplete? */ checkIsWritable = true; break; case 0x02: /* is disc complete? */ checkIsWritable = discInfo.erasable ? true : false; break; } /* Obtain rzone status: */ if (checkIsWritable) { UInt16 rzoneLast = (discInfo.lastRZoneNumberInLastBorderMSB << 8) | discInfo.lastRZoneNumberInLastBorderLSB; result = reportRZoneInfo(rzoneLast,&rzoneInfo); if (result != kIOReturnSuccess) { break; } if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ _maxBlockNumber = max( _maxBlockNumber, max( OSSwapBigToHostInt32(rzoneInfo.rzoneStartAddress) + OSSwapBigToHostInt32(rzoneInfo.rzoneSize), 1 ) - 1 ); } if (rzoneInfo.incremental) { /* is rzone incremental? */ _writeProtected = false; break; } if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ if (rzoneInfo.blank) { /* is rzone invisible? */ UInt16 rzoneFirst = (discInfo.firstRZoneNumberInLastBorderMSB << 8) | discInfo.firstRZoneNumberInLastBorderLSB; if (rzoneFirst < rzoneLast) { result = reportRZoneInfo(rzoneLast - 1,&rzoneInfo); if (result != kIOReturnSuccess) { break; } if (rzoneInfo.incremental) { /* is rzone incremental? */ _writeProtected = false; break; } } } } } break; } case kDVDMediaTypePlusR: case kDVDMediaTypeHDR: { DVDDiscInfo discInfo; DVDRZoneInfo rzoneInfo; IOReturn result; result = reportDiscInfo(&discInfo); if (result != kIOReturnSuccess) { break; } /* Obtain rzone status: */ if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ UInt16 rzoneLast = (discInfo.lastRZoneNumberInLastBorderMSB << 8) | discInfo.lastRZoneNumberInLastBorderLSB; _writeProtected = false; result = reportRZoneInfo(rzoneLast,&rzoneInfo); if (result != kIOReturnSuccess) { break; } _maxBlockNumber = max( _maxBlockNumber, max( OSSwapBigToHostInt32(rzoneInfo.rzoneStartAddress) + OSSwapBigToHostInt32(rzoneInfo.rzoneSize), 1 ) - 1 ); } break; } } return IOBlockStorageDriver::acceptNewMedia(); }
UniversalMachOLayout::UniversalMachOLayout(const char* path, const std::set<ArchPair>* onlyArchs) : fPath(strdup(path)) { // map in whole file int fd = ::open(path, O_RDONLY, 0); if ( fd == -1 ) { int err = errno; if ( err == ENOENT ) throwf("file not found"); else throwf("can't open file, errno=%d", err); } struct stat stat_buf; if ( fstat(fd, &stat_buf) == -1) throwf("can't stat open file %s, errno=%d", path, errno); if ( stat_buf.st_size < 20 ) throwf("file too small %s", path); uint8_t* p = (uint8_t*)::mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); if ( p == (uint8_t*)(-1) ) throwf("can't map file %s, errno=%d", path, errno); ::close(fd); try { // if fat file, process each architecture const fat_header* fh = (fat_header*)p; const mach_header* mh = (mach_header*)p; if ( fh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { // Fat header is always big-endian const struct fat_arch* slices = (struct fat_arch*)(p + sizeof(struct fat_header)); const uint32_t sliceCount = OSSwapBigToHostInt32(fh->nfat_arch); for (uint32_t i=0; i < sliceCount; ++i) { if ( requestedSlice(onlyArchs, OSSwapBigToHostInt32(slices[i].cputype), OSSwapBigToHostInt32(slices[i].cpusubtype)) ) { uint32_t fileOffset = OSSwapBigToHostInt32(slices[i].offset); if ( fileOffset > stat_buf.st_size ) { throwf("malformed universal file, slice %u for architecture 0x%08X is beyond end of file: %s", i, OSSwapBigToHostInt32(slices[i].cputype), path); } if ( (fileOffset+OSSwapBigToHostInt32(slices[i].size)) > stat_buf.st_size ) { throwf("malformed universal file, slice %u for architecture 0x%08X is beyond end of file: %s", i, OSSwapBigToHostInt32(slices[i].cputype), path); } try { switch ( OSSwapBigToHostInt32(slices[i].cputype) ) { case CPU_TYPE_I386: fLayouts.push_back(new MachOLayout<x86>(&p[fileOffset], fileOffset, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); break; case CPU_TYPE_X86_64: fLayouts.push_back(new MachOLayout<x86_64>(&p[fileOffset], fileOffset, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); break; case CPU_TYPE_ARM: fLayouts.push_back(new MachOLayout<arm>(&p[fileOffset], fileOffset, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); break; default: throw "unknown slice in fat file"; } } catch (const char* msg) { fprintf(stderr, "warning: %s for %s\n", msg, path); } } } } else { try { if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_I386)) { if ( requestedSlice(onlyArchs, OSSwapLittleToHostInt32(mh->cputype), OSSwapLittleToHostInt32(mh->cpusubtype)) ) fLayouts.push_back(new MachOLayout<x86>(mh, 0, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); } else if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC_64) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_X86_64)) { if ( requestedSlice(onlyArchs, OSSwapLittleToHostInt32(mh->cputype), OSSwapLittleToHostInt32(mh->cpusubtype)) ) fLayouts.push_back(new MachOLayout<x86_64>(mh, 0, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); } else if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_ARM)) { if ( requestedSlice(onlyArchs, OSSwapLittleToHostInt32(mh->cputype), OSSwapLittleToHostInt32(mh->cpusubtype)) ) fLayouts.push_back(new MachOLayout<arm>(mh, 0, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); } else { throw "unknown file format"; } } catch (const char* msg) { fprintf(stderr, "warning: %s for %s\n", msg, path); } } } catch (...) { ::munmap(p, stat_buf.st_size); throw; } }
MODULE_SCOPE int TclpLoadMemory( Tcl_Interp *interp, /* Used for error reporting. */ void *buffer, /* Buffer containing the desired code * (allocated with TclpLoadMemoryGetBuffer). */ int size, /* Allocation size of buffer. */ int codeSize, /* Size of code data read into buffer or -1 if * an error occurred and the buffer should * just be freed. */ Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded * file which will be passed back to * (*unloadProcPtr)() to unload the file. */ Tcl_FSUnloadFileProc **unloadProcPtr) /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ { Tcl_DyldLoadHandle *dyldLoadHandle; NSObjectFileImage dyldObjFileImage = NULL; Tcl_DyldModuleHandle *modulePtr; NSModule module; const char *objFileImageErrMsg = NULL; /* * Try to create an object file image that we can load from. */ if (codeSize >= 0) { NSObjectFileImageReturnCode err = NSObjectFileImageSuccess; const struct fat_header *fh = buffer; uint32_t ms = 0; #ifndef __LP64__ const struct mach_header *mh = NULL; #define mh_size sizeof(struct mach_header) #define mh_magic MH_MAGIC #define arch_abi 0 #else const struct mach_header_64 *mh = NULL; #define mh_size sizeof(struct mach_header_64) #define mh_magic MH_MAGIC_64 #define arch_abi CPU_ARCH_ABI64 #endif if ((size_t) codeSize >= sizeof(struct fat_header) && fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) { uint32_t fh_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); /* * Fat binary, try to find mach_header for our architecture */ TclLoadDbgMsg("Fat binary, %d archs", fh_nfat_arch); if ((size_t) codeSize >= sizeof(struct fat_header) + fh_nfat_arch * sizeof(struct fat_arch)) { void *fatarchs = (char*)buffer + sizeof(struct fat_header); const NXArchInfo *arch = NXGetLocalArchInfo(); struct fat_arch *fa; if (fh->magic != FAT_MAGIC) { swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder); } fa = NXFindBestFatArch(arch->cputype | arch_abi, arch->cpusubtype, fatarchs, fh_nfat_arch); if (fa) { TclLoadDbgMsg("NXFindBestFatArch() successful: " "local cputype %d subtype %d, " "fat cputype %d subtype %d", arch->cputype | arch_abi, arch->cpusubtype, fa->cputype, fa->cpusubtype); mh = (void*)((char*)buffer + fa->offset); ms = fa->size; } else { TclLoadDbgMsg("NXFindBestFatArch() failed"); err = NSObjectFileImageInappropriateFile; } if (fh->magic != FAT_MAGIC) { swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder); } } else { TclLoadDbgMsg("Fat binary header failure"); err = NSObjectFileImageInappropriateFile; } } else { /* * Thin binary */ TclLoadDbgMsg("Thin binary"); mh = buffer; ms = codeSize; } if (ms && !(ms >= mh_size && mh->magic == mh_magic && mh->filetype == MH_BUNDLE)) { TclLoadDbgMsg("Inappropriate file: magic %x filetype %d", mh->magic, mh->filetype); err = NSObjectFileImageInappropriateFile; } if (err == NSObjectFileImageSuccess) { err = NSCreateObjectFileImageFromMemory(buffer, codeSize, &dyldObjFileImage); if (err == NSObjectFileImageSuccess) { TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() " "successful"); } else { objFileImageErrMsg = DyldOFIErrorMsg(err); TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() failed: %s", objFileImageErrMsg); } } else { objFileImageErrMsg = DyldOFIErrorMsg(err); } } /* * If it went wrong (or we were asked to just deallocate), get rid of the * memory block and create an error message. */ if (dyldObjFileImage == NULL) { vm_deallocate(mach_task_self(), (vm_address_t) buffer, size); if (objFileImageErrMsg != NULL) { Tcl_AppendResult(interp, "NSCreateObjectFileImageFromMemory() " "error: ", objFileImageErrMsg, NULL); } return TCL_ERROR; } /* * Extract the module we want from the image of the object file. */ module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(dyldObjFileImage); if (module) { TclLoadDbgMsg("NSLinkModule() successful"); } else { NSLinkEditErrors editError; int errorNumber; const char *errorName, *errMsg; NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg); Tcl_AppendResult(interp, errMsg, NULL); return TCL_ERROR; } /* * Stash the module reference within the load handle we create and return. */ modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; modulePtr->nextPtr = NULL; dyldLoadHandle = (Tcl_DyldLoadHandle *) ckalloc(sizeof(Tcl_DyldLoadHandle)); #if TCL_DYLD_USE_DLFCN dyldLoadHandle->dlHandle = NULL; #endif dyldLoadHandle->dyldLibHeader = NULL; dyldLoadHandle->modulePtr = modulePtr; *loadHandle = (Tcl_LoadHandle) dyldLoadHandle; *unloadProcPtr = &TclpUnloadFile; return TCL_OK; }
int main(int argc, char *argv[]) { printf("\n" "\n\t" " _/_/_/ _/ \n\t" " _/ _/_/ _/_/_/ _/_/ Copyright \n\t" " _/ _/ _/ _/ _/ _/_/_/_/ © 2014 \n\t" "_/ _/ _/ _/ _/ _/ Zhi-Wei Cai \n\t" " _/_/_/ _/_/ _/_/_/ _/_/_/ v %s \n\t" " _/ _/ _/ \n\t" " _/ _/ _/_/_/ _/_/_/ _/_/_/ _/_/_/ \n\t" " _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/ \n\t" "_/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/ \n\t" " _/_/ _/ _/ _/_/_/ _/ _/_/_/ _/ _/ \n\t" " _/ \n\t" " - http://vox.vg/ - _/_/ \n\n\n", VERSION); if (argc < 2) { printf("usage: codeunsign target_file\n"); return 0; } char *addr = NULL; int fd = open(argv[1], O_RDWR); size_t size; struct stat stat_buf; struct fat_arch *fa; struct fat_header *fh; struct mach_header *mh; struct mach_header_64 *mh64; struct load_command *lc; uint32_t mm; uint32_t err; fstat(fd, &stat_buf); size = stat_buf.st_size; addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); mm = *(uint32_t *)(addr); printf("* MH_MAGIC: %04X\n", mm); switch(mm) { case MH_MAGIC: mh = (struct mach_header *)addr; addr += sizeof(struct mach_header); printf("* Architecture: i386\n"); printf("* Load Commands: %d\n", mh->ncmds); err = 2; for (int i=0; i<mh->ncmds; i++) { lc = (struct load_command *)addr; if (lc->cmd == LC_CODE_SIGNATURE) { // LC_CODE_SIGNATURE found printf("* Patching...\n"); err = 0; mh->ncmds -= 1; mh->sizeofcmds -= lc->cmdsize; lc->cmd = 0; lc->cmdsize = 0; } // Next load command addr += lc->cmdsize; } msync(addr, size, MS_ASYNC); break; case MH_MAGIC_64: mh64 = (struct mach_header_64 *)addr; addr += sizeof(struct mach_header_64); printf("* Architecture: x86_64\n"); printf("* Load Commands: %d\n", mh64->ncmds); err = 2; for (int i = 0; i < mh64->ncmds; i++) { lc = (struct load_command *)addr; if (lc->cmd == LC_CODE_SIGNATURE) { printf("* Patching...\n"); err = 0; mh64->ncmds -= 1; mh64->sizeofcmds -= lc->cmdsize; lc->cmd = 0; lc->cmdsize = 0; } addr += lc->cmdsize; } msync(addr, size, MS_ASYNC); break; case FAT_CIGAM: fh = (struct fat_header *)addr; uint32_t i = 0; uint32_t nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); // In fat_arch struct the attributes are stored in big-endian. printf("* Mach-O Type: Fat\n"); printf("* Architectures: %x\n", nfat_arch); fa = (struct fat_arch *)(addr + sizeof(struct fat_header)); for(;nfat_arch-- > 0; fa++) { uint32_t offset, cputype; cputype = OSSwapBigToHostInt32(fa->cputype); offset = OSSwapBigToHostInt32(fa->offset); char *addrTemp = NULL; switch(cputype) { case 0x7: // 32bit addrTemp = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); mh = (struct mach_header *)(addrTemp + offset); addrTemp += sizeof(struct mach_header) + offset; printf("* MH_MAGIC: %04X\n\t", mh->magic); printf("* Load Commands: %d\n\t", mh->ncmds); err = 3; for (int i = 0; i < mh->ncmds; i++) { lc = (struct load_command *)addrTemp; if (lc->cmd == LC_CODE_SIGNATURE) { printf("* Patching...\n"); err = 0; mh->ncmds -= 1; mh->sizeofcmds -= lc->cmdsize; lc->cmd = 0; lc->cmdsize = 0; } addrTemp += lc->cmdsize; } break; case 0x1000007: // 64bit addrTemp = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); mh64 = (struct mach_header_64 *)(addrTemp + offset); addrTemp += sizeof(struct mach_header_64) + offset; printf("* MH_MAGIC_64: %04X\n\t", mh64->magic); printf("* Load Commands: %d\n\t", mh64->ncmds); err = 3; for (int i = 0; i < mh64->ncmds; i++) { lc = (struct load_command *)addrTemp; if (lc->cmd == LC_CODE_SIGNATURE) { printf("* Patching...\n"); err = 0; mh64->ncmds -= 1; mh64->sizeofcmds -= lc->cmdsize; lc->cmd = 0; lc->cmdsize = 0; } addrTemp += lc->cmdsize; } break; } if(err) printf("[ERROR] LC_CODE_SIGNATURE NOT FOUND.\n"); msync(addrTemp, size, MS_ASYNC); munmap(addrTemp, size); } break; default: printf("[ERROR] INVALID MACH-O BINARY.\n"); err = 1; } printf("\n"); switch(err) { case 1: printf("[ERROR] ABORT.\n"); break; case 2: printf("[ERROR] LC_CODE_SIGNATURE NOT FOUND.\n"); break; } munmap(addr, size); close(fd); printf("\n* All done. :)\n\n"); return 0; }
uint32_t fmbe32(uint32_t x) { return OSSwapBigToHostInt32(x); }
static void check(const char* path) { struct stat stat_buf; try { int fd = ::open(path, O_RDONLY, 0); if ( fd == -1 ) throw "cannot open file"; ::fstat(fd, &stat_buf); uint32_t length = stat_buf.st_size; uint8_t* p = (uint8_t*)::mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); if ( p == ((uint8_t*)(-1)) ) throw "cannot map file"; ::close(fd); const mach_header* mh = (mach_header*)p; if ( mh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { const struct fat_header* fh = (struct fat_header*)p; const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header)); for (unsigned long i=0; i < fh->nfat_arch; ++i) { if ( archs[i].cputype == CPU_TYPE_POWERPC ) { if ( MachOChecker<ppc>::validFile(p + archs[i].offset) ) MachOChecker<ppc>::make(p + archs[i].offset, archs[i].size, path); else throw "in universal file, ppc slice does not contain ppc mach-o"; } else if ( archs[i].cputype == CPU_TYPE_I386 ) { if ( MachOChecker<x86>::validFile(p + archs[i].offset) ) MachOChecker<x86>::make(p + archs[i].offset, archs[i].size, path); else throw "in universal file, i386 slice does not contain i386 mach-o"; } else if ( archs[i].cputype == CPU_TYPE_POWERPC64 ) { if ( MachOChecker<ppc64>::validFile(p + archs[i].offset) ) MachOChecker<ppc64>::make(p + archs[i].offset, archs[i].size, path); else throw "in universal file, ppc64 slice does not contain ppc64 mach-o"; } else if ( archs[i].cputype == CPU_TYPE_X86_64 ) { if ( MachOChecker<x86_64>::validFile(p + archs[i].offset) ) MachOChecker<x86_64>::make(p + archs[i].offset, archs[i].size, path); else throw "in universal file, x86_64 slice does not contain x86_64 mach-o"; } else { throw "in universal file, unknown architecture slice"; } } } else if ( MachOChecker<x86>::validFile(p) ) { MachOChecker<x86>::make(p, length, path); } else if ( MachOChecker<ppc>::validFile(p) ) { MachOChecker<ppc>::make(p, length, path); } else if ( MachOChecker<ppc64>::validFile(p) ) { MachOChecker<ppc64>::make(p, length, path); } else if ( MachOChecker<x86_64>::validFile(p) ) { MachOChecker<x86_64>::make(p, length, path); } else { throw "not a known file type"; } } catch (const char* msg) { throwf("%s in %s", msg, path); } }
long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { long ret = 0; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; u_int32_t uncompressed_size = 0, size = 0, adler32 = 0; void *buffer = NULL; unsigned long len = 0; /*#if 0 printf("kernel header:\n"); printf("signature: 0x%x\n", kernel_header->signature); printf("compress_type: 0x%x\n", kernel_header->compress_type); printf("adler32: 0x%x\n", kernel_header->adler32); printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size); printf("compressed_size: 0x%x\n", kernel_header->compressed_size); getchar(); #endif*/ if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { DBG("Decompressing Kernel: "); if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) && (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn'))) { error("ERROR: kernel compression is bad!\n"); return -1; } #if NOTDEF if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name)) { return -1; } if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path)) { return -1; } #endif uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size); binary = buffer = malloc(uncompressed_size); // MinusZwei size = 0; switch (kernel_header->compress_type) { case OSSwapBigToHostConstInt32('lzvn'): size = decompress_lzvn( binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); break; case OSSwapBigToHostConstInt32('lzss'): size = decompress_lzss( (u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size)); break; default: break; } // MinusZwei if (uncompressed_size != size) { if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn')) { error("ERROR: size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size); } if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss')) { error("ERROR: size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size); } return -1; } adler32 = Adler32(binary, uncompressed_size); if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32) { error("ERROR: adler mismatch (found: %x, expected: %x).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32)); return -1; } DBG("OK.\n"); } ret = ThinFatFile(&binary, &len); if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64) { archCpuType=CPU_TYPE_I386; ret = ThinFatFile(&binary, &len); } // Bungo: no range checking, sorry size = 0; while (memcmp((uint8_t *)binary + size, (uint8_t *)gDarwinBuildVerStr, 21)) { size++; } gDarwinBuildVerStr = (char *)binary + size; // Notify modules that the kernel has been decompressed, thinned and is about to be decoded execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL); ret = DecodeMachO(binary, rentry, raddr, rsize); if (ret < 0 && archCpuType == CPU_TYPE_X86_64) { archCpuType = CPU_TYPE_I386; ret = DecodeMachO(binary, rentry, raddr, rsize); } return ret; }
long decodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize) { // return DecodeMachO(binary, rentry, raddr, rsize); void *buffer; long ret; unsigned long len; u_int32_t uncompressedSize, size; compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary; #if DEBUG_DRIVERS printf("Kernel header data.\n"); printf("===================\n"); printf("signature : 0x%08x\n", kernel_header->signature); printf("compressType : 0x%08x\n", kernel_header->compressType); printf("adler32 : 0x%08x\n", kernel_header->adler32); printf("uncompressedSize : 0x%08x\n", kernel_header->uncompressedSize); printf("compressedSize : 0x%08x\n", kernel_header->compressedSize); printf("platformName : %s\n", kernel_header->platformName); printf("rootPath : %s\n", kernel_header->rootPath); printf("Sleeping for 5 seconds...\n"); sleep(5); #endif if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) { if (kernel_header->compressType != OSSwapBigToHostConstInt32('lzss')) { error("kernel compression is bad\n"); return -1; } #if NOTDEF if (kernel_header->platformName[0] && strcmp(gPlatform.ModelID, kernel_header->platformName)) { return -1; } if (kernel_header->rootPath[0] && strcmp(gBootFile, kernel_header->rootPath)) { return -1; } #endif uncompressedSize = OSSwapBigToHostInt32(kernel_header->uncompressedSize); binary = buffer = malloc(uncompressedSize); size = decompressLZSS((u_int8_t *) binary, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressedSize)); if (uncompressedSize != size) { error("Size mismatch from lzss: 0x08%x\n", size); return -1; } if (OSSwapBigToHostInt32(kernel_header->adler32) != localAdler32(binary, uncompressedSize)) { printf("Adler mismatch\n"); return -1; } } ret = ThinFatFile(&binary, &len); if (ret == 0 && len == 0 && gArchCPUType == CPU_TYPE_X86_64) { gArchCPUType = CPU_TYPE_I386; ret = ThinFatFile(&binary, &len); } ret = DecodeMachO(binary, rentry, raddr, rsize); if (ret < 0 && gArchCPUType == CPU_TYPE_X86_64) { gArchCPUType = CPU_TYPE_I386; ret = DecodeMachO(binary, rentry, raddr, rsize); } return ret; }
int main(int argc, char *argv[]){ if(argc < 5){ usage(); exit(0); } PROT_TYPE prottype = 0; /* Determine prot type */ if (strcmp(argv[1], "init") == 0) prottype = PROT_INIT; else if (strcmp(argv[1], "max") == 0) prottype = PROT_MAX; else { fprintf(stderr, "Unrecognized prot type '%s'\n", argv[1]); exit(1); } /* Calculate prot */ vm_prot_t prot = 0; char *protstring = argv[4]; while(*protstring != '\0'){ switch(*protstring){ case 'r': prot |= VM_PROT_READ; break; case 'w': prot |= VM_PROT_WRITE; break; case 'x': prot |= VM_PROT_EXECUTE; break; default: usage(); exit(0); } protstring++; } /* Open file */ struct stat stat_buf; int fd = open(argv[2], O_RDWR, 0); if( fd == -1 ) perror("Cannot open file"), exit(1); if( fstat(fd, &stat_buf) != 0 ) perror("fstat failed"), exit(1); uint32_t length = stat_buf.st_size; uint8_t *p = (uint8_t*)mmap(NULL, stat_buf.st_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); if( p == ((uint8_t*)(-1)) ) perror("cannot map file"), exit(1); close(fd); /* Call proper methods */ const struct mach_header* mh = (struct mach_header*)p; /* Check if binary is thin/fat and 64/32 bit */ if ( mh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { const struct fat_header* fh = (struct fat_header*)p; const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header)); for (unsigned long i = 0; i < OSSwapBigToHostInt32(fh->nfat_arch); i++) { size_t offset = OSSwapBigToHostInt32(archs[i].offset); cpu_type_t cputype = OSSwapBigToHostInt32(archs[i].cputype); if(cputype & CPU_ARCH_ABI64) /* Slice is 64 bit */ mach_prot_64((struct mach_header_64*)(offset + (uint8_t*)mh), argv[3], prot, prottype); else /* Slice is 32 bit */ mach_prot((struct mach_header*)(offset + (uint8_t*)mh), argv[3], prot, prottype); } }else if( mh->magic == MH_MAGIC_64 ){ mach_prot_64((struct mach_header_64*)mh, argv[3], prot, prottype); }else if( mh->magic == MH_MAGIC ){ mach_prot((struct mach_header*)mh, argv[3], prot, prottype); }else{ fprintf(stderr, "Invalid file!\n"); exit(1); } return 0; }
static daddr_t sbmap(struct iob *io, daddr_t bn) { register struct inode *ip; int i, j, sh; daddr_t nb, *bap; ip = &io->i_ino; if (ip->i_icflags & IC_FASTLINK) { error("fast symlinks unimplemented\n"); return ((daddr_t)0); } if (bn < 0) { #if SYS_MESSAGES error("bn negative\n"); #endif return ((daddr_t)0); } /* * blocks 0..NDADDR are direct blocks */ if(bn < NDADDR) { nb = ip->i_db[bn]; return (nb); } /* * addresses NIADDR have single and double indirect blocks. * the first step is to determine how many levels of indirection. */ sh = 1; bn -= NDADDR; for (j = NIADDR; j > 0; j--) { sh *= NINDIR(io->i_fs); if (bn < sh) break; bn -= sh; } if (j == 0) { #if SYS_MESSAGES error("bn ovf %d\n", bn); #endif return ((daddr_t)0); } /* * fetch the first indirect block address from the inode */ nb = ip->i_ib[NIADDR - j]; if (nb == 0) { #if SYS_MESSAGES error("bn void %d\n",bn); #endif return ((daddr_t)0); } /* * fetch through the indirect blocks */ for (; j <= NIADDR; j++) { if (blknos[j] != nb) { io->i_bn = fsbtodb(io->i_fs, nb) + io->i_boff; if (b[j] == (char *)0) b[j] = malloc(MAXBSIZE); io->i_ma = b[j]; io->i_cc = io->i_fs->fs_bsize; if (devread(io) != io->i_fs->fs_bsize) { #if SYS_MESSAGES error("bn %d: read error\n", io->i_bn); #endif return ((daddr_t)0); } blknos[j] = nb; } bap = (daddr_t *)b[j]; sh /= NINDIR(io->i_fs); i = (bn / sh) % NINDIR(io->i_fs); #if BIG_ENDIAN_FS #if 1 // for now it is little endian FS for intel nb = bap[i]; #else nb = OSSwapBigToHostInt32(bap[i]); #endif 1 #else BIG_ENDIAN_FS nb = bap[i]; #endif BIG_ENDIAN_FS if(nb == 0) { #if SYS_MESSAGES error("bn void %d\n",bn); #endif return ((daddr_t)0); } } return (nb); }
IOReturn AppleFileSystemDriver::readHFSUUID(IOMedia *media, void **uuidPtr) { bool mediaIsOpen = false; UInt64 mediaBlockSize = 0; IOBufferMemoryDescriptor * buffer = 0; uint8_t * bytes = 0; UInt64 bytesAt = 0; UInt64 bufferReadAt = 0; vm_size_t bufferSize = 0; IOReturn status = kIOReturnError; HFSMasterDirectoryBlock * mdbPtr = 0; HFSPlusVolumeHeader * volHdrPtr = 0; VolumeUUID * volumeUUIDPtr = (VolumeUUID *)uuidPtr; DEBUG_LOG("%s::%s\n", kClassName, __func__); do { mediaBlockSize = media->getPreferredBlockSize(); bufferSize = IORound(sizeof(HFSMasterDirectoryBlock), mediaBlockSize); buffer = IOBufferMemoryDescriptor::withCapacity(bufferSize, kIODirectionIn); if ( buffer == 0 ) break; bytes = (uint8_t *) buffer->getBytesNoCopy(); // Open the media with read access. mediaIsOpen = media->open(media, 0, kIOStorageAccessReader); if ( mediaIsOpen == false ) break; bytesAt = 2 * kHFSBlockSize; bufferReadAt = IOTrunc( bytesAt, mediaBlockSize ); bytesAt -= bufferReadAt; mdbPtr = (HFSMasterDirectoryBlock *)&bytes[bytesAt]; volHdrPtr = (HFSPlusVolumeHeader *)&bytes[bytesAt]; status = media->read(media, bufferReadAt, buffer); if ( status != kIOReturnSuccess ) break; /* * If this is a wrapped HFS Plus volume, read the Volume Header from * sector 2 of the embedded volume. */ if ( OSSwapBigToHostInt16(mdbPtr->drSigWord) == kHFSSigWord && OSSwapBigToHostInt16(mdbPtr->drEmbedSigWord) == kHFSPlusSigWord) { u_int32_t allocationBlockSize, firstAllocationBlock, startBlock, blockCount; if (OSSwapBigToHostInt16(mdbPtr->drSigWord) != kHFSSigWord) { break; } allocationBlockSize = OSSwapBigToHostInt32(mdbPtr->drAlBlkSiz); firstAllocationBlock = OSSwapBigToHostInt16(mdbPtr->drAlBlSt); if (OSSwapBigToHostInt16(mdbPtr->drEmbedSigWord) != kHFSPlusSigWord) { break; } startBlock = OSSwapBigToHostInt16(mdbPtr->drEmbedExtent.startBlock); blockCount = OSSwapBigToHostInt16(mdbPtr->drEmbedExtent.blockCount); bytesAt = ((u_int64_t)startBlock * (u_int64_t)allocationBlockSize) + ((u_int64_t)firstAllocationBlock * (u_int64_t)kHFSBlockSize) + (u_int64_t)(2 * kHFSBlockSize); bufferReadAt = IOTrunc( bytesAt, mediaBlockSize ); bytesAt -= bufferReadAt; mdbPtr = (HFSMasterDirectoryBlock *)&bytes[bytesAt]; volHdrPtr = (HFSPlusVolumeHeader *)&bytes[bytesAt]; status = media->read(media, bufferReadAt, buffer); if ( status != kIOReturnSuccess ) break; } /* * At this point, we have the MDB for plain HFS, or VHB for HFS Plus and HFSX * volumes (including wrapped HFS Plus). Verify the signature and grab the * UUID from the Finder Info. */ if (OSSwapBigToHostInt16(mdbPtr->drSigWord) == kHFSSigWord) { bcopy((void *)&mdbPtr->drFndrInfo[6], volumeUUIDPtr->bytes, kVolumeUUIDValueLength); status = kIOReturnSuccess; } else if (OSSwapBigToHostInt16(volHdrPtr->signature) == kHFSPlusSigWord || OSSwapBigToHostInt16(volHdrPtr->signature) == kHFSXSigWord) { bcopy((void *)&volHdrPtr->finderInfo[24], volumeUUIDPtr->bytes, kVolumeUUIDValueLength); status = kIOReturnSuccess; } else { // status = 0 from earlier successful media->read() status = kIOReturnBadMedia; } } while (false); if ( mediaIsOpen ) media->close(media); if ( buffer ) buffer->release(); DEBUG_LOG("%s::%s finishes with status %d\n", kClassName, __func__, status); return status; }
int main(int argc, char *argv[]) { printf(" # ====================================\n"); printf(" #\n"); printf(" # PIE Stripper v%s\n", VERSION); printf(" # Copyright (C) 2015 Zhi-Wei Cai.\n"); printf(" #\n"); printf(" # ====================================\n # \n"); if (argc < 2) { printf(" # Usage: %s target_file\n", argv[0]); return 0; } char *addr = NULL; int fd = open(argv[1], O_RDWR); size_t size; struct stat stat_buf; struct fat_arch *fa; struct fat_header *fh; struct mach_header *mh; struct mach_header_64 *mh64; uint32_t mm; uint32_t err; fstat(fd, &stat_buf); size = stat_buf.st_size; addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); mm = *(uint32_t *)(addr); char *buf = "MH_MAGIC: "; asprintf(&buf,"%s%04X", buf, mm); switch(mm) { case MH_MAGIC: asprintf(&buf,"%s (%s)", buf, "i386"); printLog(buf, 0); mh = (struct mach_header *)addr; addr += sizeof(struct mach_header); err = stripASLR(mh, addr, size); break; case MH_MAGIC_64: asprintf(&buf,"%s (%s)", buf, "x86_64"); printLog(buf, 0); mh64 = (struct mach_header_64 *)addr; addr += sizeof(struct mach_header_64); err = stripASLR64(mh64, addr, size); break; case FAT_CIGAM: asprintf(&buf,"%s (%s)", buf, "FAT"); printLog(buf, 0); fh = (struct fat_header *)addr; // fat_arch struct were stored in big-endian. uint32_t nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); fa = (struct fat_arch *)(addr + sizeof(struct fat_header)); for(;nfat_arch-- > 0; fa++) { uint32_t offset, cputype; cputype = OSSwapBigToHostInt32(fa->cputype); offset = OSSwapBigToHostInt32(fa->offset); char *addr = NULL; switch(cputype) { case 0x7: printLog(" >>> FAT -> i386", 0); addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); mh = (struct mach_header *)(addr + offset); addr += sizeof(struct mach_header) + offset; err = stripASLR(mh, addr, size); break; case 0x1000007: printLog(" >>> FAT -> x86_64", 0); addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); mh64 = (struct mach_header_64 *)(addr + offset); addr += sizeof(struct mach_header_64) + offset; err = stripASLR64(mh64, addr, size); break; default: printLog("UNKNOWN FAT MACH-O TYPE", 1); return 0; } } break; default: printLog("UNKNOWN MACH-O TYPE", 1); return 0; } if (!err) { printLog("MH_PIE: 0 (NO ASLR/PIE)", 1); } munmap(addr, size); close(fd); printLog("All done.\n # ", 0); printf(" # ====================================\n\n"); return 0; }
void mozilla::ReadAheadLib(mozilla::pathstr_t aFilePath) { if (!aFilePath) { return; } #if defined(XP_WIN) ReadAheadFile(aFilePath); #elif defined(LINUX) && !defined(ANDROID) int fd = open(aFilePath, O_RDONLY); if (fd < 0) { return; } union { char buf[bufsize]; Elf_Ehdr ehdr; } elf; // Read ELF header (ehdr) and program header table (phdr). // We check that the ELF magic is found, that the ELF class matches // our own, and that the program header table as defined in the ELF // headers fits in the buffer we read. if ((read(fd, elf.buf, bufsize) <= 0) || (memcmp(elf.buf, ELFMAG, 4)) || (elf.ehdr.e_ident[EI_CLASS] != ELFCLASS) || (elf.ehdr.e_phoff + elf.ehdr.e_phentsize * elf.ehdr.e_phnum >= bufsize)) { close(fd); return; } // The program header table contains segment definitions. One such // segment type is PT_LOAD, which describes how the dynamic loader // is going to map the file in memory. We use that information to // find the biggest offset from the library that will be mapped in // memory. Elf_Phdr *phdr = (Elf_Phdr *)&elf.buf[elf.ehdr.e_phoff]; Elf_Off end = 0; for (int phnum = elf.ehdr.e_phnum; phnum; phdr++, phnum--) { if ((phdr->p_type == PT_LOAD) && (end < phdr->p_offset + phdr->p_filesz)) { end = phdr->p_offset + phdr->p_filesz; } } // Let the kernel read ahead what the dynamic loader is going to // map in memory soon after. if (end > 0) { ReadAhead(fd, 0, end); } close(fd); #elif defined(XP_MACOSX) ScopedMMap buf(aFilePath); char *base = buf; if (!base) { return; } // An OSX binary might either be a fat (universal) binary or a // Mach-O binary. A fat binary actually embeds several Mach-O // binaries. If we have a fat binary, find the offset where the // Mach-O binary for our CPU type can be found. struct fat_header *fh = (struct fat_header *)base; if (OSSwapBigToHostInt32(fh->magic) == FAT_MAGIC) { uint32_t nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); struct fat_arch *arch = (struct fat_arch *)&buf[sizeof(struct fat_header)]; for (; nfat_arch; arch++, nfat_arch--) { if (OSSwapBigToHostInt32(arch->cputype) == CPU_TYPE) { base += OSSwapBigToHostInt32(arch->offset); break; } } if (base == buf) { return; } } // Check Mach-O magic in the Mach header struct cpu_mach_header *mh = (struct cpu_mach_header *)base; if (mh->magic != MH_MAGIC) { return; } // The Mach header is followed by a sequence of load commands. // Each command has a header containing the command type and the // command size. LD_SEGMENT commands describes how the dynamic // loader is going to map the file in memory. We use that // information to find the biggest offset from the library that // will be mapped in memory. char *cmd = &base[sizeof(struct cpu_mach_header)]; off_t end = 0; for (uint32_t ncmds = mh->ncmds; ncmds; ncmds--) { struct segment_command *sh = (struct segment_command *)cmd; if (sh->cmd != LC_SEGMENT) { continue; } if (end < sh->fileoff + sh->filesize) { end = sh->fileoff + sh->filesize; } cmd += sh->cmdsize; } // Let the kernel read ahead what the dynamic loader is going to // map in memory soon after. if (end > 0) { ReadAhead(buf.getFd(), base - buf, end); } #endif }
int fat_iterator_find_fat_arch( fat_iterator iter, cpu_type_t cputype, cpu_subtype_t cpusubtype, struct fat_arch * fat_arch_out) { int result = 0; uint32_t magic; uint32_t nfat_arch; struct fat_arch * fat_arches; struct fat_arch * fat_arches_copy = NULL; // must free struct fat_arch * found_arch; magic = MAGIC32(iter->file_start); if (iter->fat_header) { uint32_t fat_arches_size; uint32_t index; nfat_arch = iter->num_arches; fat_arches_size = nfat_arch * sizeof(struct fat_arch); fat_arches_copy = (struct fat_arch *)(malloc(fat_arches_size)); if (!fat_arches_copy) { goto finish; } fat_arches = fat_arches_copy; memcpy(fat_arches, iter->fat_arches, fat_arches_size); /* NXFindBestFatArch() requires all the fat info to be in host * byte order. */ for (index = 0; index < nfat_arch; index++) { fat_arches[index].cputype = OSSwapBigToHostInt32(fat_arches[index].cputype); fat_arches[index].cpusubtype = OSSwapBigToHostInt32(fat_arches[index].cpusubtype); fat_arches[index].offset = OSSwapBigToHostInt32(fat_arches[index].offset); fat_arches[index].size = OSSwapBigToHostInt32(fat_arches[index].size); fat_arches[index].align = OSSwapBigToHostInt32(fat_arches[index].align); } } else { struct fat_arch fake_fat_arches; uint8_t swap; struct mach_header * mach_hdr; nfat_arch = 1; bzero(&fake_fat_arches, sizeof(fake_fat_arches)); fat_arches = &fake_fat_arches; swap = ISSWAPPEDMACHO(magic); mach_hdr = (struct mach_header *)iter->file_start; fat_arches[0].cputype = CondSwapInt32(swap, mach_hdr->cputype); fat_arches[0].cpusubtype = CondSwapInt32(swap, mach_hdr->cpusubtype); fat_arches[0].offset = 0; fat_arches[0].size = iter->file_end - iter->file_start; fat_arches[0].align = 1; // not used anyhow } found_arch = NXFindBestFatArch(cputype, cpusubtype, fat_arches, nfat_arch); if (found_arch) { result = 1; if (fat_arch_out) { memcpy(fat_arch_out, found_arch, sizeof(*fat_arch_out)); } } finish: if (fat_arches_copy) { free(fat_arches_copy); } return result; }