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;
}
Пример #2
0
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);
    }
}
Пример #3
0
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;
		}
	}
Пример #5
0
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;
}
Пример #7
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;
}
Пример #9
0
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);
}
Пример #10
0
/*
 * 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;
}
Пример #16
0
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();
}
Пример #18
0
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;
	}
}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
uint32_t fmbe32(uint32_t x) { return OSSwapBigToHostInt32(x);    }
Пример #22
0
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);
	}
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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;
}
Пример #26
0
Файл: sys.c Проект: aosm/boot
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);
}
Пример #27
0
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;
}
Пример #28
0
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;
}
Пример #29
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
}
Пример #30
0
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;
}