void swap_JournalInfoBlock(JournalInfoBlock* record) { // trace("record (%p)", record); /* struct JournalInfoBlock { uint32_t flags; uint32_t device_signature[8]; // signature used to locate our device. uint64_t offset; // byte offset to the journal on the device uint64_t size; // size in bytes of the journal uuid_string_t ext_jnl_uuid; char machine_serial_num[48]; char reserved[JIB_RESERVED_SIZE]; } __attribute__((aligned(2), packed)); typedef struct JournalInfoBlock JournalInfoBlock; */ Swap32(record->flags); for(unsigned i = 0; i < 8; i++) Swap32(record->device_signature[i]); Swap64(record->offset); Swap64(record->size); // noswap: uuid_string_t is a series of char // noswap: machine_serial_num is a series of char // noswap: reserved is reserved }
/** * Writes a 64-bit value to the stream. */ void IDataStream::Write64(UInt64 inData) { if(swapBytes) inData = Swap64(inData); WriteBuf(&inData, sizeof(UInt64)); }
void swap_HFSPlusForkData(HFSPlusForkData* record) { // trace("record (%p)", record); Swap64(record->logicalSize); Swap32(record->totalBlocks); Swap32(record->clumpSize); swap_HFSPlusExtentRecord(record->extents); }
void swap_HFSPlusVolumeHeader(HFSPlusVolumeHeader* record) { // trace("record (%p)", record); Swap16(record->signature); Swap16(record->version); Swap32(record->attributes); Swap32(record->lastMountedVersion); Swap32(record->journalInfoBlock); Swap32(record->createDate); Swap32(record->modifyDate); Swap32(record->backupDate); Swap32(record->checkedDate); Swap32(record->fileCount); Swap32(record->folderCount); Swap32(record->blockSize); Swap32(record->totalBlocks); Swap32(record->freeBlocks); Swap32(record->nextAllocation); Swap32(record->rsrcClumpSize); Swap32(record->dataClumpSize); Swap32(record->nextCatalogID); Swap32(record->writeCount); Swap64(record->encodingsBitmap); HFSPlusVolumeFinderInfo* finderInfo = (void*)&record->finderInfo; Swap32(finderInfo->bootDirID); Swap32(finderInfo->bootParentID); Swap32(finderInfo->openWindowDirID); Swap32(finderInfo->os9DirID); // noswap: reserved is reserved (uint32) Swap32(finderInfo->osXDirID); Swap64(finderInfo->volID); swap_HFSPlusForkData(&record->allocationFile); swap_HFSPlusForkData(&record->extentsFile); swap_HFSPlusForkData(&record->catalogFile); swap_HFSPlusForkData(&record->attributesFile); swap_HFSPlusForkData(&record->startupFile); }
/** * Reads and returns a 64-bit value from the stream */ UInt64 IDataStream::Read64(void) { UInt64 out; ReadBuf(&out, sizeof(UInt64)); if(swapBytes) out = Swap64(out); return out; }
static void CoreOS_Unpack(u8 *buffer) { struct coreHdr *hdr = (struct coreHdr *)buffer; struct coreEntry *entry = (struct coreEntry *)hdr->entries; u32 i; s32 ret; /* Unpack entries */ for (i = 0; i < Swap32(hdr->files); i++, entry++) { char *filename = entry->filename; u64 filesize = Swap64(entry->filesize); u64 offset = Swap64(entry->offset); /* Entry info */ printf("File: %-32s (offset: 0x%08llX, size: %.2f MB)\n", filename, offset, filesize / MEGABYTE); /* Write file */ ret = File_Write(filename, buffer + offset, filesize); if (ret <= 0) fprintf(stderr, "ERROR: Could not unpack file \"%s\"! (%d)\n", filename, ret); } }
// // Convert byte order // static void ConvertExecutable(VMExecutable * oCore) { // Code entry point oCore -> entry_point = Swap32(oCore -> entry_point); // Offset of code segment oCore -> code_offset = Swap32(oCore -> code_offset); // Code segment size oCore -> code_size = Swap32(oCore -> code_size); // Offset of static text segment oCore -> syscalls_offset = Swap32(oCore -> syscalls_offset); // Static text segment size oCore -> syscalls_data_size = Swap32(oCore -> syscalls_data_size); // Offset of static text index segment oCore -> syscalls_index_offset = Swap32(oCore -> syscalls_index_offset); // Static text index segment size oCore -> syscalls_index_size = Swap32(oCore -> syscalls_index_size); // Offset of static data segment oCore -> static_data_offset = Swap32(oCore -> static_data_offset); // Static data segment size oCore -> static_data_data_size = Swap32(oCore -> static_data_data_size); // Offset of static text segment oCore -> static_text_offset = Swap32(oCore -> static_text_offset); // Static text segment size oCore -> static_text_data_size = Swap32(oCore -> static_text_data_size); // Offset of static text index segment oCore -> static_text_index_offset = Swap32(oCore -> static_text_index_offset); // Static text index segment size oCore -> static_text_index_size = Swap32(oCore -> static_text_index_size); // Version 2.2+ // Offset of static data bit index oCore -> static_data_bit_index_offset = Swap32(oCore -> static_data_bit_index_offset); /// Offset of static data bit index oCore -> static_data_bit_index_size = Swap32(oCore -> static_data_bit_index_size); // Platform oCore -> platform = Swap64(oCore -> platform); // Ugly-jolly hack! // ... dereferencing type-punned pointer will break strict-aliasing rules ... UINT_64 iTMP; memcpy(&iTMP, &(oCore -> ieee754double), sizeof(UINT_64)); iTMP = Swap64(iTMP); memcpy(&(oCore -> ieee754double), &iTMP, sizeof(UINT_64)); // Cyclic Redundancy Check oCore -> crc = 0; // Convert data structures // Convert code segment VMInstruction * pInstructions = const_cast<VMInstruction *>(VMExecutable::GetCodeSeg(oCore)); UINT_32 iI = 0; UINT_32 iSteps = oCore -> code_size / sizeof(VMInstruction); for(iI = 0; iI < iSteps; ++iI) { pInstructions -> instruction = Swap32(pInstructions -> instruction); pInstructions -> argument = Swap32(pInstructions -> argument); pInstructions -> reserved = Swap64(pInstructions -> reserved); ++pInstructions; } // Convert syscalls index TextDataIndex * pTextIndex = const_cast<TextDataIndex *>(VMExecutable::GetSyscallsIndexSeg(oCore)); iSteps = oCore -> syscalls_index_size / sizeof(TextDataIndex); for(iI = 0; iI < iSteps; ++iI) { pTextIndex -> offset = Swap32(pTextIndex -> offset); pTextIndex -> length = Swap32(pTextIndex -> length); ++pTextIndex; } // Convert static text index pTextIndex = const_cast<TextDataIndex *>(VMExecutable::GetStaticTextIndexSeg(oCore)); iSteps = oCore -> static_text_index_size / sizeof(TextDataIndex); for(iI = 0; iI < iSteps; ++iI) { pTextIndex -> offset = Swap32(pTextIndex -> offset); pTextIndex -> length = Swap32(pTextIndex -> length); ++pTextIndex; } // Convert static data StaticDataVar * pStaticDataVar = const_cast<StaticDataVar *>(VMExecutable::GetStaticDataSeg(oCore)); iSteps = oCore -> static_data_data_size / sizeof(StaticDataVar); for(iI = 0; iI < iSteps; ++iI) { (*pStaticDataVar).i_data = Swap64((*pStaticDataVar).i_data); ++pStaticDataVar; } }
static void CoreOS_Pack(const char *outfile, const char **filelist, u32 files) { struct coreHdr *hdr = NULL; struct coreEntry *entry = NULL; FILE *fp; u32 i, j; /* Create file */ fp = fopen(outfile, "wb"); if (!fp) { fprintf(stderr, "ERROR: Could not create file \"%s\"! (%d)\n", outfile, errno); return; } /* Allocate memory */ hdr = malloc(sizeof(*hdr)); entry = malloc(sizeof(*entry) * files); /* Write empty header */ fwrite(hdr, 1, sizeof(*hdr), fp); /* Write empty entries */ fwrite(entry, 1, sizeof(*entry) * files, fp); /* Pack entries */ for (i = 0; i < files; ++i) { const char *filename = filelist[i]; u64 offset = ftell(fp); u8 *buffer = NULL; u32 buflen; /* Read file */ buflen = File_Read(filename, &buffer); if (buflen <= 0) { fprintf(stderr, "ERROR: Could not pack file \"%s\"! (%d)\n", filename, buflen); goto out; } /* File info */ printf("File: %-32s (offset: 0x%08llX, size: %.2f MB)\n", filename, offset, buflen / MEGABYTE); /* Write entry */ fwrite(buffer, 1, buflen, fp); /* Write padding */ for (j = 0; j < (buflen % 4); ++j) fputc(0, fp); /* Free buffer */ free(buffer); /* Fill entry */ entry[i].offset = Swap64(offset); entry[i].filesize = Swap64(buflen); strncpy(entry[i].filename, filename, FILENAME_LEN); } /* Fill header */ hdr->unk = Swap32(1); hdr->files = Swap32(files); hdr->size = Swap64(ftell(fp)); /* Write header */ fseek(fp, 0, SEEK_SET); fwrite(hdr, 1, sizeof(*hdr), fp); /* Write entries */ fwrite(entry, 1, sizeof(*entry) * files, fp); out: /* Close file */ if (fp) fclose(fp); /* Free buffers */ if (hdr) free(hdr); if (entry) free(entry); }