bool FSeek(FILE* a_fpFile, n64 a_nOffset) { if (fflush(a_fpFile) != 0) { return false; } int nFd = FFileno(a_fpFile); if (nFd == -1) { return false; } FFseek(a_fpFile, 0, SEEK_END); n64 nFileSize = FFtell(a_fpFile); if (nFileSize < a_nOffset) { n64 nOffset = FLseek(nFd, a_nOffset - 1, SEEK_SET); if (nOffset == -1) { return false; } fputc(0, a_fpFile); fflush(a_fpFile); } else { FFseek(a_fpFile, a_nOffset, SEEK_SET); } return true; }
bool C3dsTool::compressFile() { FILE* fp = FFopen(m_pFileName, "rb"); bool bReuslt = fp != nullptr; if (bReuslt) { FFseek(fp, 0, SEEK_END); u32 uUncompressedSize = static_cast<u32>(FFtell(fp)); FFseek(fp, 0, SEEK_SET); u8* pUncompressed = new u8[uUncompressedSize]; fread(pUncompressed, 1, uUncompressedSize, fp); fclose(fp); u32 uCompressedSize = 0; switch (m_eCompressType) { case kCompressTypeBlz: uCompressedSize = uUncompressedSize; break; case kCompressTypeLz: case kCompressTypeLzEx: uCompressedSize = CLz77::GetCompressBoundSize(uUncompressedSize, m_nCompressAlign); break; default: break; } u8* pCompressed = new u8[uCompressedSize]; switch (m_eCompressType) { case kCompressTypeBlz: bReuslt = CBackwardLz77::Compress(pUncompressed, uUncompressedSize, pCompressed, uCompressedSize); break; case kCompressTypeLz: bReuslt = CLz77::CompressLz(pUncompressed, uUncompressedSize, pCompressed, uCompressedSize, m_nCompressAlign); break; case kCompressTypeLzEx: bReuslt = CLz77::CompressLzEx(pUncompressed, uUncompressedSize, pCompressed, uCompressedSize, m_nCompressAlign); break; default: break; } if (bReuslt) { fp = FFopen(m_pCompressOutFileName, "wb"); bReuslt = fp != nullptr; if (bReuslt) { fwrite(pCompressed, 1, uCompressedSize, fp); fclose(fp); } } else { printf("ERROR: compress error\n\n"); } delete[] pCompressed; delete[] pUncompressed; } return bReuslt; }
bool FEncryptAesCtrFile(const char* a_pDataFileName, u8 a_uKey[16], u8 a_uAesCtr[16], n64 a_nDataOffset, n64 a_nDataSize, bool a_bDataFileAll, bool a_bVerbose) { FILE* fpData = FFopen(a_pDataFileName, "rb+"); if (fpData == nullptr) { return false; } FFseek(fpData, 0, SEEK_END); n64 nDataSize = FFtell(fpData); if (nDataSize < a_nDataOffset) { fclose(fpData); printf("ERROR: data file %s size less than data offset\n\n", a_pDataFileName); return false; } if (a_bDataFileAll) { a_nDataSize = nDataSize - a_nDataOffset; } if (nDataSize < a_nDataOffset + a_nDataSize) { if (a_bVerbose) { fclose(fpData); printf("ERROR: data file %s size less than data offset + data size\n\n", a_pDataFileName); return false; } a_nDataSize = nDataSize - a_nDataOffset; } AES_KEY aesKey; AES_set_encrypt_key(a_uKey, 128, &aesKey); u8 uEcountBuf[16] = {}; u32 nNum = 0; n64 nIndex = 0; const n64 nBufferSize = 0x100000; u8* pInBuffer = new u8[nBufferSize]; u8* pOutBuffer = new u8[nBufferSize]; while (a_nDataSize > 0) { n64 nSize = a_nDataSize > nBufferSize ? nBufferSize : a_nDataSize; FFseek(fpData, a_nDataOffset + nIndex * nBufferSize, SEEK_SET); fread(pInBuffer, 1, static_cast<size_t>(nSize), fpData); AES_ctr128_encrypt(pInBuffer, pOutBuffer, static_cast<size_t>(nSize), &aesKey, a_uAesCtr, uEcountBuf, &nNum); FFseek(fpData, a_nDataOffset + nIndex * nBufferSize, SEEK_SET); fwrite(pOutBuffer, 1, static_cast<size_t>(nSize), fpData); a_nDataSize -= nSize; nIndex++; } delete[] pOutBuffer; delete[] pInBuffer; fclose(fpData); return true; }
bool FEncryptXorData(void* a_pData, const char* a_pXorFileName, n64 a_nDataSize, n64 a_nXorOffset, bool a_bVerbose) { FILE* fpXor = FFopen(a_pXorFileName, "rb"); if (fpXor == nullptr) { return false; } FFseek(fpXor, 0, SEEK_END); n64 nXorSize = FFtell(fpXor); if (nXorSize - a_nXorOffset < a_nDataSize) { if (a_bVerbose) { fclose(fpXor); printf("ERROR: xor file %s size less than data size\n\n", a_pXorFileName); return false; } a_nDataSize = nXorSize - a_nXorOffset; } FFseek(fpXor, a_nXorOffset, SEEK_SET); n64 nIndex = 0; const n64 nBufferSize = 0x100000; u8* pXorBuffer = new u8[nBufferSize]; while (a_nDataSize > 0) { n64 nSize = a_nDataSize > nBufferSize ? nBufferSize : a_nDataSize; fread(pXorBuffer, 1, static_cast<size_t>(nSize), fpXor); u64* pDataBuffer64 = reinterpret_cast<u64*>(static_cast<u8*>(a_pData) + nIndex * nBufferSize); u64* pXorBuffer64 = reinterpret_cast<u64*>(pXorBuffer); n64 nXorCount = nSize / 8; for (n64 i = 0; i < nXorCount; i++) { *pDataBuffer64++ ^= *pXorBuffer64++; } int nRemain = nSize % 8; if (nRemain != 0) { u8* pDataBuffer8 = reinterpret_cast<u8*>(pDataBuffer64); u8* pXorBuffer8 = reinterpret_cast<u8*>(pXorBuffer64); for (n64 i = 0; i < nRemain; i++) { *pDataBuffer8++ ^= *pXorBuffer8++; } } a_nDataSize -= nSize; nIndex++; } delete[] pXorBuffer; fclose(fpXor); return true; }
bool FEncryptXorCopyFile(FILE* a_fpDest, FILE* a_fpSrc, const char* a_pXorFileName, n64 a_nOffset, n64 a_nSize, bool a_bVerbose) { FILE* fpXor = FFopen(a_pXorFileName, "rb"); if (fpXor == nullptr) { return false; } FFseek(fpXor, 0, SEEK_END); n64 nXorSize = FFtell(fpXor); if (nXorSize < a_nSize && a_bVerbose) { fclose(fpXor); printf("ERROR: xor file %s size less than data size\n\n", a_pXorFileName); return false; } FFseek(fpXor, 0, SEEK_SET); const n64 nBufferSize = 0x100000; u8* pDataBuffer = new u8[nBufferSize]; u8* pXorBuffer = new u8[nBufferSize]; FFseek(a_fpSrc, a_nOffset, SEEK_SET); while (a_nSize > 0) { n64 nSize = a_nSize > nBufferSize ? nBufferSize : a_nSize; fread(pDataBuffer, 1, static_cast<size_t>(nSize), a_fpSrc); fread(pXorBuffer, 1, static_cast<size_t>(nSize), fpXor); u64* pDataBuffer64 = reinterpret_cast<u64*>(pDataBuffer); u64* pXorBuffer64 = reinterpret_cast<u64*>(pXorBuffer); n64 nXorCount = FAlign(nSize, 8) / 8; for (n64 i = 0; i < nXorCount; i++) { *pDataBuffer64++ ^= *pXorBuffer64++; } fwrite(pDataBuffer, 1, static_cast<size_t>(nSize), a_fpDest); a_nSize -= nSize; } delete[] pXorBuffer; delete[] pDataBuffer; fclose(fpXor); return true; }
void FCopyFile(FILE* a_fpDest, FILE* a_fpSrc, n64 a_nSrcOffset, n64 a_nSize) { const n64 nBufferSize = 0x100000; u8* pBuffer = new u8[nBufferSize]; FFseek(a_fpSrc, a_nSrcOffset, SEEK_SET); while (a_nSize > 0) { n64 nSize = a_nSize > nBufferSize ? nBufferSize : a_nSize; fread(pBuffer, 1, static_cast<size_t>(nSize), a_fpSrc); fwrite(pBuffer, 1, static_cast<size_t>(nSize), a_fpDest); a_nSize -= nSize; } delete[] pBuffer; }
void FEncryptAesCtrCopyFile(FILE* a_fpDest, FILE* a_fpSrc, u8 a_uKey[16], u8 a_uAesCtr[16], n64 a_nSrcOffset, n64 a_nSize, bool a_bVerbose) { AES_KEY aesKey; AES_set_encrypt_key(a_uKey, 128, &aesKey); u8 uEcountBuf[16] = {}; u32 nNum = 0; const n64 nBufferSize = 0x100000; u8* pInBuffer = new u8[nBufferSize]; u8* pOutBuffer = new u8[nBufferSize]; FFseek(a_fpSrc, a_nSrcOffset, SEEK_SET); while (a_nSize > 0) { n64 nSize = a_nSize > nBufferSize ? nBufferSize : a_nSize; fread(pInBuffer, 1, static_cast<size_t>(nSize), a_fpSrc); AES_ctr128_encrypt(pInBuffer, pOutBuffer, static_cast<size_t>(nSize), &aesKey, a_uAesCtr, uEcountBuf, &nNum); fwrite(pOutBuffer, 1, static_cast<size_t>(nSize), a_fpDest); a_nSize -= nSize; } delete[] pOutBuffer; delete[] pInBuffer; }
bool FEncryptXorFile(const char* a_pDataFileName, const char* a_pXorFileName, n64 a_nDataOffset, n64 a_nDataSize, bool a_bDataFileAll, n64 a_nXorOffset, bool a_bVerbose) { FILE* fpData = FFopen(a_pDataFileName, "rb+"); if (fpData == nullptr) { return false; } FFseek(fpData, 0, SEEK_END); n64 nDataSize = FFtell(fpData); if (nDataSize < a_nDataOffset) { fclose(fpData); printf("ERROR: data file %s size less than data offset\n\n", a_pDataFileName); return false; } if (a_bDataFileAll) { a_nDataSize = nDataSize - a_nDataOffset; } if (nDataSize < a_nDataOffset + a_nDataSize) { if (a_bVerbose) { fclose(fpData); printf("ERROR: data file %s size less than data offset + data size\n\n", a_pDataFileName); return false; } a_nDataSize = nDataSize - a_nDataOffset; } FILE* fpXor = FFopen(a_pXorFileName, "rb"); if (fpXor == nullptr) { fclose(fpData); return false; } FFseek(fpXor, 0, SEEK_END); n64 nXorSize = FFtell(fpXor); if (nXorSize - a_nXorOffset < a_nDataSize) { if (a_bVerbose) { fclose(fpXor); fclose(fpData); printf("ERROR: xor file %s size less than data size\n\n", a_pXorFileName); return false; } a_nDataSize = nXorSize - a_nXorOffset; } FFseek(fpXor, a_nXorOffset, SEEK_SET); n64 nIndex = 0; const n64 nBufferSize = 0x100000; u8* pDataBuffer = new u8[nBufferSize]; u8* pXorBuffer = new u8[nBufferSize]; while (a_nDataSize > 0) { n64 nSize = a_nDataSize > nBufferSize ? nBufferSize : a_nDataSize; FFseek(fpData, a_nDataOffset + nIndex * nBufferSize, SEEK_SET); fread(pDataBuffer, 1, static_cast<size_t>(nSize), fpData); fread(pXorBuffer, 1, static_cast<size_t>(nSize), fpXor); u64* pDataBuffer64 = reinterpret_cast<u64*>(pDataBuffer); u64* pXorBuffer64 = reinterpret_cast<u64*>(pXorBuffer); n64 nXorCount = FAlign(nSize, 8) / 8; for (n64 i = 0; i < nXorCount; i++) { *pDataBuffer64++ ^= *pXorBuffer64++; } FFseek(fpData, a_nDataOffset + nIndex * nBufferSize, SEEK_SET); fwrite(pDataBuffer, 1, static_cast<size_t>(nSize), fpData); a_nDataSize -= nSize; nIndex++; } delete[] pXorBuffer; delete[] pDataBuffer; fclose(fpXor); fclose(fpData); return true; }