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; } }
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; } }
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; } }
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; }
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); } }
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; }
AbstractFile* duplicateImg3File(AbstractFile* file, AbstractFile* backing) { Img3Info* info; AbstractFile* toReturn; if(!file) { return NULL; } toReturn = createAbstractFileFromImg3(((Img3Info*)file->data)->file); info = (Img3Info*)toReturn->data; info->file = backing; info->offset = 0; info->dirty = TRUE; info->data->header->dataSize = 0; info->data->header->size = info->data->header->dataSize + sizeof(AppleImg3Header); return toReturn; }