Ejemplo n.º 1
0
void writeDriverDescriptorMap(AbstractFile* file, DriverDescriptorRecord* DDM, ChecksumFunc dataForkChecksum, void* dataForkToken,
				ResourceKey **resources) {
  AbstractFile* bufferFile;
  BLKXTable* blkx;
  ChecksumToken uncompressedToken;
  DriverDescriptorRecord* buffer;
  
  buffer = (DriverDescriptorRecord*) malloc(DDM_SIZE * SECTOR_SIZE);
  memcpy(buffer, DDM, DDM_SIZE * SECTOR_SIZE);
  memset(&uncompressedToken, 0, sizeof(uncompressedToken));
  
  flipDriverDescriptorRecord(buffer, TRUE);

  bufferFile = createAbstractFileFromMemory((void**)&buffer, DDM_SIZE * SECTOR_SIZE);
  
  blkx = insertBLKX(file, bufferFile, DDM_OFFSET, DDM_SIZE, DDM_DESCRIPTOR, CHECKSUM_CRC32, &CRCProxy, &uncompressedToken,
			dataForkChecksum, dataForkToken, NULL);
              
  blkx->checksum.data[0] = uncompressedToken.crc;
  
  *resources = insertData(*resources, "blkx", -1, "Driver Descriptor Map (DDM : 0)", (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
  
  free(buffer);
  bufferFile->close(bufferFile);
  free(blkx);
}
Ejemplo n.º 2
0
void readDriverDescriptorMap(AbstractFile* file, ResourceKey* resources) {
  BLKXTable* blkx;
  unsigned char* buffer;
  AbstractFile* bufferFile;
  DriverDescriptorRecord* record;
  int i;
  
  blkx = (BLKXTable*) (getDataByID(getResourceByKey(resources, "blkx"), -1)->data);

  buffer = (unsigned char*) malloc(512);
  bufferFile = createAbstractFileFromMemory((void**)&(buffer), 512);
  extractBLKX(file, bufferFile, blkx);
  bufferFile->close(bufferFile);

  record = (DriverDescriptorRecord*)buffer;
  flipDriverDescriptorRecord(record, FALSE);
  printf("sbSig:\t\t0x%x\n", record->sbSig);
  printf("sbBlkSize:\t0x%x\n", record->sbBlkSize);
  printf("sbBlkCount:\t0x%x\n", record->sbBlkCount);
  printf("sbDevType:\t0x%x\n", record->sbDevType);
  printf("sbDevId:\t0x%x\n", record->sbDevId);
  printf("sbData:\t\t0x%x\n", record->sbData);
  printf("sbDrvrCount:\t0x%x\n", record->sbDrvrCount);
  printf("ddBlock:\t0x%x\n", record->ddBlock);
  printf("ddSize:\t\t0x%x\n", record->ddSize);
  printf("ddType:\t\t0x%x\n", record->ddType);
  
  for(i = 0; i < (record->sbDrvrCount - 1); i++) {
    printf("\tddBlock:\t0x%x\n", record->ddPad[i].ddBlock);
    printf("\tddSize:\t\t0x%x\n", record->ddPad[i].ddSize);
    printf("\tddType:\t\t0x%x\n", record->ddPad[i].ddType);
  }
  
  free(buffer);
}
Ejemplo n.º 3
0
int copyAcrossVolumes(Volume* volume1, Volume* volume2, char* path1, char* path2) {
	void* buffer;
	size_t bufferSize;
	AbstractFile* tmpFile;
	int ret;
	
	buffer = malloc(1);
	bufferSize = 0;
	tmpFile = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);
	
	if(!silence)
	{
		printf("retrieving... "); fflush(stdout);
	}

	get_hfs(volume1, path1, tmpFile);
	tmpFile->seek(tmpFile, 0);

	if(!silence)
	{
		printf("writing (%ld)... ", (long) tmpFile->getLength(tmpFile)); fflush(stdout);
	}

	ret = add_hfs(volume2, tmpFile, path2);

	if(!silence)
	{
		printf("done\n");
	}
	
	free(buffer);
	
	return ret;
}
Ejemplo n.º 4
0
int writeDriverDescriptorMap(int pNum, AbstractFile* file, DriverDescriptorRecord* DDM, unsigned int BlockSize, ChecksumFunc dataForkChecksum, void* dataForkToken,
				ResourceKey **resources) {
  AbstractFile* bufferFile;
  BLKXTable* blkx;
  ChecksumToken uncompressedToken;
  DriverDescriptorRecord* buffer;
  
  buffer = (DriverDescriptorRecord*) malloc(DDM_SIZE * BlockSize);
  memcpy(buffer, DDM, DDM_SIZE * BlockSize);
  memset(&uncompressedToken, 0, sizeof(uncompressedToken));
  
  flipDriverDescriptorRecord(buffer, TRUE);

  bufferFile = createAbstractFileFromMemory((void**)&buffer, DDM_SIZE * BlockSize);
  
  blkx = insertBLKX(file, bufferFile, DDM_OFFSET, DDM_SIZE, DDM_DESCRIPTOR, CHECKSUM_CRC32, &CRCProxy, &uncompressedToken,
			dataForkChecksum, dataForkToken, NULL, 0);
              
  blkx->checksum.data[0] = uncompressedToken.crc;
  
  char pName[100];
  sprintf(pName, "Driver Descriptor Map (DDM : %d)", pNum + 1);	
  *resources = insertData(*resources, "blkx", pNum, pName, (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
  
  free(buffer);
  bufferFile->close(bufferFile);
  free(blkx);

  pNum++;

  if((DDM_SIZE * BlockSize / SECTOR_SIZE) - DDM_SIZE > 0)
    pNum = writeFreePartition(pNum, file, DDM_SIZE, (DDM_SIZE * BlockSize / SECTOR_SIZE) - DDM_SIZE, resources);

  return pNum;
}
Ejemplo n.º 5
0
Archivo: hfs.c Proyecto: arkanoid1/xpwn
void cmd_extract(Volume* volume, int argc, const char *argv[]) {
	HFSPlusCatalogRecord* record;
	AbstractFile *outFile;
	
	if(argc < 3) {
		printf("Not enough arguments");
		return;
	}
	
	outFile = createAbstractFileFromFile(fopen(argv[2], "wb"));
	
	if(outFile == NULL) {
		printf("cannot create file");
	}
	
	record = getRecordFromPath(argv[1], volume, NULL, NULL);
	
	if(record != NULL) {
		if(record->recordType == kHFSPlusFileRecord)
			writeToFile((HFSPlusCatalogFile*)record, outFile, volume);
		else
			printf("Not a file\n");
	} else {
		printf("No such file or directory\n");
	}
	
	outFile->close(outFile);
	free(record);
}
Ejemplo n.º 6
0
int absFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
	AbstractFile* file;
	file = (AbstractFile*) io->data;
	file->seek(file, location);
	if(file->write(file, buffer, size) == size) {
		return TRUE;
	} else {
		return FALSE;
	}
}
Ejemplo n.º 7
0
int writeApplePartitionMap(int pNum, AbstractFile* file, Partition* partitions, unsigned int BlockSize, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources, NSizResource** nsizIn) {
  AbstractFile* bufferFile;
  BLKXTable* blkx;
  ChecksumToken uncompressedToken;
  Partition* buffer;
  NSizResource* nsiz;
  CSumResource csum;
 
  size_t realPartitionSize = (PARTITION_SIZE * SECTOR_SIZE) / BlockSize * BlockSize; 
  buffer = (Partition*) malloc(realPartitionSize);
  memcpy(buffer, partitions, realPartitionSize);
  memset(&uncompressedToken, 0, sizeof(uncompressedToken));
   
  flipPartition(buffer, TRUE, BlockSize);

  bufferFile = createAbstractFileFromMemory((void**)&buffer, realPartitionSize);
   
  blkx = insertBLKX(file, bufferFile, PARTITION_OFFSET * BlockSize / SECTOR_SIZE, realPartitionSize / SECTOR_SIZE, pNum, CHECKSUM_CRC32,
              &BlockCRC, &uncompressedToken, dataForkChecksum, dataForkToken, NULL, 0);
  
  bufferFile->close(bufferFile);

  *((uint32_t*)blkx->checksum.data) = uncompressedToken.crc;
  
  csum.version = 1;
  csum.type = CHECKSUM_MKBLOCK;
  csum.checksum = uncompressedToken.block;

  char pName[100];
  sprintf(pName, "Apple (Apple_partition_map : %d)", pNum + 1);	
  *resources = insertData(*resources, "blkx", pNum, pName, (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
  *resources = insertData(*resources, "cSum", 0, "", (const char*) (&csum), sizeof(csum), 0);
  
  nsiz = (NSizResource*) malloc(sizeof(NSizResource));
  memset(nsiz, 0, sizeof(NSizResource));
  nsiz->isVolume = FALSE;
  nsiz->blockChecksum2 = uncompressedToken.block;
  nsiz->partitionNumber = 0;
  nsiz->version = 6;
  nsiz->next = NULL;
  
  if((*nsizIn) == NULL) {
    *nsizIn = nsiz;
  } else {
    nsiz->next = (*nsizIn)->next;
    (*nsizIn)->next = nsiz;
  }
  
  free(buffer);
  free(blkx);

  return pNum + 1;
}
Ejemplo n.º 8
0
int main(int argc, char* argv[]) {
	init_libxpwn();
	
	if(argc < 4) {
		print_usage();
		return 0;
	}

	AbstractFile* png;
	AbstractFile* img;
	AbstractFile* dst;
	void* imageBuffer;
	size_t imageSize;

	unsigned int key[16];
	unsigned int iv[16];
	unsigned int* pKey = NULL;
	unsigned int* pIV = NULL;

	if(strcmp(argv[1], "e") == 0) {
		img = createAbstractFileFromFile(fopen(argv[2], "rb"));

		if(argc >= 6) {
			sscanf(argv[4], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
				&iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8],
				&iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]);

			sscanf(argv[5], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
				&key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8],
				&key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15]);

			pKey = key;
			pIV = iv;
		}
			
		AbstractFile2* img3 = (AbstractFile2*) createAbstractFileFromImg3(img);
		img3->setKey(img3, key, iv);
		
		AbstractFile * out = createAbstractFileFromFile(fopen(argv[3], "wb"));
		
		size_t inDataSize = (size_t) ((AbstractFile *)img3)->getLength((AbstractFile *)img3);
		char *inData = (char*) malloc(inDataSize);
		
		((AbstractFile *)img3)->read((AbstractFile *)img3, inData, inDataSize);
		
		out->write(out, inData, inDataSize);
		
	}

	return 0;
}
Ejemplo n.º 9
0
BOOL hfslib_untar(HfsContext* ctx, char* tarFile) {
	AbstractFile *inFile = createAbstractFileFromFile(fopen(tarFile, "rb"));
	BOOL result = FALSE;
	if(inFile == NULL) {
		printf("file to untar not found");
	} else {
		result = hfs_untar(ctx->volume, inFile);
	}

	if (inFile != NULL) {
		inFile->close(inFile);
	}
	return result;
}
Ejemplo n.º 10
0
void fixupBootNeuterArgs(Volume* volume, char unlockBaseband, char selfDestruct, char use39, char use46) {
	const char bootNeuterPlist[] = "/System/Library/LaunchDaemons/com.devteam.bootneuter.auto.plist";
	AbstractFile* plistFile;
	char* plist;
	Dictionary* info;
	size_t bufferSize;
	ArrayValue* arguments;
	
	XLOG(0, "fixing up BootNeuter arguments...\n");
	
	plist = malloc(1);
	bufferSize = 0;
	plistFile = createAbstractFileFromMemoryFile((void**)&plist, &bufferSize);
	get_hfs(volume, bootNeuterPlist, plistFile);	
	plistFile->close(plistFile);
	info = createRoot(plist);
	free(plist);

	arguments = (ArrayValue*) getValueByKey(info, "ProgramArguments");
	addStringToArray(arguments, "-autoMode");
	addStringToArray(arguments, "YES");
	addStringToArray(arguments, "-RegisterForSystemEvents");
	addStringToArray(arguments, "YES");
	
	if(unlockBaseband) {
		addStringToArray(arguments, "-unlockBaseband");
		addStringToArray(arguments, "YES");
	}
	
	if(selfDestruct) {
		addStringToArray(arguments, "-selfDestruct");
		addStringToArray(arguments, "YES");
	}
	
	if(use39) {
		addStringToArray(arguments, "-bootLoader");
		addStringToArray(arguments, "3.9");
	} else if(use46) {
		addStringToArray(arguments, "-bootLoader");
		addStringToArray(arguments, "4.6");
	}
	
	plist = getXmlFromRoot(info);
	releaseDictionary(info);
	
	plistFile = createAbstractFileFromMemory((void**)&plist, sizeof(char) * strlen(plist));
	add_hfs(volume, plistFile, bootNeuterPlist);
	free(plist);
}
Ejemplo n.º 11
0
void extractAllInFolder(HFSCatalogNodeID folderID, Volume* volume) {
	CatalogRecordList* list;
	CatalogRecordList* theList;
	char cwd[1024];
	char* name;
	HFSPlusCatalogFolder* folder;
	HFSPlusCatalogFile* file;
	AbstractFile* outFile;
	struct stat status;
	
	ASSERT(getcwd(cwd, 1024) != NULL, "cannot get current working directory");
	
	theList = list = getFolderContents(folderID, volume);
	
	while(list != NULL) {
		name = unicodeToAscii(&list->name);
		if(strncmp(name, ".HFS+ Private Directory Data", sizeof(".HFS+ Private Directory Data") - 1) == 0 || name[0] == '\0') {
			free(name);
			list = list->next;
			continue;
		}
		
		if(list->record->recordType == kHFSPlusFolderRecord) {
			folder = (HFSPlusCatalogFolder*)list->record;
			printf("folder: %s\n", name);
			if(stat(name, &status) != 0) {
				ASSERT(mkdir(name, 0755) == 0, "mkdir");
			}
			ASSERT(chdir(name) == 0, "chdir");
			extractAllInFolder(folder->folderID, volume);
			ASSERT(chdir(cwd) == 0, "chdir");
		} else if(list->record->recordType == kHFSPlusFileRecord) {
			printf("file: %s\n", name);
			file = (HFSPlusCatalogFile*)list->record;
			outFile = createAbstractFileFromFile(fopen(name, "wb"));
			if(outFile != NULL) {
				writeToFile(file, outFile, volume);
				outFile->close(outFile);
			} else {
				printf("WARNING: cannot fopen %s\n", name);
			}
		}
		
		free(name);
		list = list->next;
	}
	releaseCatalogRecordList(theList);
}
Ejemplo n.º 12
0
void writeATAPI(AbstractFile* file, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources, NSizResource** nsizIn) {
  AbstractFile* bufferFile;
  BLKXTable* blkx;
  ChecksumToken uncompressedToken;
  NSizResource* nsiz;
  CSumResource csum;
  char* atapi;
  
  memset(&uncompressedToken, 0, sizeof(uncompressedToken));
  
  atapi = (char*) malloc(ATAPI_SIZE * SECTOR_SIZE);
  printf("malloc: %p %d\n", atapi, ATAPI_SIZE * SECTOR_SIZE); fflush(stdout);
  memcpy(atapi, atapi_data, ATAPI_SIZE * SECTOR_SIZE);
  bufferFile = createAbstractFileFromMemory((void**)&atapi, ATAPI_SIZE * SECTOR_SIZE);

  blkx = insertBLKX(file, bufferFile, ATAPI_OFFSET, ATAPI_SIZE, 1, CHECKSUM_CRC32,
              &BlockCRC, &uncompressedToken, dataForkChecksum, dataForkToken, NULL);

  bufferFile->close(bufferFile);
  free(atapi);

  blkx->checksum.data[0] = uncompressedToken.crc;
  
  csum.version = 1;
  csum.type = CHECKSUM_MKBLOCK;
  csum.checksum = uncompressedToken.block;

  *resources = insertData(*resources, "blkx", 1, "Macintosh (Apple_Driver_ATAPI : 2)", (const char*) blkx, sizeof(BLKXTable) + (blkx->blocksRunCount * sizeof(BLKXRun)), ATTRIBUTE_HDIUTIL);
  *resources = insertData(*resources, "cSum", 1, "", (const char*) (&csum), sizeof(csum), 0);
  
  nsiz = (NSizResource*) malloc(sizeof(NSizResource));
  memset(nsiz, 0, sizeof(NSizResource));
  nsiz->isVolume = FALSE;
  nsiz->blockChecksum2 = uncompressedToken.block;
  nsiz->partitionNumber = 1;
  nsiz->version = 6;
  nsiz->next = NULL;
  
  if((*nsizIn) == NULL) {
    *nsizIn = nsiz;
  } else {
    nsiz->next = (*nsizIn)->next;
    (*nsizIn)->next = nsiz;
  }
  
  free(blkx);
}
Ejemplo n.º 13
0
void createRestoreOptions(Volume* volume, const char *optionsPlist, int SystemPartitionSize, int UpdateBaseband) {
	AbstractFile* plistFile;
	Dictionary* info;
	char* plist;

	HFSPlusCatalogRecord* record;
	info = NULL;
	record = getRecordFromPath(optionsPlist, volume, NULL, NULL);
	if(record != NULL && record->recordType == kHFSPlusFileRecord) {
		HFSPlusCatalogFile* file = (HFSPlusCatalogFile*)record;
		size_t bufferSize = 512;
		plist = malloc(bufferSize);
		plistFile = createAbstractFileFromMemory((void**)&plist, bufferSize);
		if (plistFile) {
			char zero = 0;
			writeToFile(file, plistFile, volume);
			plistFile->write(plistFile, &zero, sizeof(zero));
			plistFile->close(plistFile);
			info = createRoot(plist);
			removeKey(info, "CreateFilesystemPartitions");
			removeKey(info, "SystemPartitionSize");
			removeKey(info, "UpdateBaseband");
			removeKey(info, "MinimumSystemPartition");
			addIntegerToDictionary(info, "MinimumSystemPartition", SystemPartitionSize);
			XLOG(0, "got %s from ramdisk\n", optionsPlist);
		}
		free(plist);
	}

	XLOG(0, "start create restore options\n");

	if (!info) info = createRoot("<dict></dict>");
	addBoolToDictionary(info, "CreateFilesystemPartitions", TRUE);
	addIntegerToDictionary(info, "SystemPartitionSize", SystemPartitionSize);
	addBoolToDictionary(info, "UpdateBaseband", UpdateBaseband);

	plist = getXmlFromRoot(info);
	releaseDictionary(info);
	
	XLOG(0, "%s", plist);

	plistFile = createAbstractFileFromMemory((void**)&plist, sizeof(char) * strlen(plist));

	add_hfs(volume, plistFile, optionsPlist);
	free(plist);
}
Ejemplo n.º 14
0
void doPatchInPlace(Volume* volume, const char* filePath, const char* patchPath) {
	void* buffer;
	void* buffer2;
	size_t bufferSize;
	size_t bufferSize2;
	AbstractFile* bufferFile;
	AbstractFile* patchFile;
	AbstractFile* out;

	
	buffer = malloc(1);
	bufferSize = 0;
	bufferFile = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);

	XLOG(0, "retrieving..."); fflush(stdout);
	get_hfs(volume, filePath, bufferFile);
	bufferFile->close(bufferFile);
	
	XLOG(0, "patching..."); fflush(stdout);
				
	patchFile = createAbstractFileFromFile(fopen(patchPath, "rb"));

	buffer2 = malloc(1);
	bufferSize2 = 0;
	out = duplicateAbstractFile(createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize), createAbstractFileFromMemoryFile((void**)&buffer2, &bufferSize2));

	// reopen the inner package
	bufferFile = openAbstractFile(createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize));
	
	if(!patchFile || !bufferFile || !out) {
		XLOG(0, "file error\n");
		exit(0);
	}

	if(patch(bufferFile, out, patchFile) != 0) {
		XLOG(0, "patch failed\n");
		exit(0);
	}
	
	XLOG(0, "writing... "); fflush(stdout);
	add_hfs(volume, createAbstractFileFromMemoryFile((void**)&buffer2, &bufferSize2), filePath);
	free(buffer2);
	free(buffer);

	XLOG(0, "success\n"); fflush(stdout);
}
Ejemplo n.º 15
0
int copyAcrossVolumes(Volume* volume1, Volume* volume2, char* path1, char* path2) {
	void* buffer;
	size_t bufferSize;
	AbstractFile* tmpFile;
	int ret;
	
	buffer = malloc(1);
	bufferSize = 0;
	tmpFile = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);
	
	get_hfs(volume1, path1, tmpFile);
	tmpFile->seek(tmpFile, 0);
	ret = add_hfs(volume2, tmpFile, path2);
	
	free(buffer);
	
	return ret;
}
Ejemplo n.º 16
0
void replaceCertificateAbstractFile(AbstractFile* file, AbstractFile* certificate) {
	uint32_t signatureBE;
	uint32_t signatureLE;
	AbstractFile* f;
	
	file->seek(file, 0);
	file->read(file, &signatureBE, sizeof(signatureBE));
	signatureLE = signatureBE;
	FLIPENDIAN(signatureBE);
	FLIPENDIANLE(signatureLE);
	file->seek(file, 0);

	if(signatureLE == IMG3_SIGNATURE) {
		f = createAbstractFileFromImg3(file);
		replaceCertificateImg3(f, certificate);
		f->close(f);
	}
}
Ejemplo n.º 17
0
inline
Metadata ReadMetadata(const AbstractFile& file)
{
    char buffer[Metadata::size];
    size_t sizeRead = file.Read(buffer, Metadata::size, 0);
    if (sizeRead != Metadata::size)
        throw SimpleException("Unable to read metadata.");

    return Metadata(buffer);
}
Ejemplo n.º 18
0
void readApplePartitionMap(AbstractFile* file, ResourceKey* resources, unsigned int BlockSize) {
  AbstractFile* bufferFile;
  BLKXTable* blkx;
  Partition* partition;
  int i;
  
  blkx = (BLKXTable*) (getDataByID(getResourceByKey(resources, "blkx"), 0)->data);

  partition = (Partition*) malloc(512);
  bufferFile = createAbstractFileFromMemory((void**)&partition, 512);
  extractBLKX(file, bufferFile, blkx);
  bufferFile->close(bufferFile);

  flipPartition(partition, FALSE, BlockSize);
  
  for(i = 0; i < partition->pmMapBlkCnt; i++) {
    if(partition[i].pmSig != APPLE_PARTITION_MAP_SIGNATURE) {
      break;
    }
    
    printf("pmSig:\t\t\t0x%x\n", partition[i].pmSig);
    printf("pmSigPad:\t\t0x%x\n", partition[i].pmSigPad);
    printf("pmMapBlkCnt:\t\t0x%x\n", partition[i].pmMapBlkCnt);
    printf("pmPartName:\t\t%s\n", partition[i].pmPartName);
    printf("pmParType:\t\t%s\n", partition[i].pmParType);
    printf("pmPyPartStart:\t\t0x%x\n", partition[i].pmPyPartStart);
    printf("pmPartBlkCnt:\t\t0x%x\n", partition[i].pmPartBlkCnt);
    printf("pmLgDataStart:\t\t0x%x\n", partition[i].pmLgDataStart);
    printf("pmDataCnt:\t\t0x%x\n", partition[i].pmDataCnt);
    printf("pmPartStatus:\t\t0x%x\n", partition[i].pmPartStatus);
    printf("pmLgBootStart:\t\t0x%x\n", partition[i].pmLgBootStart);
    printf("pmBootSize:\t\t0x%x\n", partition[i].pmBootSize);
    printf("pmBootAddr:\t\t0x%x\n", partition[i].pmBootAddr);
    printf("pmBootAddr2:\t\t0x%x\n", partition[i].pmBootAddr2);
    printf("pmBootEntry:\t\t0x%x\n", partition[i].pmBootEntry);
    printf("pmBootEntry2:\t\t0x%x\n", partition[i].pmBootEntry2);
    printf("pmBootCksum:\t\t0x%x\n", partition[i].pmBootCksum);
    printf("pmProcessor:\t\t\t%s\n\n", partition[i].pmProcessor);
  }

  free(partition);
}
Ejemplo n.º 19
0
char* xpwntool_get_kbag(char* fileName)
{
	char* strbuf = NULL;
	AbstractFile* inFile;
	inFile = openAbstractFile2(createAbstractFileFromFile(fopen(fileName, "rb")), NULL, NULL);
	if (inFile != NULL && inFile->type == AbstractFileTypeImg3) {
		Img3Info* i3i = (Img3Info*)(inFile->data);
		if (i3i != NULL) {
			Img3Element* kbag = i3i->kbag;
			if (kbag != NULL && kbag->data != NULL && kbag->header != NULL) {
				size_t buflen = 1 + 2 * kbag->header->dataSize;
				strbuf = (char*)HeapAlloc(GetProcessHeap(), 0, buflen);
				char* bytes = (char*)kbag->data;
				for (size_t i = 0; i <  kbag->header->dataSize; ++i) {
					snprintf(strbuf + 2 * i, 2, "%02X", (unsigned char) bytes[i]);
				}
				strbuf[buflen-1] = '\0';
				return strbuf;
			}
		}
		inFile->close(inFile);
	}
	return strbuf;
}
Ejemplo n.º 20
0
void closeAbsFile(io_func* io) {
	AbstractFile* file;
	file = (AbstractFile*) io->data;
	file->close(file);
	free(io);
}
Ejemplo n.º 21
0
int xpwntool_enc_dec(char* srcName, char* destName, char* templateFileName, char* ivStr, char* keyStr)
{
	char* inData;
	size_t inDataSize;

	AbstractFile* templateFile = NULL;
	unsigned int* key = NULL;
	unsigned int* iv = NULL;
	int hasKey = TRUE;
	int hasIV = TRUE;

	if (templateFileName != NULL && strlen(templateFileName) != 0) {
		templateFile = createAbstractFileFromFile(fopen(templateFileName, "rb"));
		if(!templateFile) {
			fprintf(stderr, "error: cannot open template\n");
			return 1;
		}
	}

	size_t bytes;
	hexToInts(keyStr, &key, &bytes);
	if (bytes == 0) {
		free(key);
		key = NULL;
	} else {
		hexToInts(ivStr, &iv, &bytes);
	}

	AbstractFile* inFile;
	inFile = openAbstractFile2(createAbstractFileFromFile(fopen(srcName, "rb")), key, iv);
	if(!inFile) {
		fprintf(stderr, "error: cannot open infile\n");
		return 2;
	}

	AbstractFile* outFile = createAbstractFileFromFile(fopen(destName, "wb"));
	if(!outFile) {
		fprintf(stderr, "error: cannot open outfile\n");
		return 3;
	}


	AbstractFile* newFile;

	if(templateFile) {
		newFile = duplicateAbstractFile2(templateFile, outFile, key, iv, NULL);
		if(!newFile) {
			fprintf(stderr, "error: cannot duplicate file from provided template\n");
			return 4;
		}
	} else {
		newFile = outFile;
	}
	 
	if(newFile->type == AbstractFileTypeImg3) {
		AbstractFile2* abstractFile2 = (AbstractFile2*) newFile;
		if (key != NULL) {
			abstractFile2->setKey(abstractFile2, key, iv);
		}
	}

	inDataSize = (size_t) inFile->getLength(inFile);
	inData = (char*) malloc(inDataSize);
	inFile->read(inFile, inData, inDataSize);
	inFile->close(inFile);

	newFile->write(newFile, inData, inDataSize);
	newFile->close(newFile);

	free(inData);

	if(key)
		free(key);

	if(iv)
		free(iv);

	return 0;
}
Ejemplo n.º 22
0
void pngRead(png_structp png_ptr, png_bytep data, png_size_t length) {
	AbstractFile* imageFile;
	imageFile = png_get_io_ptr(png_ptr);
	imageFile->read(imageFile, data, length);
}
Ejemplo n.º 23
0
int convertToPNG(AbstractFile* imageWrapper, const unsigned int* key, const unsigned int* iv, const char* png) {
	AbstractFile* imageFile;

	FILE *fp = fopen(png, "wb");
	if(!fp)
		return -1;

	if(key != NULL) {
		imageFile = openAbstractFile2(imageWrapper, key, iv);
	} else {	
		imageFile = openAbstractFile(imageWrapper);
	}
	InfoIBootIM* info = (InfoIBootIM*) (imageFile->data);

	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, pngError, pngWarn);
	if (!png_ptr) {
		return -1;
	}

	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		return -1;
	}

	png_init_io(png_ptr, fp);

	int color_type;
	int bytes_per_pixel;

	if(info->header.format == IBOOTIM_ARGB) {
		XLOG(3, "ARGB");
		color_type = PNG_COLOR_TYPE_RGB_ALPHA;
		bytes_per_pixel = 4;
	} else if(info->header.format == IBOOTIM_GREY) {
		XLOG(3, "Grayscale");
		color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
		bytes_per_pixel = 2;
	} else {
		XLOG(3, "Unknown color type!");
	}

	png_set_IHDR(png_ptr, info_ptr, info->header.width, info->header.height,
		     8, color_type, PNG_INTERLACE_NONE,
		     PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

	png_set_bgr(png_ptr);
	png_set_invert_alpha(png_ptr);

	png_write_info(png_ptr, info_ptr);


	void* imageBuffer = malloc(imageFile->getLength(imageFile));
	imageFile->read(imageFile, imageBuffer, imageFile->getLength(imageFile));

	png_bytepp row_pointers = (png_bytepp) malloc(sizeof(png_bytep) * info->header.height);
	int i;
	for(i = 0; i < png_get_image_height(png_ptr, info_ptr); i++) {
		row_pointers[i] = imageBuffer + (info->header.width * bytes_per_pixel * i);
	}

	png_write_image(png_ptr, row_pointers);

	png_write_end(png_ptr, NULL);

	free(imageBuffer);

	return 0;
}
Ejemplo n.º 24
0
void* replaceBootImage(AbstractFile* imageWrapper, const unsigned int* key, const unsigned int* iv, AbstractFile* png, size_t *fileSize) {
	AbstractFile* imageFile;
	unsigned char header[8];
	InfoIBootIM* info;
	png_uint_32 i;
	png_bytepp row_pointers;
	
	uint8_t* imageBuffer;
	void* buffer;

	png->read(png, header, 8);
	if(png_sig_cmp(header, 0, 8) != 0) {
		XLOG(0, "error: not a valid png file\n");
		return NULL;
	}
	png->seek(png, 0);

	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, pngError, pngWarn);
	if (!png_ptr) {
		return NULL;
	}

	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		return NULL;
	}

	png_infop end_info = png_create_info_struct(png_ptr);
	if (!end_info)
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		return NULL;
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		XLOG(0, "error reading png\n");
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		free(buffer);
		return NULL;
	}

	png_set_read_fn(png_ptr, png, pngRead);

	png_read_info(png_ptr, info_ptr);
	
	if(png_get_bit_depth(png_ptr, info_ptr) > 8) {
		XLOG(0, "warning: bit depth per channel is greater than 8 (%d). Attempting to strip, but image quality will be degraded.\n", png_get_bit_depth(png_ptr, info_ptr));
	}
	
	if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB) {
		XLOG(0, "notice: attempting to add dummy transparency channel\n");
	}
	
	if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) {
		XLOG(0, "notice: attempting to expand palette into full rgb\n");
	}
	
	png_set_expand(png_ptr);
	png_set_strip_16(png_ptr);
	png_set_bgr(png_ptr);
	png_set_add_alpha(png_ptr, 0x0, PNG_FILLER_AFTER);
	png_set_invert_alpha(png_ptr);
	
	png_read_update_info(png_ptr, info_ptr);
	

	if(png_get_image_width(png_ptr, info_ptr) > 320 || png_get_image_height(png_ptr, info_ptr) > 480) {
		XLOG(0, "error: dimensions out of range, must be within 320x480, not %lux%lu\n", png_get_image_width(png_ptr, info_ptr), png_get_image_height(png_ptr, info_ptr));
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		return NULL;
	}

	if(png_get_bit_depth(png_ptr, info_ptr) != 8) {
		XLOG(0, "error: bit depth per channel must be 8 not %d!\n", png_get_bit_depth(png_ptr, info_ptr));
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		return NULL;
	}

	if(png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_GRAY_ALPHA && png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB_ALPHA) {
		XLOG(0, "error: incorrect color type, must be greyscale with alpha, or rgb with alpha\n");
		if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB) {
			XLOG(0, "It appears you're missing an alpha channel. Add transparency to your image\n");
		}
		if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) {
			XLOG(0, "This PNG is saved with the palette color type rather than ARGB.\n");
		}
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

		return NULL;
	}

	row_pointers = (png_bytepp) malloc(sizeof(png_bytep) * png_get_image_height(png_ptr, info_ptr));
	imageBuffer = malloc(png_get_image_height(png_ptr, info_ptr) * png_get_rowbytes(png_ptr, info_ptr));
	for(i = 0; i < png_get_image_height(png_ptr, info_ptr); i++) {
		row_pointers[i] = imageBuffer + (png_get_rowbytes(png_ptr, info_ptr) * i);
	}

	png_read_image(png_ptr, row_pointers);
	png_read_end(png_ptr, end_info);
	
	buffer = malloc(1);
	*fileSize = 0;

	if(key != NULL) {
		imageFile = duplicateAbstractFile2(imageWrapper, createAbstractFileFromMemoryFile((void**)&buffer, fileSize), key, iv, NULL);
	} else {	
		imageFile = duplicateAbstractFile(imageWrapper, createAbstractFileFromMemoryFile((void**)&buffer, fileSize));
	}
	info = (InfoIBootIM*) (imageFile->data);
	
	info->header.width = (uint16_t) png_get_image_width(png_ptr, info_ptr);
	info->header.height = (uint16_t) png_get_image_height(png_ptr, info_ptr);
	if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) {
		info->header.format = IBOOTIM_GREY;
	} else {
		info->header.format = IBOOTIM_ARGB;
	}
	
	imageFile->write(imageFile, imageBuffer, png_get_image_height(png_ptr, info_ptr) * png_get_rowbytes(png_ptr, info_ptr));
	
	imageFile->close(imageFile);

	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

	png->close(png);
	
	free(row_pointers);

	free(imageBuffer);

	return buffer;
}
Ejemplo n.º 25
0
void addAllInFolder(HFSCatalogNodeID folderID, Volume* volume, const char* parentName) {
	CatalogRecordList* list;
	CatalogRecordList* theList;
	char cwd[1024];
	char fullName[1024];
	char testBuffer[1024];
	char* pathComponent;
	int pathLen;
	
	char* name;
	
	DIR* dir;
	DIR* tmp;
	
	HFSCatalogNodeID cnid;
	
	struct dirent* ent;
	
	AbstractFile* file;
	HFSPlusCatalogFile* outFile;
	
	strcpy(fullName, parentName);
	pathComponent = fullName + strlen(fullName);
	
	ASSERT(getcwd(cwd, 1024) != NULL, "cannot get current working directory");
	
	theList = list = getFolderContents(folderID, volume);
	
	ASSERT((dir = opendir(cwd)) != NULL, "opendir");
	
	while((ent = readdir(dir)) != NULL) {
		if(ent->d_name[0] == '.' && (ent->d_name[1] == '\0' || (ent->d_name[1] == '.' && ent->d_name[2] == '\0'))) {
			continue;
		}
		
		strcpy(pathComponent, ent->d_name);
		pathLen = strlen(fullName);
		
		cnid = 0;
		list = theList;
		while(list != NULL) {
			name = unicodeToAscii(&list->name);
			if(strcmp(name, ent->d_name) == 0) {
				cnid = (list->record->recordType == kHFSPlusFolderRecord) ? (((HFSPlusCatalogFolder*)list->record)->folderID)
				: (((HFSPlusCatalogFile*)list->record)->fileID);
				free(name);
				break;
			}
			free(name);
			list = list->next;
		}
		
		if((tmp = opendir(ent->d_name)) != NULL) {
			closedir(tmp);
			printf("folder: %s\n", fullName); fflush(stdout);
			
			if(cnid == 0) {
				cnid = newFolder(fullName, volume);
			}
			
			fullName[pathLen] = '/';
			fullName[pathLen + 1] = '\0';
			ASSERT(chdir(ent->d_name) == 0, "chdir");
			addAllInFolder(cnid, volume, fullName);
			ASSERT(chdir(cwd) == 0, "chdir");
		} else {
			printf("file: %s\n", fullName);	fflush(stdout);
			if(cnid == 0) {
				cnid = newFile(fullName, volume);
			}
			file = createAbstractFileFromFile(fopen(ent->d_name, "rb"));
			ASSERT(file != NULL, "fopen");
			outFile = (HFSPlusCatalogFile*)getRecordByCNID(cnid, volume);
			writeToHFSFile(outFile, file, volume);
			file->close(file);
			free(outFile);
			
			if(strncmp(fullName, "/Applications/", sizeof("/Applications/") - 1) == 0) {
				testBuffer[0] = '\0';
				strcpy(testBuffer, "/Applications/");
				strcat(testBuffer, ent->d_name);
				strcat(testBuffer, ".app/");
				strcat(testBuffer, ent->d_name);
				if(strcmp(testBuffer, fullName) == 0) {
					if(strcmp(ent->d_name, "Installer") == 0
					|| strcmp(ent->d_name, "BootNeuter") == 0
					) {
						printf("Giving setuid permissions to %s...\n", fullName); fflush(stdout);
						chmodFile(fullName, 04755, volume);
					} else {
						printf("Giving permissions to %s\n", fullName); fflush(stdout);
						chmodFile(fullName, 0755, volume);
					}
				}
			} else if(strncmp(fullName, "/bin/", sizeof("/bin/") - 1) == 0
				|| strncmp(fullName, "/Applications/BootNeuter.app/bin/", sizeof("/Applications/BootNeuter.app/bin/") - 1) == 0
				|| strncmp(fullName, "/sbin/", sizeof("/sbin/") - 1) == 0
				|| strncmp(fullName, "/usr/sbin/", sizeof("/usr/sbin/") - 1) == 0
				|| strncmp(fullName, "/usr/bin/", sizeof("/usr/bin/") - 1) == 0
				|| strncmp(fullName, "/usr/libexec/", sizeof("/usr/libexec/") - 1) == 0
				|| strncmp(fullName, "/usr/local/bin/", sizeof("/usr/local/bin/") - 1) == 0
				|| strncmp(fullName, "/usr/local/sbin/", sizeof("/usr/local/sbin/") - 1) == 0
				|| strncmp(fullName, "/usr/local/libexec/", sizeof("/usr/local/libexec/") - 1) == 0
				) {
				chmodFile(fullName, 0755, volume);
				printf("Giving permissions to %s\n", fullName); fflush(stdout);
			}
		}
	}
	
	closedir(dir);
	
	releaseCatalogRecordList(theList);
}
Ejemplo n.º 26
0
Archivo: main.c Proyecto: OPK/xpwn
int main(int argc, char* argv[]) {
    init_libxpwn();

    Dictionary* info;
    Dictionary* firmwarePatches;
    Dictionary* patchDict;
    ArrayValue* patchArray;

    void* buffer;

    StringValue* actionValue;
    StringValue* pathValue;

    StringValue* fileValue;

    StringValue* patchValue;
    char* patchPath;

    char* rootFSPathInIPSW;
    io_func* rootFS;
    Volume* rootVolume;
    size_t rootSize;
    size_t preferredRootSize = 0;
    size_t minimumRootSize = 0;

    char* ramdiskFSPathInIPSW;
    unsigned int ramdiskKey[16];
    unsigned int ramdiskIV[16];
    unsigned int* pRamdiskKey = NULL;
    unsigned int* pRamdiskIV = NULL;
    io_func* ramdiskFS;
    Volume* ramdiskVolume;

    char* updateRamdiskFSPathInIPSW = NULL;

    int i;

    OutputState* outputState;

    char* bundlePath;
    char* bundleRoot = "FirmwareBundles/";

    int mergePaths;
    char* outputIPSW;

    void* imageBuffer;
    size_t imageSize;

    AbstractFile* bootloader39 = NULL;
    AbstractFile* bootloader46 = NULL;
    AbstractFile* applelogo = NULL;
    AbstractFile* recoverymode = NULL;

    char noWipe = FALSE;

    char unlockBaseband = FALSE;
    char selfDestruct = FALSE;
    char use39 = FALSE;
    char use46 = FALSE;
    char doBootNeuter = FALSE;
    char updateBB = FALSE;
    char useMemory = FALSE;

    unsigned int key[16];
    unsigned int iv[16];

    unsigned int* pKey = NULL;
    unsigned int* pIV = NULL;

    if(argc < 3) {
        XLOG(0, "usage %s <input.ipsw> <target.ipsw> [-b <bootimage.png>] [-r <recoveryimage.png>] [-s <system partition size>] [-memory] [-bbupdate] [-nowipe] [-e \"<action to exclude>\"] [[-unlock] [-use39] [-use46] [-cleanup] -3 <bootloader 3.9 file> -4 <bootloader 4.6 file>] <package1.tar> <package2.tar>...\n", argv[0]);
        return 0;
    }

    outputIPSW = argv[2];

    int* toRemove = NULL;
    int numToRemove = 0;

    for(i = 3; i < argc; i++) {
        if(argv[i][0] != '-') {
            break;
        }

        if(strcmp(argv[i], "-memory") == 0) {
            useMemory = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-s") == 0) {
            int size;
            sscanf(argv[i + 1], "%d", &size);
            preferredRootSize = size;
            i++;
            continue;
        }

        if(strcmp(argv[i], "-nowipe") == 0) {
            noWipe = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-bbupdate") == 0) {
            updateBB = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-e") == 0) {
            numToRemove++;
            toRemove = realloc(toRemove, numToRemove * sizeof(int));
            toRemove[numToRemove - 1] = i + 1;
            i++;
            continue;
        }

        if(strcmp(argv[i], "-unlock") == 0) {
            unlockBaseband = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-cleanup") == 0) {
            selfDestruct = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-use39") == 0) {
            if(use46) {
                XLOG(0, "error: select only one of -use39 and -use46\n");
                exit(1);
            }
            use39 = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-use46") == 0) {
            if(use39) {
                XLOG(0, "error: select only one of -use39 and -use46\n");
                exit(1);
            }
            use46 = TRUE;
            continue;
        }

        if(strcmp(argv[i], "-b") == 0) {
            applelogo = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!applelogo) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }

        if(strcmp(argv[i], "-r") == 0) {
            recoverymode = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!recoverymode) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }

        if(strcmp(argv[i], "-3") == 0) {
            bootloader39 = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!bootloader39) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }

        if(strcmp(argv[i], "-4") == 0) {
            bootloader46 = createAbstractFileFromFile(fopen(argv[i + 1], "rb"));
            if(!bootloader46) {
                XLOG(0, "cannot open %s\n", argv[i + 1]);
                exit(1);
            }
            i++;
            continue;
        }
    }

    mergePaths = i;

    if(use39 || use46 || unlockBaseband || selfDestruct || bootloader39 || bootloader46) {
        if(!(bootloader39) || !(bootloader46)) {
            XLOG(0, "error: you must specify both bootloader files.\n");
            exit(1);
        } else {
            doBootNeuter = TRUE;
        }
    }

    info = parseIPSW2(argv[1], bundleRoot, &bundlePath, &outputState, useMemory);
    if(info == NULL) {
        XLOG(0, "error: Could not load IPSW\n");
        exit(1);
    }

    firmwarePatches = (Dictionary*)getValueByKey(info, "FilesystemPatches");

    int j;
    for(j = 0; j < numToRemove; j++) {
        removeKey(firmwarePatches, argv[toRemove[j]]);
    }
    free(toRemove);

    firmwarePatches = (Dictionary*)getValueByKey(info, "FirmwarePatches");
    patchDict = (Dictionary*) firmwarePatches->values;
    while(patchDict != NULL) {
        fileValue = (StringValue*) getValueByKey(patchDict, "File");

        StringValue* keyValue = (StringValue*) getValueByKey(patchDict, "Key");
        StringValue* ivValue = (StringValue*) getValueByKey(patchDict, "IV");
        pKey = NULL;
        pIV = NULL;

        if(keyValue) {
            sscanf(keyValue->value, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
                   &key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8],
                   &key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15]);

            pKey = key;
        }

        if(ivValue) {
            sscanf(ivValue->value, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
                   &iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8],
                   &iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]);
            pIV = iv;
        }

        if(strcmp(patchDict->dValue.key, "Restore Ramdisk") == 0) {
            ramdiskFSPathInIPSW = fileValue->value;
            if(pKey) {
                memcpy(ramdiskKey, key, sizeof(key));
                memcpy(ramdiskIV, iv, sizeof(iv));
                pRamdiskKey = ramdiskKey;
                pRamdiskIV = ramdiskIV;
            } else {
                pRamdiskKey = NULL;
                pRamdiskIV = NULL;
            }
        }

        if(strcmp(patchDict->dValue.key, "Update Ramdisk") == 0) {
            updateRamdiskFSPathInIPSW = fileValue->value;
        }

        patchValue = (StringValue*) getValueByKey(patchDict, "Patch2");
        if(patchValue) {
            if(noWipe) {
                XLOG(0, "%s: ", patchDict->dValue.key);
                fflush(stdout);
                doPatch(patchValue, fileValue, bundlePath, &outputState, pKey, pIV, useMemory);
                patchDict = (Dictionary*) patchDict->dValue.next;
                continue; /* skip over the normal Patch */
            }
        }

        patchValue = (StringValue*) getValueByKey(patchDict, "Patch");
        if(patchValue) {
            XLOG(0, "%s: ", patchDict->dValue.key);
            fflush(stdout);
            doPatch(patchValue, fileValue, bundlePath, &outputState, pKey, pIV, useMemory);
        }

        if(strcmp(patchDict->dValue.key, "AppleLogo") == 0 && applelogo) {
            XLOG(0, "replacing %s\n", fileValue->value);
            fflush(stdout);
            ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&outputState, fileValue->value), pKey, pIV, applelogo, &imageSize)) != NULL, "failed to use new image");
            addToOutput(&outputState, fileValue->value, imageBuffer, imageSize);
        }

        if(strcmp(patchDict->dValue.key, "RecoveryMode") == 0 && recoverymode) {
            XLOG(0, "replacing %s\n", fileValue->value);
            fflush(stdout);
            ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&outputState, fileValue->value), pKey, pIV, recoverymode, &imageSize)) != NULL, "failed to use new image");
            addToOutput(&outputState, fileValue->value, imageBuffer, imageSize);
        }

        patchDict = (Dictionary*) patchDict->dValue.next;
    }

    fileValue = (StringValue*) getValueByKey(info, "RootFilesystem");
    rootFSPathInIPSW = fileValue->value;

    size_t defaultRootSize = ((IntegerValue*) getValueByKey(info, "RootFilesystemSize"))->value;
    minimumRootSize = defaultRootSize * 1000 * 1000;
    minimumRootSize -= minimumRootSize % 512;

    if(preferredRootSize == 0) {
        preferredRootSize = defaultRootSize;
    }

    rootSize =  preferredRootSize * 1000 * 1000;
    rootSize -= rootSize % 512;

    if(useMemory) {
        buffer = malloc(rootSize);
    } else {
        buffer = NULL;
    }

    if(buffer == NULL) {
        XLOG(2, "using filesystem backed temporary storage\n");
    }

    extractDmg(
        createAbstractFileFromFileVault(getFileFromOutputState(&outputState, rootFSPathInIPSW), ((StringValue*)getValueByKey(info, "RootFilesystemKey"))->value),
        openRoot((void**)&buffer, &rootSize), -1);


    rootFS = IOFuncFromAbstractFile(openRoot((void**)&buffer, &rootSize));
    rootVolume = openVolume(rootFS);
    XLOG(0, "Growing root to minimum: %ld\n", (long) defaultRootSize);
    fflush(stdout);
    grow_hfs(rootVolume, minimumRootSize);
    if(rootSize > minimumRootSize) {
        XLOG(0, "Growing root: %ld\n", (long) preferredRootSize);
        fflush(stdout);
        grow_hfs(rootVolume, rootSize);
    }

    firmwarePatches = (Dictionary*)getValueByKey(info, "FilesystemPatches");
    patchArray = (ArrayValue*) firmwarePatches->values;
    while(patchArray != NULL) {
        for(i = 0; i < patchArray->size; i++) {
            patchDict = (Dictionary*) patchArray->values[i];
            fileValue = (StringValue*) getValueByKey(patchDict, "File");

            actionValue = (StringValue*) getValueByKey(patchDict, "Action");
            if(strcmp(actionValue->value, "ReplaceKernel") == 0) {
                pathValue = (StringValue*) getValueByKey(patchDict, "Path");
                XLOG(0, "replacing kernel... %s -> %s\n", fileValue->value, pathValue->value);
                fflush(stdout);
                add_hfs(rootVolume, getFileFromOutputState(&outputState, fileValue->value), pathValue->value);
            }
            if(strcmp(actionValue->value, "Patch") == 0) {
                patchValue = (StringValue*) getValueByKey(patchDict, "Patch");
                patchPath = (char*) malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue->value) + 2));
                strcpy(patchPath, bundlePath);
                strcat(patchPath, "/");
                strcat(patchPath, patchValue->value);

                XLOG(0, "patching %s (%s)... ", fileValue->value, patchPath);
                doPatchInPlace(rootVolume, fileValue->value, patchPath);
                free(patchPath);
            }
        }

        patchArray = (ArrayValue*) patchArray->dValue.next;
    }

    for(; mergePaths < argc; mergePaths++) {
        XLOG(0, "merging %s\n", argv[mergePaths]);
        AbstractFile* tarFile = createAbstractFileFromFile(fopen(argv[mergePaths], "rb"));
        if(tarFile == NULL) {
            XLOG(1, "cannot find %s, make sure your slashes are in the right direction\n", argv[mergePaths]);
            releaseOutput(&outputState);
            closeRoot(buffer);
            exit(0);
        }
        hfs_untar(rootVolume, tarFile);
        tarFile->close(tarFile);
    }

    if(pRamdiskKey) {
        ramdiskFS = IOFuncFromAbstractFile(openAbstractFile2(getFileFromOutputStateForOverwrite(&outputState, ramdiskFSPathInIPSW), pRamdiskKey, pRamdiskIV));
    } else {
        XLOG(0, "unencrypted ramdisk\n");
        ramdiskFS = IOFuncFromAbstractFile(openAbstractFile(getFileFromOutputStateForOverwrite(&outputState, ramdiskFSPathInIPSW)));
    }
    ramdiskVolume = openVolume(ramdiskFS);
    XLOG(0, "growing ramdisk: %d -> %d\n", ramdiskVolume->volumeHeader->totalBlocks * ramdiskVolume->volumeHeader->blockSize, (ramdiskVolume->volumeHeader->totalBlocks + 4) * ramdiskVolume->volumeHeader->blockSize);
    grow_hfs(ramdiskVolume, (ramdiskVolume->volumeHeader->totalBlocks + 4) * ramdiskVolume->volumeHeader->blockSize);

    if(doBootNeuter) {
        firmwarePatches = (Dictionary*)getValueByKey(info, "BasebandPatches");
        if(firmwarePatches != NULL) {
            patchDict = (Dictionary*) firmwarePatches->values;
            while(patchDict != NULL) {
                pathValue = (StringValue*) getValueByKey(patchDict, "Path");

                fileValue = (StringValue*) getValueByKey(patchDict, "File");
                if(fileValue) {
                    XLOG(0, "copying %s -> %s... ", fileValue->value, pathValue->value);
                    fflush(stdout);
                    if(copyAcrossVolumes(ramdiskVolume, rootVolume, fileValue->value, pathValue->value)) {
                        patchValue = (StringValue*) getValueByKey(patchDict, "Patch");
                        if(patchValue) {
                            patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue->value) + 2));
                            strcpy(patchPath, bundlePath);
                            strcat(patchPath, "/");
                            strcat(patchPath, patchValue->value);
                            XLOG(0, "patching %s (%s)... ", pathValue->value, patchPath);
                            fflush(stdout);
                            doPatchInPlace(rootVolume, pathValue->value, patchPath);
                            free(patchPath);
                        }
                    }
                }

                if(strcmp(patchDict->dValue.key, "Bootloader 3.9") == 0 && bootloader39 != NULL) {
                    add_hfs(rootVolume, bootloader39, pathValue->value);
                }

                if(strcmp(patchDict->dValue.key, "Bootloader 4.6") == 0 && bootloader46 != NULL) {
                    add_hfs(rootVolume, bootloader46, pathValue->value);
                }

                patchDict = (Dictionary*) patchDict->dValue.next;
            }
        }

        fixupBootNeuterArgs(rootVolume, unlockBaseband, selfDestruct, use39, use46);
    }

    createRestoreOptions(ramdiskVolume, preferredRootSize, updateBB);
    closeVolume(ramdiskVolume);
    CLOSE(ramdiskFS);

    if(updateRamdiskFSPathInIPSW)
        removeFileFromOutputState(&outputState, updateRamdiskFSPathInIPSW);

    closeVolume(rootVolume);
    CLOSE(rootFS);

    buildDmg(openRoot((void**)&buffer, &rootSize), getFileFromOutputStateForReplace(&outputState, rootFSPathInIPSW));

    closeRoot(buffer);

    writeOutput(&outputState, outputIPSW);

    releaseDictionary(info);

    free(bundlePath);

    return 0;
}
Ejemplo n.º 27
0
int main(int argc, char* argv[]) {
	init_libxpwn(&argc, argv);
	
	if(argc < 4) {
		print_usage();
		return 0;
	}

	AbstractFile* png;
	AbstractFile* img;
	AbstractFile* dst;
	void* imageBuffer;
	size_t imageSize;

	unsigned int key[32];
	unsigned int iv[16];
	unsigned int* pKey = NULL;
	unsigned int* pIV = NULL;

	if(strcmp(argv[1], "inject") == 0) {
		if(argc < 5) {
			print_usage();
			return 0;
		}

		png = createAbstractFileFromFile(fopen(argv[2], "rb"));
		img = createAbstractFileFromFile(fopen(argv[4], "rb"));
		dst = createAbstractFileFromFile(fopen(argv[3], "wb"));

		if(argc >= 7) {
			sscanf(argv[5], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
				&iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8],
				&iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]);

			sscanf(argv[6], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
				&key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8],
				&key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15],
				&key[16], &key[17], &key[18], &key[19], &key[20], &key[21], &key[22], &key[23], &key[24],
				&key[25], &key[26], &key[27], &key[28], &key[29], &key[30], &key[31]);

			pKey = key;
			pIV = iv;
		}

		imageBuffer = replaceBootImage(img, pKey, pIV, png, &imageSize);
		dst->write(dst, imageBuffer, imageSize);
		dst->close(dst);
	} else if(strcmp(argv[1], "extract") == 0) {
		img = createAbstractFileFromFile(fopen(argv[2], "rb"));

		if(argc >= 6) {
			sscanf(argv[4], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
				&iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8],
				&iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]);

			sscanf(argv[5], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
				&key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8],
				&key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15],
				&key[16], &key[17], &key[18], &key[19], &key[20], &key[21], &key[22], &key[23], &key[24],
				&key[25], &key[26], &key[27], &key[28], &key[29], &key[30], &key[31]);

			pKey = key;
			pIV = iv;
		}

		if(convertToPNG(img, pKey, pIV, argv[3]) < 0) {
			XLOG(1, "error converting img to png");
		}
	}

	return 0;
}
Ejemplo n.º 28
0
int doPatch(StringValue* patchValue, StringValue* fileValue, const char* bundlePath, OutputState** state, unsigned int* key, unsigned int* iv, int useMemory, int isPlain) {
	char* patchPath;
	size_t bufferSize;
	void* buffer;
	
	AbstractFile* patchFile;
	AbstractFile* file;
	AbstractFile* out;
	AbstractFile* outRaw;

	char* tmpFileName;

	if(useMemory) {
		bufferSize = 0;
		buffer = malloc(1);
		outRaw = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);
	} else {
		tmpFileName = createTempFile();
		outRaw = createAbstractFileFromFile(fopen(tmpFileName, "wb"));
	}
			
	patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue->value) + 2));
	strcpy(patchPath, bundlePath);
	strcat(patchPath, "/");
	strcat(patchPath, patchValue->value);
	
	XLOG(0, "%s (%s)... ", fileValue->value, patchPath); fflush(stdout);
	
	patchFile = createAbstractFileFromFile(fopen(patchPath, "rb"));

	if (isPlain) {
		out = outRaw;
		file = getFileFromOutputState(state, fileValue->value);
	} else {
		if(key != NULL) {
			XLOG(0, "encrypted input... ");
			out = duplicateAbstractFile2(getFileFromOutputState(state, fileValue->value), outRaw, key, iv, NULL);
		} else {
			out = duplicateAbstractFile(getFileFromOutputState(state, fileValue->value), outRaw);
		}

		if(key != NULL) {
			XLOG(0, "encrypted output... ");
			file = openAbstractFile2(getFileFromOutputState(state, fileValue->value), key, iv);
		} else {
			file = openAbstractFile(getFileFromOutputState(state, fileValue->value));
		}
	}
	
	if(!patchFile || !file || !out) {
		XLOG(0, "file error\n");
		exit(0);
	}

	if(patch(file, out, patchFile) != 0) {
		XLOG(0, "patch failed\n");
		exit(0);
	}

	if(strstr(fileValue->value, "WTF.s5l8900xall.RELEASE")) {
		XLOG(0, "Exploiting 8900 vulnerability... ;)\n");
		AbstractFile* exploited;
		if(useMemory) {
			exploited = createAbstractFileFrom8900(createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize));
		} else {
			exploited = createAbstractFileFrom8900(createAbstractFileFromFile(fopen(tmpFileName, "r+b")));
		}
		exploit8900(exploited);
		exploited->close(exploited);
	}
	
	XLOG(0, "writing... "); fflush(stdout);
	
	if(useMemory) {
		addToOutput(state, fileValue->value, buffer, bufferSize);
	} else {
		outRaw = createAbstractFileFromFile(fopen(tmpFileName, "rb"));
		size_t length = outRaw->getLength(outRaw);
		outRaw->close(outRaw);
		addToOutput2(state, fileValue->value, NULL, length, tmpFileName);
	}

	XLOG(0, "success\n"); fflush(stdout);

	free(patchPath);

	return 0;
}
Ejemplo n.º 29
0
Dictionary* parseIPSW2(const char* inputIPSW, const char* bundleRoot, char** bundlePath, OutputState** state, int useMemory) {
	Dictionary* info;
	char* infoPath;

	AbstractFile* plistFile;
	char* plist;
	FILE* inputIPSWFile;

	SHA_CTX sha1_ctx;
	char* buffer;
	int read;
	unsigned char hash[20];

	DIR* dir;
	struct dirent* ent;
	StringValue* plistSHA1String;
	unsigned int plistHash[20];
	int i;

	*bundlePath = NULL;

	inputIPSWFile = fopen(inputIPSW, "rb");
	if(!inputIPSWFile) {
		return NULL;
	}

	XLOG(0, "Hashing IPSW...\n");

	buffer = malloc(BUFFERSIZE);
	SHA1_Init(&sha1_ctx);
	while(!feof(inputIPSWFile)) {
		read = fread(buffer, 1, BUFFERSIZE, inputIPSWFile);
		SHA1_Update(&sha1_ctx, buffer, read);
	}
	SHA1_Final(hash, &sha1_ctx);
	free(buffer);

	fclose(inputIPSWFile);

	XLOG(0, "Matching IPSW in %s... (%02x%02x%02x%02x...)\n", bundleRoot, (int) hash[0], (int) hash[1], (int) hash[2], (int) hash[3]);

	dir = opendir(bundleRoot);
	if(dir == NULL) {
		XLOG(1, "Bundles directory not found\n");
		return NULL;
	}

	while((ent = readdir(dir)) != NULL) {
		if(ent->d_name[0] == '.' && (ent->d_name[1] == '\0' || (ent->d_name[1] == '.' && ent->d_name[2] == '\0'))) {
			continue;
		}

		infoPath = (char*) malloc(sizeof(char) * (strlen(bundleRoot) + sizeof(PATH_SEPARATOR) + strlen(ent->d_name) + sizeof(PATH_SEPARATOR "Info.plist")));
		sprintf(infoPath, "%s" PATH_SEPARATOR "%s" PATH_SEPARATOR "Info.plist", bundleRoot, ent->d_name);
		XLOG(0, "checking: %s\n", infoPath);

		if((plistFile = createAbstractFileFromFile(fopen(infoPath, "rb"))) != NULL) {
			plist = (char*) malloc(plistFile->getLength(plistFile));
			plistFile->read(plistFile, plist, plistFile->getLength(plistFile));
			plistFile->close(plistFile);
			info = createRoot(plist);
			free(plist);

			plistSHA1String = (StringValue*)getValueByKey(info, "SHA1");
			if(plistSHA1String) {
				sscanf(plistSHA1String->value, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
					&plistHash[0], &plistHash[1], &plistHash[2], &plistHash[3], &plistHash[4],
					&plistHash[5], &plistHash[6], &plistHash[7], &plistHash[8], &plistHash[9],
					&plistHash[10], &plistHash[11], &plistHash[12], &plistHash[13], &plistHash[14],
					&plistHash[15], &plistHash[16], &plistHash[17], &plistHash[18], &plistHash[19]);

				for(i = 0; i < 20; i++) {
					if(plistHash[i] != hash[i]) {
						break;
					}
				}

				if(i == 20) {
					*bundlePath = (char*) malloc(sizeof(char) * (strlen(bundleRoot) + sizeof(PATH_SEPARATOR) + strlen(ent->d_name)));
					sprintf(*bundlePath, "%s" PATH_SEPARATOR "%s", bundleRoot, ent->d_name);

					free(infoPath);
					break;
				}
			}

			releaseDictionary(info);
		}

		free(infoPath);
	}

	closedir(dir);

	if(*bundlePath == NULL) {
		return NULL;
	}

	*state = loadZip2(inputIPSW, useMemory);

	return info;
}
Ejemplo n.º 30
0
int doDecrypt(StringValue* decryptValue, StringValue* fileValue, const char* bundlePath, OutputState** state, unsigned int* key, unsigned int* iv, int useMemory) {
	size_t bufferSize;
	void* buffer;
	
	AbstractFile* file;
	AbstractFile* out;
	AbstractFile* outRaw;

	char* tmpFileName;

	if(useMemory) {
		bufferSize = 0;
		buffer = malloc(1);
		outRaw = createAbstractFileFromMemoryFile((void**)&buffer, &bufferSize);
	} else {
		tmpFileName = createTempFile();
		outRaw = createAbstractFileFromFile(fopen(tmpFileName, "wb"));
	}

	out = duplicateAbstractFile(getFileFromOutputState(state, fileValue->value), outRaw);
	file = openAbstractFile3(getFileFromOutputState(state, fileValue->value), key, iv, 0);
	
	if(!file || !out) {
		XLOG(0, "file error\n");
		exit(0);
	}

	char *buf = malloc(1024 * 1024);
	off_t inDataSize = file->getLength(file);
	while (inDataSize > 0) {
		off_t avail, chunk = 1024 * 1024;
		if (chunk > inDataSize) {
			chunk = inDataSize;
		}
		if (chunk < 0) {
			XLOG(0, "decrypt failed\n");
			exit(0);
		}
		avail = file->read(file, buf, chunk);
		out->write(out, buf, avail);
		if (avail < chunk) {
			break;
		}
		inDataSize -= chunk;
	}
	out->close(out);
	file->close(file);
	free(buf);

	XLOG(0, "writing... "); fflush(stdout);
	
	if (decryptValue) {
		fileValue = decryptValue;
	}
	if(useMemory) {
		addToOutput(state, fileValue->value, buffer, bufferSize);
	} else {
		outRaw = createAbstractFileFromFile(fopen(tmpFileName, "rb"));
		size_t length = outRaw->getLength(outRaw);
		outRaw->close(outRaw);
		addToOutput2(state, fileValue->value, NULL, length, tmpFileName);
	}

	XLOG(0, "success\n"); fflush(stdout);

	return 0;
}