コード例 #1
0
ファイル: hfslib.c プロジェクト: boxingcow/xpwn
void displayFolder(HFSCatalogNodeID folderID, Volume* volume) {
	CatalogRecordList* list;
	CatalogRecordList* theList;
	HFSPlusCatalogFolder* folder;
	HFSPlusCatalogFile* file;
	time_t fileTime;
	struct tm *date;
	HFSPlusDecmpfs* compressData;
	size_t attrSize;
	
	theList = list = getFolderContents(folderID, volume);
	
	while(list != NULL) {
		if(list->record->recordType == kHFSPlusFolderRecord) {
			folder = (HFSPlusCatalogFolder*)list->record;
			printf("%06o ", folder->permissions.fileMode);
			printf("%3d ", folder->permissions.ownerID);
			printf("%3d ", folder->permissions.groupID);
			printf("%12d ", folder->valence);
			fileTime = APPLE_TO_UNIX_TIME(folder->contentModDate);
		} else if(list->record->recordType == kHFSPlusFileRecord) {
			file = (HFSPlusCatalogFile*)list->record;
			printf("%06o ", file->permissions.fileMode);
			printf("%3d ", file->permissions.ownerID);
			printf("%3d ", file->permissions.groupID);
			if(file->permissions.ownerFlags & UF_COMPRESSED) {
				attrSize = getAttribute(volume, file->fileID, "com.apple.decmpfs", (uint8_t**)(&compressData));
				flipHFSPlusDecmpfs(compressData);
				printf("%12" PRId64 " ", compressData->size);
				free(compressData);
			} else {
				printf("%12" PRId64 " ", file->dataFork.logicalSize);
			}
			fileTime = APPLE_TO_UNIX_TIME(file->contentModDate);
		}
			
		date = localtime(&fileTime);
		if(date != NULL) {
			printf("%2d/%2d/%4d %02d:%02d ", date->tm_mon, date->tm_mday, date->tm_year + 1900, date->tm_hour, date->tm_min);
		} else {
			printf("                 ");
		}

		printUnicode(&list->name);
		printf("\n");
		
		list = list->next;
	}
	
	releaseCatalogRecordList(theList);
}
コード例 #2
0
ファイル: hfslib.c プロジェクト: boxingcow/xpwn
void displayFileLSLine(Volume* volume, HFSPlusCatalogFile* file, const char* name) {
	time_t fileTime;
	struct tm *date;
	HFSPlusDecmpfs* compressData;
	
	printf("%06o ", file->permissions.fileMode);
	printf("%3d ", file->permissions.ownerID);
	printf("%3d ", file->permissions.groupID);

	if(file->permissions.ownerFlags & UF_COMPRESSED) {
		getAttribute(volume, file->fileID, "com.apple.decmpfs", (uint8_t**)(&compressData));
		flipHFSPlusDecmpfs(compressData);
		printf("%12" PRId64 " ", compressData->size);
		free(compressData);
	} else {
		printf("%12" PRId64 " ", file->dataFork.logicalSize);
	}

	fileTime = APPLE_TO_UNIX_TIME(file->contentModDate);
	date = localtime(&fileTime);
	if(date != NULL) {
		printf("%2d/%2d/%4d %2d:%02d ", date->tm_mon, date->tm_mday, date->tm_year + 1900, date->tm_hour, date->tm_min);
	} else {
		printf("                 ");
	}
	printf("%s\n", name);

	XAttrList* next;
	XAttrList* attrs = getAllExtendedAttributes(file->fileID, volume);
	if(attrs != NULL) {
		printf("Extended attributes\n");
		while(attrs != NULL) {
			next = attrs->next;
			printf("\t%s\n", attrs->name);
			free(attrs->name);
			free(attrs);
			attrs = next;
		}	
	}	
}
コード例 #3
0
ファイル: hfscompress.c プロジェクト: 0bj3ct1veC/xpwn
io_func* openHFSPlusCompressed(Volume* volume, HFSPlusCatalogFile* file) {
	io_func* io;
	HFSPlusCompressed* data;
	uLongf actualSize;

	io = (io_func*) malloc(sizeof(io_func));
	data = (HFSPlusCompressed*) malloc(sizeof(HFSPlusCompressed));

	data->volume = volume;
	data->file = file;

	io->data = data;
	io->read = &compressedRead;
	io->write = &compressedWrite;
	io->close = &closeHFSPlusCompressed;

	data->cached = NULL;
	data->cachedStart = 0;
	data->cachedEnd = 0;
	data->io = NULL;
	data->blocks = NULL;
	data->dirty = FALSE;

	data->decmpfsSize = getAttribute(volume, file->fileID, "com.apple.decmpfs", (uint8_t**)(&data->decmpfs));
	if(data->decmpfsSize == 0) {
		data->decmpfs = (HFSPlusDecmpfs*) malloc(0x1000);
		data->decmpfs->size = 0;
		return io;		// previously not compressed file
	}

	flipHFSPlusDecmpfs(data->decmpfs);

	if(data->decmpfs->flags == 0x3) {
		data->cached = (uint8_t*) malloc(data->decmpfs->size);
		actualSize = data->decmpfs->size;
		uncompress(data->cached, &actualSize, data->decmpfs->data, data->decmpfsSize - sizeof(HFSPlusDecmpfs));
		if(actualSize != data->decmpfs->size) {
			fprintf(stderr, "decmpfs: size mismatch\n");
		}
		data->cachedStart = 0;
		data->cachedEnd = actualSize;
	} else {
		data->io = openRawFile(file->fileID, &file->resourceFork, (HFSPlusCatalogRecord*)file, volume);
		if(!data->io) {
			hfs_panic("error opening resource fork");
		}

		if(!READ(data->io, 0, sizeof(HFSPlusCmpfRsrcHead), &data->rsrcHead)) {
			hfs_panic("error reading");
		}

		flipRsrcHead(&data->rsrcHead);

		data->blocks = (HFSPlusCmpfRsrcBlockHead*) malloc(sizeof(HFSPlusCmpfRsrcBlockHead));
		if(!READ(data->io, data->rsrcHead.headerSize, sizeof(HFSPlusCmpfRsrcBlockHead), data->blocks)) {
			hfs_panic("error reading");
		}

		flipRsrcBlockHead(data->blocks);

		data->blocks = (HFSPlusCmpfRsrcBlockHead*) realloc(data->blocks, sizeof(HFSPlusCmpfRsrcBlockHead) + (sizeof(HFSPlusCmpfRsrcBlock) * data->blocks->numBlocks));
		if(!READ(data->io, data->rsrcHead.headerSize + sizeof(HFSPlusCmpfRsrcBlockHead), sizeof(HFSPlusCmpfRsrcBlock) * data->blocks->numBlocks, data->blocks->blocks)) {
			hfs_panic("error reading");
		}

		int i;
		for(i = 0; i < data->blocks->numBlocks; i++) {
			flipRsrcBlock(&data->blocks->blocks[i]);
		}
	}

	return io;
}
コード例 #4
0
ファイル: hfscompress.c プロジェクト: 0bj3ct1veC/xpwn
static void closeHFSPlusCompressed(io_func* io) {
	HFSPlusCompressed* data = (HFSPlusCompressed*) io->data;

	if(data->io)
		CLOSE(data->io);

	if(data->dirty) {
		int oldSize = data->decmpfsSize;

		if(data->blocks)
			free(data->blocks);

		data->decmpfs->magic = CMPFS_MAGIC; 
		data->decmpfs->flags = 0x4;
		data->decmpfsSize = sizeof(HFSPlusDecmpfs);

		uint32_t numBlocks = (data->decmpfs->size + 0xFFFF) / 0x10000;
		uint32_t blocksSize = sizeof(HFSPlusCmpfRsrcBlockHead) + (numBlocks * sizeof(HFSPlusCmpfRsrcBlock));
		data->blocks = (HFSPlusCmpfRsrcBlockHead*) malloc(sizeof(HFSPlusCmpfRsrcBlockHead) + (numBlocks * sizeof(HFSPlusCmpfRsrcBlock)));
		data->blocks->numBlocks = numBlocks;
		data->blocks->dataSize = blocksSize - sizeof(uint32_t); // without the front dataSize in BlockHead.

		data->rsrcHead.headerSize = 0x100;
		data->rsrcHead.dataSize = blocksSize;
		data->rsrcHead.totalSize = data->rsrcHead.headerSize + data->rsrcHead.dataSize;
		data->rsrcHead.flags = 0x32;

		uint8_t* buffer = (uint8_t*) malloc((0x10000 * 1.1) + 12);
		uint32_t curFileOffset = data->blocks->dataSize;
		uint32_t i;
		for(i = 0; i < numBlocks; i++) {
			data->blocks->blocks[i].offset = curFileOffset;
			uLongf actualSize = (0x10000 * 1.1) + 12;
			compress(buffer, &actualSize, data->cached + (0x10000 * i),
					(data->decmpfs->size - (0x10000 * i)) > 0x10000 ? 0x10000 : (data->decmpfs->size - (0x10000 * i))); 
			data->blocks->blocks[i].size = actualSize;

			// check if we can fit the whole thing into an inline extended attribute
			// a little fudge factor here since sizeof(HFSPlusAttrKey) is bigger than it ought to be, since only 127 characters are strictly allowed
			if(numBlocks <= 1 && (actualSize + sizeof(HFSPlusDecmpfs) + sizeof(HFSPlusAttrKey)) <= 0x1000) {
				int newSize = (sizeof(HFSPlusDecmpfs) + actualSize + 1) & ~1;
				if (oldSize < newSize) {
					printf("growing ");
					data->decmpfs = realloc(data->decmpfs, newSize);
					memset(data->decmpfs->data + actualSize, 0, newSize - actualSize - sizeof(HFSPlusDecmpfs));
				}
				data->decmpfs->flags = 0x3;
				memcpy(data->decmpfs->data, buffer, actualSize);
				data->decmpfsSize = newSize;
				printf("inline data\n");
				break;
			} else {
				if(i == 0) {
					data->io = openRawFile(data->file->fileID, &data->file->resourceFork, (HFSPlusCatalogRecord*)data->file, data->volume);
					if(!data->io) {
						hfs_panic("error opening resource fork");
					}
				}

				WRITE(data->io, data->rsrcHead.headerSize + sizeof(uint32_t) + data->blocks->blocks[i].offset, data->blocks->blocks[i].size, buffer);

				curFileOffset += data->blocks->blocks[i].size;
				data->blocks->dataSize += data->blocks->blocks[i].size;
				data->rsrcHead.dataSize += data->blocks->blocks[i].size;
				data->rsrcHead.totalSize += data->blocks->blocks[i].size;
			}
		}

		free(buffer);
		
		if(data->decmpfs->flags == 0x4) {
			flipRsrcHead(&data->rsrcHead);
			WRITE(data->io, 0, sizeof(HFSPlusCmpfRsrcHead), &data->rsrcHead);
			flipRsrcHead(&data->rsrcHead);

			for(i = 0; i < data->blocks->numBlocks; i++) {
				flipRsrcBlock(&data->blocks->blocks[i]);
			}
			flipRsrcBlockHead(data->blocks);
			WRITE(data->io, data->rsrcHead.headerSize, blocksSize, data->blocks);
			flipRsrcBlockHead(data->blocks);
			for(i = 0; i < data->blocks->numBlocks; i++) {
				flipRsrcBlock(&data->blocks->blocks[i]);
			}

			HFSPlusCmpfEnd end;
			memset(&end, 0, sizeof(HFSPlusCmpfEnd));
			end.unk1 = 0x1C;
			end.unk2 = 0x32;
			end.unk3 = 0x0;
			end.magic = CMPFS_MAGIC;
			end.flags = 0xA;
			end.size = 0xFFFF01;
			end.unk4 = 0x0;

			flipHFSPlusCmpfEnd(&end);
			WRITE(data->io, data->rsrcHead.totalSize, sizeof(HFSPlusCmpfEnd), &end);
			flipHFSPlusCmpfEnd(&end);

			CLOSE(data->io);
		}

		flipHFSPlusDecmpfs(data->decmpfs);
		setAttribute(data->volume, data->file->fileID, "com.apple.decmpfs", (uint8_t*)(data->decmpfs), data->decmpfsSize);
		flipHFSPlusDecmpfs(data->decmpfs);
	}

	if(data->cached)
		free(data->cached);

	if(data->blocks)
		free(data->blocks);

	free(data->decmpfs);
	free(data);
	free(io);
}