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; }
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; }
AbstractFile *openAbstractFile2(AbstractFile * file, const unsigned int *key, const unsigned int *iv) { return openAbstractFile3(file, key, iv, -1); }