예제 #1
0
파일: img3.c 프로젝트: nlog2n/xpwntool-lite
void do24kpwn(Img3Info* info, Img3Element* element, off_t curPos, const uint8_t* overflow, size_t overflow_size, const uint8_t* payload, size_t payload_size)
{
	off_t sizeRequired = (0x24000 + overflow_size) - curPos;
	off_t dataRequired = sizeRequired - sizeof(AppleImg3Header);
	element->data = realloc(element->data, dataRequired);
	memset(((uint8_t*)element->data) + element->header->dataSize, 0, dataRequired - element->header->dataSize);
	uint32_t overflowOffset = 0x24000 - (curPos + sizeof(AppleImg3Header));
	uint32_t payloadOffset = 0x23000 - (curPos + sizeof(AppleImg3Header));

	memcpy(((uint8_t*)element->data) + overflowOffset, overflow, overflow_size);
	memcpy(((uint8_t*)element->data) + payloadOffset, payload, payload_size);

	uint32_t* i;
	for(i = (uint32_t*)(((uint8_t*)element->data) + payloadOffset);
			i < (uint32_t*)(((uint8_t*)element->data) + payloadOffset + payload_size);
			i++) {
		uint32_t candidate = *i;
		FLIPENDIANLE(candidate);
		if(candidate == 0xDDCCBBAA) {
			candidate = info->replaceDWord;
			FLIPENDIANLE(candidate);
			*i = candidate;
			break;
		}
	}

	element->header->size = sizeRequired;
	element->header->dataSize = dataRequired;
}
예제 #2
0
파일: ibootim.c 프로젝트: jevinskie/xpwn
void flipIBootIMHeader(IBootIMHeader* header) {
	FLIPENDIANLE(header->unknown);
	FLIPENDIANLE(header->compression_type);
	FLIPENDIANLE(header->format);
	FLIPENDIANLE(header->width);
	FLIPENDIANLE(header->height);
}
예제 #3
0
void flipHFSPlusCmpfEnd(HFSPlusCmpfEnd* data) {
	FLIPENDIAN(data->unk1);
	FLIPENDIAN(data->unk2);
	FLIPENDIAN(data->unk3);
	FLIPENDIAN(data->magic);
	FLIPENDIAN(data->flags);
	FLIPENDIANLE(data->size);
	FLIPENDIANLE(data->unk4);
}
예제 #4
0
static size_t receiveDataBodySingle(unsigned char* data, size_t size, size_t nmemb, ReceiveDataBodyDataRef bodyData)
{
	size_t byteCount = size * nmemb;
	ReceiveBodyFileData *pFileData = bodyData->currentFile;
	// Read LocalFile header
	if (pFileData->bytesLeftInLocalFile) {
		if (byteCount < pFileData->bytesLeftInLocalFile) {
			memcpy(&pFileData->localFileBytes[sizeof(LocalFile) - pFileData->bytesLeftInLocalFile], data, byteCount);
			pFileData->bytesLeftInLocalFile -= byteCount;
			return size * nmemb;
		}
		memcpy(&pFileData->localFileBytes[sizeof(LocalFile) - pFileData->bytesLeftInLocalFile], data, pFileData->bytesLeftInLocalFile);
		data += pFileData->bytesLeftInLocalFile;
		byteCount -= pFileData->bytesLeftInLocalFile;
		pFileData->bytesLeftInLocalFile = 0;
		FLIPENDIANLE(pFileData->localFile.signature);
		FLIPENDIANLE(pFileData->localFile.versionExtract);
		// FLIPENDIANLE(pFileData->localFile.flags);
		FLIPENDIANLE(pFileData->localFile.method);
		FLIPENDIANLE(pFileData->localFile.modTime);
		FLIPENDIANLE(pFileData->localFile.modDate);
		// FLIPENDIANLE(pFileData->localFile.crc32);
		FLIPENDIANLE(pFileData->localFile.compressedSize);
		FLIPENDIANLE(pFileData->localFile.size);
		FLIPENDIANLE(pFileData->localFile.lenFileName);
		FLIPENDIANLE(pFileData->localFile.lenExtra);
		pFileData->bytesLeftBeforeData = pFileData->localFile.lenFileName + pFileData->localFile.lenExtra;
	}
	// Read file name and extra bytes before body
	if (pFileData->bytesLeftBeforeData) {
		if (byteCount < pFileData->bytesLeftBeforeData) {
			pFileData->bytesLeftBeforeData -= byteCount;
			return size * nmemb;
		}
		data += pFileData->bytesLeftBeforeData;
		byteCount -= pFileData->bytesLeftBeforeData;
		pFileData->bytesLeftBeforeData = 0;
		pFileData->startBodyCallback(bodyData);
	}
	// Read body
	if (pFileData->bytesLeftInData) {
		if (byteCount < pFileData->bytesLeftInData) {
			if (pFileData->processBodyCallback(data, byteCount, bodyData) != byteCount)
				return 0;
			pFileData->bytesLeftInData -= byteCount;
			return size * nmemb;
		}
		if (pFileData->processBodyCallback(data, pFileData->bytesLeftInData, bodyData) != pFileData->bytesLeftInData)
			return 0;
		pFileData->finishBodyCallback(bodyData);
		pFileData->bytesLeftInData = 0;
	}
	return size * nmemb;
}
예제 #5
0
AbstractFile *openAbstractFile(AbstractFile * file)
{
	uint32_t signatureBE;
	uint32_t signatureLE;

	if (!file)
		return NULL;

	file->seek(file, 0);
	file->read(file, &signatureBE, sizeof(signatureBE));
	signatureLE = signatureBE;
	FLIPENDIAN(signatureBE);
	FLIPENDIANLE(signatureLE);
	file->seek(file, 0);
	if (signatureBE == SIGNATURE_8900) {
		return openAbstractFile(createAbstractFileFrom8900(file));
	} else if (signatureLE == IMG2_SIGNATURE) {
		return openAbstractFile(createAbstractFileFromImg2(file));
	} else if (signatureLE == IMG3_SIGNATURE) {
		return openAbstractFile(createAbstractFileFromImg3(file));
	} else if (signatureBE == COMP_SIGNATURE) {
		return openAbstractFile(createAbstractFileFromComp(file));
	} else {
		return file;
	}
}
예제 #6
0
AbstractFile* duplicateAbstractFile(AbstractFile* file, AbstractFile* backing) {
	uint32_t signatureBE;
	uint32_t signatureLE;
	AbstractFile* orig;

	if (!backing) { /* imagine that: createAbstractFileFromComp() fails, because of decompress_lzss() */
		return NULL;
	}
	
	file->seek(file, 0);
	file->read(file, &signatureBE, sizeof(signatureBE));
	signatureLE = signatureBE;
	FLIPENDIAN(signatureBE);
	FLIPENDIANLE(signatureLE);
	file->seek(file, 0);
	
	if(signatureLE == IMG2_SIGNATURE) {
		orig = createAbstractFileFromImg2(file);
		return duplicateAbstractFile(orig, duplicateImg2File(orig, backing));
	} else if(signatureLE == IMG3_SIGNATURE) {
		orig = createAbstractFileFromImg3(file);
		return duplicateAbstractFile(orig, duplicateImg3File(orig, backing));
	} else if(signatureBE == COMP_SIGNATURE) {
		orig = createAbstractFileFromComp(file);
		return duplicateAbstractFile(orig, duplicateCompFile(orig, backing));
	} else {
		file->close(file);
		return backing;
	}
}
예제 #7
0
파일: validate.c 프로젝트: 0neday/xpwn
uint64_t
getECID(const void *data)
{
	unsigned char temp[8];
	memcpy(temp, data, sizeof(temp));
	FLIPENDIANLE(temp);
	return *(uint64_t *)temp;
}
예제 #8
0
AbstractFile *duplicateAbstractFile2(AbstractFile * file,
				     AbstractFile * backing,
				     const unsigned int *key,
				     const unsigned int *iv,
				     AbstractFile * certificate)
{
	uint32_t signatureBE;
	uint32_t signatureLE;
	AbstractFile *orig;
	AbstractFile *newFile;

	file->seek(file, 0);
	file->read(file, &signatureBE, sizeof(signatureBE));
	signatureLE = signatureBE;
	FLIPENDIAN(signatureBE);
	FLIPENDIANLE(signatureLE);
	file->seek(file, 0);

	if (signatureBE == SIGNATURE_8900) {
		orig = createAbstractFileFrom8900(file);
		newFile = duplicate8900File(orig, backing);
		if (certificate != NULL)
			replaceCertificate8900(newFile, certificate);
		return duplicateAbstractFile(orig, newFile);
	} else if (signatureLE == IMG2_SIGNATURE) {
		orig = createAbstractFileFromImg2(file);
		return duplicateAbstractFile(orig,
					     duplicateImg2File(orig, backing));
	} else if (signatureLE == IMG3_SIGNATURE) {
		AbstractFile2 *newFile;
		AbstractFile2 *img3;

		img3 = (AbstractFile2 *) createAbstractFileFromImg3(file);
		if (key != NULL)
			img3->setKey(img3, key, iv);

		newFile =
		    (AbstractFile2 *) duplicateImg3File((AbstractFile *) img3,
							backing);
		if (key != NULL)
			img3->setKey(newFile, key, iv);

		if (certificate != NULL)
			replaceCertificateImg3((AbstractFile *) newFile,
					       certificate);
		return duplicateAbstractFile((AbstractFile *) img3,
					     (AbstractFile *) newFile);
	} else if (signatureBE == COMP_SIGNATURE) {
		orig = createAbstractFileFromComp(file);
		return duplicateAbstractFile(orig,
					     duplicateCompFile(orig, backing));
	} else {
		file->close(file);
		return backing;
	}
}
예제 #9
0
파일: img3.c 프로젝트: 0x76/opensn0w
void closeImg3(AbstractFile * file)
{
	uint8_t ivec[16];
	Img3Info *info = (Img3Info *) file->data;

	if (info->dirty) {
		if (info->encrypted) {
			uint32_t sz = info->data->header->dataSize;
			if (info->decryptLast) {
				sz = info->data->header->size;
			}
			
			memcpy(ivec, info->iv, 16);
			AES_cbc_encrypt(info->data->data, info->data->data,
					(sz / 16) * 16, &(info->encryptKey),
					ivec, AES_ENCRYPT);
		}

		if (info->exploit24k) {
			info->replaceDWord = *((uint32_t *) info->data->data);
			FLIPENDIANLE(info->replaceDWord);
			*((uint32_t *) info->data->data) = 0x22023001;
			flipEndianLE(info->data->data, 4);
		}

		if (info->exploitN8824k) {
			info->replaceDWord = *((uint32_t *) info->data->data);
			FLIPENDIANLE(info->replaceDWord);
			*((uint32_t *) info->data->data) = 0x84023001;
			flipEndianLE(info->data->data, 4);
		}

		info->file->seek(info->file, 0);
		info->root->header->dataSize = 0;	/* hack to make certain writeImg3Element doesn't preallocate */
		info->root->header->size = 0;
		writeImg3Element(info->file, info->root, info);
	}

	info->root->free(info->root);
	info->file->close(info->file);
	free(info);
	free(file);
}
예제 #10
0
파일: 8900.c 프로젝트: ashamsu/FirmExtract
void flipApple8900Header(Apple8900Header* header) {
	FLIPENDIAN(header->magic);
	FLIPENDIANLE(header->unknown1);
	FLIPENDIANLE(header->sizeOfData);
	FLIPENDIANLE(header->footerSignatureOffset);
	FLIPENDIANLE(header->footerCertOffset);
	FLIPENDIANLE(header->footerCertLen);
	FLIPENDIANLE(header->unknown2);
	FLIPENDIANLE(header->epoch);
}
예제 #11
0
void flipPartitionMultiple(Partition* partition, char multiple, char out, unsigned int BlockSize) {
	int i;
	int numPartitions;
	
	if(out) {
		numPartitions = partition->pmMapBlkCnt;
	} else {
		numPartitions = partition->pmMapBlkCnt;
		FLIPENDIAN(numPartitions);
	}
	
	for(i = 0; i < numPartitions; i++) {
		if(out) {
			if(partition->pmSig != APPLE_PARTITION_MAP_SIGNATURE) {
				break;
			}
			FLIPENDIAN(partition->pmSig);
		} else {
			FLIPENDIAN(partition->pmSig);
			if(partition->pmSig != APPLE_PARTITION_MAP_SIGNATURE) {
				break;
			}
		}
		
		FLIPENDIAN(partition->pmMapBlkCnt);
		FLIPENDIAN(partition->pmPyPartStart);
		FLIPENDIAN(partition->pmPartBlkCnt);
		FLIPENDIAN(partition->pmLgDataStart);
		FLIPENDIAN(partition->pmDataCnt);
		FLIPENDIAN(partition->pmPartStatus);
		FLIPENDIAN(partition->pmLgBootStart);
		FLIPENDIAN(partition->pmBootSize);
		FLIPENDIAN(partition->pmBootAddr);
		FLIPENDIAN(partition->pmBootAddr2);
		FLIPENDIAN(partition->pmBootEntry);
		FLIPENDIAN(partition->pmBootEntry2);
		FLIPENDIAN(partition->pmBootCksum);
		FLIPENDIANLE(partition->bootCode);
		
		if(!multiple) {
			break;
		}

		partition = (Partition*)((uint8_t*)partition + BlockSize);
	}
}
예제 #12
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);
	}
}
예제 #13
0
AbstractFile *openAbstractFile3(AbstractFile * file, const unsigned int *key,
				const unsigned int *iv, int layers)
{
	uint32_t signatureBE;
	uint32_t signatureLE;

	AbstractFile *cur;

	if (!file)
		return NULL;

	file->seek(file, 0);
	file->read(file, &signatureBE, sizeof(signatureBE));
	signatureLE = signatureBE;
	FLIPENDIAN(signatureBE);
	FLIPENDIANLE(signatureLE);
	file->seek(file, 0);

	if (signatureBE == SIGNATURE_8900) {
		cur = createAbstractFileFrom8900(file);
	} else if (signatureLE == IMG2_SIGNATURE) {
		cur = createAbstractFileFromImg2(file);
	} else if (signatureLE == IMG3_SIGNATURE) {
		AbstractFile2 *img3 =
		    (AbstractFile2 *) createAbstractFileFromImg3(file);

		if (key && iv)
			img3->setKey(img3, key, iv);
		cur = (AbstractFile *) img3;
		key = NULL;
		iv = NULL;
	} else if (signatureBE == COMP_SIGNATURE) {
		cur = createAbstractFileFromComp(file);
		key = NULL;
		iv = NULL;
	} else {
		return file;
	}

	if (layers < 0 || layers > 0)
		return openAbstractFile3(cur, key, iv, layers - 1);
	else
		return cur;
}
예제 #14
0
파일: validate.c 프로젝트: 0neday/xpwn
static void
doPartialSHA1(unsigned char md[SHA_DIGEST_LENGTH], const unsigned char *toHashData, int toHashLength, DataValue *partialDigest)
{
	const unsigned *q = (const unsigned *)partialDigest->value;
	unsigned v31 = q[0]; // XXX ASSERT(v31 == ecid->size == 64)?
	unsigned v32 = q[1];
	SHA_CTX hashctx;
	memset(&hashctx, 0, sizeof(hashctx));
	hashctx.h0 = q[2];
	hashctx.h1 = q[3];
	hashctx.h2 = q[4];
	hashctx.h3 = q[5];
	hashctx.h4 = q[6];
	FLIPENDIAN(hashctx.h0);
	FLIPENDIAN(hashctx.h1);
	FLIPENDIAN(hashctx.h2);
	FLIPENDIAN(hashctx.h3);
	FLIPENDIAN(hashctx.h4);
	FLIPENDIANLE(v32);
	hashctx.Nl = 8 * v32 + 64; // XXX could this 64 be actually v31?
	SHA1_Update(&hashctx, toHashData, toHashLength);
	SHA1_Final(md, &hashctx);
}
예제 #15
0
파일: img2.c 프로젝트: zebbra2014/xpwn
void closeImg2(AbstractFile* file) {
    InfoImg2* info = (InfoImg2*) (file->data);
    uint32_t cksum;

    if(info->dirty) {
        info->file->seek(info->file, sizeof(info->header));
        info->file->write(info->file, info->buffer, info->header.dataLen);
        info->header.dataLenPadded = info->header.dataLen;

        flipImg2Header(&(info->header));

        cksum = crc32(0, (unsigned char *)&(info->header), 0x64);
        FLIPENDIANLE(cksum);
        info->header.header_checksum = cksum;

        info->file->seek(info->file, 0);
        info->file->write(info->file, &(info->header), sizeof(info->header));
    }

    free(info->buffer);
    info->file->close(info->file);
    free(info);
    free(file);
}
예제 #16
0
파일: img3.c 프로젝트: nlog2n/xpwntool-lite
void flipAppleImg3KBAGHeader(AppleImg3KBAGHeader* data) {
	FLIPENDIANLE(data->key_modifier);
	FLIPENDIANLE(data->key_bits);
}
예제 #17
0
파일: img3.c 프로젝트: nlog2n/xpwntool-lite
void flipAppleImg3RootExtra(AppleImg3RootExtra* extra) {
	FLIPENDIANLE(extra->shshOffset);
	FLIPENDIANLE(extra->name);
}
예제 #18
0
파일: img3.c 프로젝트: nlog2n/xpwntool-lite
void flipAppleImg3Header(AppleImg3Header* header) {
	FLIPENDIANLE(header->magic);
	FLIPENDIANLE(header->size);
	FLIPENDIANLE(header->dataSize);
}
예제 #19
0
파일: img2.c 프로젝트: zebbra2014/xpwn
void flipImg2Header(Img2Header* header) {
    FLIPENDIANLE(header->signature);
    FLIPENDIANLE(header->imageType);
    FLIPENDIANLE(header->unknown1);
    FLIPENDIANLE(header->security_epoch);
    FLIPENDIANLE(header->flags1);
    FLIPENDIANLE(header->dataLen);
    FLIPENDIANLE(header->dataLenPadded);
    FLIPENDIANLE(header->unknown3);
    FLIPENDIANLE(header->flags2);
    FLIPENDIANLE(header->unknown4);
    FLIPENDIANLE(header->header_checksum);
    FLIPENDIANLE(header->checksum2);
}
예제 #20
0
void flipRsrcBlockHead(HFSPlusCmpfRsrcBlockHead* data) {
	FLIPENDIAN(data->dataSize);
	FLIPENDIANLE(data->numBlocks);
}
예제 #21
0
ZipInfo* PartialZipInit(const char* url)
{
	ZipInfo* info = (ZipInfo*) malloc(sizeof(ZipInfo));
	info->url = strdup(url);
	info->centralDirectoryRecvd = 0;
	info->centralDirectoryEndRecvd = 0;
	info->centralDirectoryDesc = NULL;

	info->hCurl = curl_easy_init();

	curl_easy_setopt(info->hCurl, CURLOPT_URL, info->url);
	curl_easy_setopt(info->hCurl, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(info->hCurl, CURLOPT_NOBODY, 1);
	curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, dummyReceive);
	curl_easy_setopt(info->hCurl, CURLOPT_SSL_VERIFYPEER, 0);

	if(strncmp(info->url, "file://", 7) == 0)
	{
		char path[1024];
		strcpy(path, info->url + 7);
		char* filePath = (char*) curl_easy_unescape(info->hCurl, path, 0,  NULL);
		FILE* f = fopen(filePath, "rb");
		if(!f)
		{
			curl_free(filePath);
			curl_easy_cleanup(info->hCurl);
			free(info->url);
			free(info);

			return NULL;
		}

		fseek(f, 0, SEEK_END);
		info->length = ftell(f);
		fclose(f);

		curl_free(filePath);
	}
	else
	{
		curl_easy_perform(info->hCurl);

		double dFileLength;
		curl_easy_getinfo(info->hCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &dFileLength);
		info->length = dFileLength;
	}

	char sRange[100];
	uint64_t start;

	if(info->length > (0xffff + sizeof(EndOfCD)))
		start = info->length - 0xffff - sizeof(EndOfCD);
	else
		start = 0;

	uint64_t end = info->length - 1;

	sprintf(sRange, "%" PRIu64 "-%" PRIu64, start, end);

	curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, receiveCentralDirectoryEnd);
	curl_easy_setopt(info->hCurl, CURLOPT_WRITEDATA, info);
	curl_easy_setopt(info->hCurl, CURLOPT_RANGE, sRange);
	curl_easy_setopt(info->hCurl, CURLOPT_HTTPGET, 1);

	curl_easy_perform(info->hCurl);

	char* cur;
	for(cur = info->centralDirectoryEnd; cur < (info->centralDirectoryEnd + (end - start - 1)); cur++)
	{
		EndOfCD* candidate = (EndOfCD*) cur;
		uint32_t signature = candidate->signature;
		FLIPENDIANLE(signature);
		if(signature == 0x06054b50)
		{
			uint16_t lenComment = candidate->lenComment;
			FLIPENDIANLE(lenComment);
			if((cur + lenComment + sizeof(EndOfCD)) == (info->centralDirectoryEnd + info->centralDirectoryEndRecvd))
			{
				FLIPENDIANLE(candidate->diskNo);
				FLIPENDIANLE(candidate->CDDiskNo);
				FLIPENDIANLE(candidate->CDDiskEntries);
				FLIPENDIANLE(candidate->CDEntries);
				FLIPENDIANLE(candidate->CDSize);
				FLIPENDIANLE(candidate->CDOffset);
				FLIPENDIANLE(candidate->lenComment);
				info->centralDirectoryDesc = candidate;
				break;
			}
		}

	}

	if(info->centralDirectoryDesc)
	{
		info->centralDirectory = malloc(info->centralDirectoryDesc->CDSize);
		start = info->centralDirectoryDesc->CDOffset;
		end = start + info->centralDirectoryDesc->CDSize - 1;
		sprintf(sRange, "%" PRIu64 "-%" PRIu64, start, end);
		curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, receiveCentralDirectory);
		curl_easy_setopt(info->hCurl, CURLOPT_WRITEDATA, info);
		curl_easy_setopt(info->hCurl, CURLOPT_RANGE, sRange);
		curl_easy_setopt(info->hCurl, CURLOPT_HTTPGET, 1);
		curl_easy_perform(info->hCurl);

		flipFiles(info);

		return info;
	}
	else 
	{
		curl_easy_cleanup(info->hCurl);
		free(info->url);
		free(info);
		return NULL;
	}
}
예제 #22
0
static void flipFiles(ZipInfo* info)
{
	char* cur = info->centralDirectory;

	unsigned int i;
	for(i = 0; i < info->centralDirectoryDesc->CDEntries; i++)
	{
		CDFile* candidate = (CDFile*) cur;
		FLIPENDIANLE(candidate->signature);
		FLIPENDIANLE(candidate->version);
		FLIPENDIANLE(candidate->versionExtract);
		// FLIPENDIANLE(candidate->flags);
		FLIPENDIANLE(candidate->method);
		FLIPENDIANLE(candidate->modTime);
		FLIPENDIANLE(candidate->modDate);
		// FLIPENDIANLE(candidate->crc32);
		FLIPENDIANLE(candidate->compressedSize);
		FLIPENDIANLE(candidate->size);
		FLIPENDIANLE(candidate->lenFileName);
		FLIPENDIANLE(candidate->lenExtra);
		FLIPENDIANLE(candidate->lenComment);
		FLIPENDIANLE(candidate->diskStart);
		// FLIPENDIANLE(candidate->internalAttr);
		// FLIPENDIANLE(candidate->externalAttr);
		FLIPENDIANLE(candidate->offset);

		cur += sizeof(CDFile) + candidate->lenFileName + candidate->lenExtra + candidate->lenComment;
	}
}
예제 #23
0
unsigned char* PartialZipGetFile(ZipInfo* info, CDFile* file)
{
	LocalFile localHeader;
	LocalFile* pLocalHeader = &localHeader;

	uint64_t start = file->offset;
	uint64_t end = file->offset + sizeof(LocalFile) - 1;
	char sRange[100];
	sprintf(sRange, "%" PRIu64 "-%" PRIu64, start, end);

	void* pFileHeader[] = {pLocalHeader, NULL, NULL, NULL}; 

	curl_easy_setopt(info->hCurl, CURLOPT_URL, info->url);
	curl_easy_setopt(info->hCurl, CURLOPT_SSL_VERIFYPEER, 0);
	curl_easy_setopt(info->hCurl, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, receiveData);
	curl_easy_setopt(info->hCurl, CURLOPT_WRITEDATA, &pFileHeader);
	curl_easy_setopt(info->hCurl, CURLOPT_RANGE, sRange);
	curl_easy_setopt(info->hCurl, CURLOPT_HTTPGET, 1);
	curl_easy_perform(info->hCurl);
	
	FLIPENDIANLE(localHeader.signature);
	FLIPENDIANLE(localHeader.versionExtract);
	// FLIPENDIANLE(localHeader.flags);
	FLIPENDIANLE(localHeader.method);
	FLIPENDIANLE(localHeader.modTime);
	FLIPENDIANLE(localHeader.modDate);
	// FLIPENDIANLE(localHeader.crc32);
	FLIPENDIANLE(localHeader.compressedSize);
	FLIPENDIANLE(localHeader.size);
	FLIPENDIANLE(localHeader.lenFileName);
	FLIPENDIANLE(localHeader.lenExtra);

	unsigned char* fileData = (unsigned char*) malloc(file->compressedSize);
	size_t progress = 0;
	void* pFileData[] = {fileData, info, file, &progress}; 

	start = file->offset + sizeof(LocalFile) + localHeader.lenFileName + localHeader.lenExtra;
	end = start + file->compressedSize - 1;
	sprintf(sRange, "%" PRIu64 "-%" PRIu64, start, end);

	curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, receiveData);
	curl_easy_setopt(info->hCurl, CURLOPT_WRITEDATA, pFileData);
	curl_easy_setopt(info->hCurl, CURLOPT_RANGE, sRange);
	curl_easy_setopt(info->hCurl, CURLOPT_HTTPGET, 1);
	curl_easy_perform(info->hCurl);

	if(file->method == 8)
	{
		unsigned char* uncData = (unsigned char*) malloc(file->size);
		z_stream strm;
		strm.zalloc = Z_NULL;
		strm.zfree = Z_NULL;
		strm.opaque = Z_NULL;
		strm.avail_in = 0;
		strm.next_in = NULL;

		inflateInit2(&strm, -MAX_WBITS);
		strm.avail_in = file->compressedSize;
		strm.next_in = fileData;
		strm.avail_out = file->size;
		strm.next_out = uncData;
		inflate(&strm, Z_FINISH);
		inflateEnd(&strm);
		free(fileData);
		fileData = uncData;
	}
	return fileData;
}
예제 #24
0
파일: pwnutil.c 프로젝트: 0neday/xpwn
int patchKernel(AbstractFile* file) {
	// codesign
	const char patch[] = {0x00, 0x00, 0x00, 0x0A, 0x00, 0x40, 0xA0, 0xE3, 0x04, 0x00, 0xA0, 0xE1, 0x90, 0x80, 0xBD, 0xE8};

	const char patch_old[] = {0xFF, 0x50, 0xA0, 0xE3, 0x04, 0x00, 0xA0, 0xE1, 0x0A, 0x10, 0xA0, 0xE1};

	// 2.0 vm_map max_prot
	const char patch3[] = {0x99, 0x91, 0x43, 0x2B, 0x91, 0xCD, 0xE7, 0x04, 0x24, 0x1D, 0xB0};
	
	// 3.0 vm_map max_prot
	const char patch2[] = {0x2E, 0xD1, 0x35, 0x98, 0x80, 0x07, 0x33, 0xD4, 0x6B, 0x08, 0x1E, 0x1C};

	// 3.0 illb img3 patch 1
	const char patch4[] = {0x98, 0x47, 0x00, 0x28, 0x00, 0xD0, 0xAE, 0xE0, 0x06, 0x98};

	// 3.0 illb img3 patch 2
	const char patch5[] = {0x05, 0x1E, 0x00, 0xD0, 0xA8, 0xE0, 0x03, 0x9B};

	// 3.0 CS enforcement patch
	const char patch6[] = {0x9C, 0x22, 0x03, 0x59, 0x99, 0x58};

	// 3.0 armv7 vm_map_enter max_prot
	const char n88patch1[] = {0x93, 0xBB, 0x16, 0xF0, 0x02, 0x0F, 0x40, 0xF0, 0x36, 0x80, 0x63, 0x08};

	// 3.0 armv7 cs patch
	const char n88patch2[] = {0x05, 0x4B, 0x98, 0x47, 0x00, 0xB1, 0x00, 0x24, 0x20, 0x46, 0x90, 0xBD};

	// 3.0 armv7 cs_enforcement_disable patch
	const char n88patch3[] = {0xD3, 0xF8, 0x9C, 0x20, 0xDF, 0xF8};

	// 3.0 arm7 img3 prod patch
	const char n88patch4[] = {0x03, 0x94, 0xFF, 0xF7, 0x29, 0xFF, 0xF8, 0xB1};

	// 3.0 arm7 img3 ecid patch
	const char n88patch5[] = {0x0C, 0xCA, 0xFF, 0xF7, 0x10, 0xFF, 0x00, 0x38};

	// 3.0 arm7 img3 signature patch
	const char n88patch6[] = {0x30, 0xE0, 0x4F, 0xF0, 0xFF, 0x30, 0x2D, 0xE0};

	// 3.0 arm7 img3 signature patch
	const char n88patch_test1[] = {0x67, 0x4B, 0x98, 0x47, 0x00, 0x28};

	// 3.0 arm7 img3 signature patch
	const char n88patch_test2[] = {0x04, 0x98, 0xFF, 0xF7, 0xD9, 0xFD, 0x04, 0x46};

	// 3.0 arm7 img3 signature patch
	const char n88patch_test3[] = {0x01, 0x99, 0xFF, 0xF7, 0xBE, 0xFC, 0x00, 0xB3};

	size_t length = file->getLength(file);
	uint8_t* buffer = (uint8_t*)malloc(length + sizeof(patch));
	file->seek(file, 0);
	file->read(file, buffer, length);
	memset(buffer + length, 0, sizeof(patch));
	
	int retval = 0;
	int i;
	for(i = 0; i < length; i++) {
		uint8_t* candidate = &buffer[i];
		if(memcmp(candidate, patch, sizeof(patch)) == 0) {
			XLOG(3, "kernel patch1 success\n"); fflush(stdout);
			candidate[4] = 0x01;
			file->seek(file, i);
			file->write(file, candidate, sizeof(patch));
			retval = TRUE;
			continue;
		}
		if(memcmp(candidate, patch_old, sizeof(patch_old)) == 0) {
			XLOG(3, "kernel patch_old success\n"); fflush(stdout);
			candidate[0] = 0x0;
			file->seek(file, i);
			file->write(file, candidate, sizeof(patch_old));
			retval = TRUE;
			continue;
		}
		if(memcmp(candidate, patch3, sizeof(patch3)) == 0) {
			XLOG(3, "kernel patch3 success\n"); fflush(stdout);
			candidate[0] = 0x2B;
			candidate[1] = 0x99;
			candidate[2] = 0x00;
			candidate[3] = 0x00;
			file->seek(file, i);
			file->write(file, candidate, sizeof(patch3));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, patch2, sizeof(patch2)) == 0) {
			XLOG(3, "kernel patch2 success\n"); fflush(stdout);
			// NOP out the BMI
			candidate[6] = 0x00;
			candidate[7] = 0x28;
			file->seek(file, i);
			file->write(file, candidate, sizeof(patch2));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, patch4, sizeof(patch4)) == 0) {
			XLOG(3, "kernel patch4 success\n"); fflush(stdout);
			candidate[3] = 0x20;
			file->seek(file, i);
			file->write(file, candidate, sizeof(patch4));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, patch5, sizeof(patch5)) == 0) {
			XLOG(3, "kernel patch5 success\n"); fflush(stdout);
			candidate[0] = 0x00;
			candidate[1] = 0x25;
			file->seek(file, i);
			file->write(file, candidate, sizeof(patch5));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch1, sizeof(n88patch1)) == 0) {
			XLOG(3, "kernel armv7 vm_map_enter patch success\n"); fflush(stdout);
			candidate[6] = 0x8B;
			candidate[7] = 0x46;
			candidate[8] = 0x8B;
			candidate[9] = 0x46;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch1));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch2, sizeof(n88patch2)) == 0) {
			XLOG(3, "kernel armv7 cs patch success\n"); fflush(stdout);
			candidate[6] = 0x1;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch2));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch4, sizeof(n88patch4)) == 0) {
			XLOG(3, "kernel armv7 img3 prod patch success\n"); fflush(stdout);
			candidate[2] = 0x00;
			candidate[3] = 0x20;
			candidate[4] = 0x00;
			candidate[5] = 0x20;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch4));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch5, sizeof(n88patch5)) == 0) {
			XLOG(3, "kernel armv7 img3 ecid patch success\n"); fflush(stdout);
			candidate[2] = 0x00;
			candidate[3] = 0x20;
			candidate[4] = 0x00;
			candidate[5] = 0x20;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch5));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch6, sizeof(n88patch6)) == 0) {
			XLOG(3, "kernel armv7 img3 signature patch success\n"); fflush(stdout);
			candidate[2] = 0x00;
			candidate[3] = 0x20;
			candidate[4] = 0x00;
			candidate[5] = 0x20;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch6));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch_test1, sizeof(n88patch_test1)) == 0) {
			XLOG(3, "kernel armv7 img3 ParseFirmwareFooter patch success\n"); fflush(stdout);
			candidate[2] = 0x00;
			candidate[3] = 0x20;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch_test1));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch_test2, sizeof(n88patch_test2)) == 0) {
			XLOG(3, "kernel armv7 img3 CheckMetaTags patch success\n"); fflush(stdout);
			candidate[2] = 0x00;
			candidate[3] = 0x20;
			candidate[4] = 0x00;
			candidate[5] = 0x20;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch_test2));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch_test3, sizeof(n88patch_test3)) == 0) {
			XLOG(3, "kernel armv7 img3 encrypt SHSH with 89A patch success\n"); fflush(stdout);
			candidate[2] = 0x01;
			candidate[3] = 0x20;
			candidate[4] = 0x01;
			candidate[5] = 0x20;
			file->seek(file, i);
			file->write(file, candidate, sizeof(n88patch_test3));
			retval = TRUE;
			continue;
		}
		if(Do30Patches && memcmp(candidate, patch6, sizeof(patch6)) == 0) {
			if(candidate[7] != 0x4B)
				continue;

			uint32_t cs_enforcement_disable = *((uint32_t*)(((intptr_t)(&candidate[6] + 0x4) & ~0x3) + (0x4 * candidate[6])));
			FLIPENDIANLE(cs_enforcement_disable);

			uint32_t offset = cs_enforcement_disable - 0xC0008000;

			XLOG(3, "kernel cs_enforcement_disable at: 0x%X, 0x%X\n", cs_enforcement_disable, offset); fflush(stdout);

			uint32_t value = 1;

			FLIPENDIANLE(value);

			*((uint32_t*)(buffer + offset)) = value;

			file->seek(file, offset);
			file->write(file, &value, sizeof(value));
			continue;
		}
		if(Do30Patches && memcmp(candidate, n88patch3, sizeof(n88patch3)) == 0) {
			uint32_t cs_enforcement_disable = *((uint32_t*)(((intptr_t)(&candidate[4] + 0x4) & ~0x3) + (((candidate[7] & 0xF) << 8) + candidate[6])));
			FLIPENDIANLE(cs_enforcement_disable);

			uint32_t offset = cs_enforcement_disable - 0xC0008000;

			XLOG(3, "kernel cs_enforcement_disable at: 0x%X, 0x%X\n", cs_enforcement_disable, offset); fflush(stdout);

			uint32_t value = 1;

			FLIPENDIANLE(value);

			*((uint32_t*)(buffer + offset)) = value;

			file->seek(file, offset);
			file->write(file, &value, sizeof(value));
			continue;
		}
	}
	
	free(buffer);
	return retval;
}
예제 #25
0
void flipRsrcBlock(HFSPlusCmpfRsrcBlock* data) {
	FLIPENDIANLE(data->offset);
	FLIPENDIANLE(data->size);
}
예제 #26
0
void flipHFSPlusDecmpfs(HFSPlusDecmpfs* compressData) {
	FLIPENDIANLE(compressData->magic);
	FLIPENDIANLE(compressData->flags);
	FLIPENDIANLE(compressData->size);
}
예제 #27
0
파일: 8900.c 프로젝트: mucit/opensn0w
void close8900(AbstractFile * file)
{
	unsigned char ivec[16];
	SHA_CTX sha_ctx;
	unsigned char md[20];
	unsigned char exploit_data[0x54] = { 0 };
	/*int align; */
	size_t origSize;
	uint32_t cksum;
	Info8900 *info = (Info8900 *) (file->data);

	if (info->dirty) {
		if (info->header.format == 3) {
			/* we need to block-align our data, or AES will break */
			origSize = info->header.sizeOfData;
			/* gotta break abstraction here, because Apple is mean */
			if (((Img2Header *) info->buffer)->signature ==
			    IMG2_SIGNATURE) {
				((Img2Header *) info->buffer)->dataLenPadded =
				    ((Img2Header *) info->
				     buffer)->dataLenPadded % 16 ==
				    0 ? ((Img2Header *) info->buffer)->
				    dataLenPadded
				    : ((((Img2Header *) info->
					 buffer)->dataLenPadded / 16) + 1) * 16;
				info->header.sizeOfData =
				    ((Img2Header *) info->
				     buffer)->dataLenPadded +
				    sizeof(Img2Header);

				cksum =
				    crc32(0, (unsigned char *)info->buffer,
					  0x64);
				FLIPENDIANLE(cksum);
				((Img2Header *) info->buffer)->header_checksum =
				    cksum;
			}

			info->header.sizeOfData =
			    (info->header.sizeOfData) % 16 ==
			    0 ? info->
			    header.sizeOfData : ((info->header.sizeOfData / 16)
						 + 1) * 16;
			if (info->header.sizeOfData != origSize) {
				info->buffer =
				    realloc(info->buffer,
					    info->header.sizeOfData);
				memset((void *)((uint8_t *) info->buffer +
						origSize), 0,
				       info->header.sizeOfData - origSize);
			}
		}

		info->header.footerSignatureOffset = info->header.sizeOfData;
		info->header.footerCertOffset =
		    info->header.footerSignatureOffset + 0x80;

		if (info->header.format == 3) {
			memset(ivec, 0, 16);
			AES_cbc_encrypt(info->buffer, info->buffer,
					info->header.sizeOfData,
					&(info->encryptKey), ivec, AES_ENCRYPT);
		}

		info->file->seek(info->file, sizeof(info->header));
		info->file->write(info->file, info->buffer,
				  info->header.sizeOfData);
		info->file->seek(info->file,
				 sizeof(info->header) +
				 info->header.footerSignatureOffset);
		info->file->write(info->file, info->footerSignature, 0x80);
		info->file->seek(info->file,
				 sizeof(info->header) +
				 info->header.footerCertOffset);

		if (info->exploit) {
			info->footerCertificate[0x8be] = 0x9F;
			info->footerCertificate[0xb08] = 0x55;
		}

		info->file->write(info->file, info->footerCertificate,
				  info->header.footerCertLen);

		if (info->exploit) {
			info->header.footerCertLen = 0xc5e;
			exploit_data[0x30] = 0x01;
			exploit_data[0x50] = 0xEC;
			exploit_data[0x51] = 0x57;
			exploit_data[0x53] = 0x20;
			info->file->write(info->file, exploit_data,
					  sizeof(exploit_data));
		}

		flipApple8900Header(&(info->header));
		SHA1_Init(&sha_ctx);
		SHA1_Update(&sha_ctx, &(info->header), 0x40);
		SHA1_Final(md, &sha_ctx);

		memset(ivec, 0, 16);
		AES_cbc_encrypt(md,
				(unsigned char *)&(info->
						   header.headerSignature),
				0x10, &(info->encryptKey), ivec, AES_ENCRYPT);

		info->file->seek(info->file, 0);
		info->file->write(info->file, &(info->header),
				  sizeof(info->header));
	}

	free(info->footerCertificate);
	free(info->buffer);
	info->file->close(info->file);
	free(info);
	free(file);
}
예제 #28
0
파일: validate.c 프로젝트: 0neday/xpwn
static const char *
checkBlob(X509 *x0, DataValue *blob, DataValue *partialDigest, uint64_t *savecid)
{
	int rv;
	X509 *x1, *x2;
	uint64_t thisecid;
	unsigned partial0;
	int len = blob->len;
	const unsigned char *ptr = blob->value;

	AppleImg3Header *cert = NULL;
	AppleImg3Header *ecid = NULL;
	AppleImg3Header *shsh = NULL;

	while (len > 0) {
		AppleImg3Header *hdr;
		if (len < sizeof(AppleImg3Header)) {
			return "truncated";
		}
		hdr = (AppleImg3Header *)ptr;
		flipAppleImg3Header(hdr); // XXX we need to flip ECID back before hashing
		switch (hdr->magic) {
			case IMG3_ECID_MAGIC:
				ecid = (AppleImg3Header *)ptr;
				break;
			case IMG3_SHSH_MAGIC:
				shsh = (AppleImg3Header *)ptr;
				break;
			case IMG3_CERT_MAGIC:
				cert = (AppleImg3Header *)ptr;
				break;
			default:
				return "unknown";
		}
		len -= hdr->size;
		ptr += hdr->size;
	}

	if (!ecid || !shsh || !cert) {
		return "incomplete";
	}
	partial0 = *(unsigned *)partialDigest->value;
	FLIPENDIANLE(partial0);
	if (partial0 != 0x40 || partial0 != ecid->size) {
		return "internal"; // XXX see doPartialSHA1()
	}

	thisecid = getECID(ecid + 1);
	if (*savecid == 0) {
		*savecid = thisecid;
	}
	if (*savecid != thisecid) {
		return "mismatch";
	}

	rv = extract2Certs((unsigned char *)(cert + 1), cert->dataSize, &x1, &x2);
	if (rv) {
		return "asn1";
	}

	rv = cryptoMagic(x0, x1, x2, (unsigned char *)ecid, ecid->size, (unsigned char *)(shsh + 1), shsh->dataSize, partialDigest);

	X509_free(x2);
	X509_free(x1);
	return rv ? "crypto" : NULL;
}