/// <summary> /// Uncompresses a GZIP file. /// </summary> /// <param name="bytes"> The compressed bytes. </param> /// <returns> The uncompressed bytes. </returns> /// <exception cref="IOException"> if an I/O error occurs. </exception> public static byte[] Gunzip(byte[] bytes) { /* create the streams */ var @is = new GZIPInputStream(new ByteArrayInputStream(bytes)); try { var os = new ByteArrayOutputStream(); try { /* copy data between the streams */ var buf = new byte[4096]; var len = 0; while ((len = @is.read(buf, 0, buf.Length)) != -1) { os.write(buf, 0, len); } } finally { os.close(); } /* return the uncompressed bytes */ return(os.toByteArray()); } finally { @is.close(); } }
public virtual int sceGzipDecompress(TPointer outBufferAddr, int outBufferLength, TPointer inBufferAddr, TPointer32 crc32Addr) { if (log.TraceEnabled) { log.trace(string.Format("sceGzipDecompress: {0}", Utilities.getMemoryDump(inBufferAddr.Address, 16))); } int result; CRC32 crc32 = new CRC32(); sbyte[] buffer = new sbyte[4096]; try { // Using a GZIPInputStream instead of an Inflater because the GZIPInputStream // is skipping the GZIP header and this should be done manually with an Inflater. GZIPInputStream @is = new GZIPInputStream(new MemoryInputStream(inBufferAddr.Address)); IMemoryWriter memoryWriter = MemoryWriter.getMemoryWriter(outBufferAddr.Address, outBufferLength, 1); int decompressedLength = 0; while (decompressedLength < outBufferLength) { int Length = @is.read(buffer); if (Length < 0) { // End of GZIP stream break; } if (decompressedLength + Length > outBufferLength) { Console.WriteLine(string.Format("sceGzipDecompress : decompress buffer too small inBuffer={0}, outLength={1:D}", inBufferAddr, outBufferLength)); @is.close(); return(SceKernelErrors.ERROR_INVALID_SIZE); } crc32.update(buffer, 0, Length); for (int i = 0; i < Length; i++) { memoryWriter.writeNext(buffer[i] & 0xFF); } decompressedLength += Length; } @is.close(); memoryWriter.flush(); result = decompressedLength; } catch (IOException e) { Console.WriteLine("sceGzipDecompress", e); return(SceKernelErrors.ERROR_INVALID_FORMAT); } crc32Addr.setValue((int)crc32.Value); return(result); }
public virtual sbyte[] DecryptAndUncompressPRX(sbyte[] buf, int size) { int compAttribute = readUnaligned16(buf, 0x6); int pspSize = readUnaligned32(buf, 0x2C); int elfSize = readUnaligned32(buf, 0x28); int decryptMode = read8(buf, 0x7C); sbyte[] resultBuffer = new sbyte[size]; Array.Copy(buf, 0, resultBuffer, 0, size); int type; switch (decryptMode) { case DECRYPT_MODE_VSH_MODULE: case DECRYPT_MODE_USER_MODULE: int result = memlmdModule.hleMemlmd_6192F715(resultBuffer, size); //if (log.DebugEnabled) { Console.WriteLine(string.Format("DecryptPRX: memlmd_6192F715 returning 0x{0:X}: {1}", result, Utilities.getMemoryDump(resultBuffer, 0, 0x80 + 0xD0))); } type = 9; break; case DECRYPT_MODE_UMD_GAME_EXEC: type = 9; break; case DECRYPT_MODE_GAMESHARING_EXEC: type = 2; break; case DECRYPT_MODE_MS_UPDATER: type = 8; break; case DECRYPT_MODE_DEMO_EXEC: case DECRYPT_MODE_APP_MODULE: type = 4; break; case DECRYPT_MODE_POPS_EXEC: type = 5; break; default: Console.WriteLine(string.Format("DecryptAndUncompressPRX unknown decryptMode={0:D}", decryptMode)); type = 2; break; } int resultSize = DecryptPRX(resultBuffer, size, type, null, null); if (resultSize < 0) { return(null); } if ((compAttribute & SCE_EXEC_FILE_COMPRESSED) != 0) { if ((compAttribute & 0xF00) == 0) { // GZIP compressed try { GZIPInputStream @in = new GZIPInputStream(new System.IO.MemoryStream(resultBuffer, 0, pspSize)); sbyte[] elfBuffer = new sbyte[elfSize]; int elfOffset = 0; while (elfOffset < elfSize) { int Length = @in.read(elfBuffer, elfOffset, elfSize - elfOffset); if (Length <= 0) { break; } elfOffset += Length; } @in.close(); // Return the uncompressed ELF file resultSize = elfOffset; resultBuffer = elfBuffer; } catch (IOException e) { Console.WriteLine(e); } } else { Console.WriteLine(string.Format("KL4E decompression unimplemented, compAttribute=0x{0:X}", compAttribute)); } } // Truncate the resultBuffer if too long if (resultBuffer.Length > resultSize) { sbyte[] newBuffer = new sbyte[resultSize]; Array.Copy(resultBuffer, 0, newBuffer, 0, resultSize); resultBuffer = newBuffer; } return(resultBuffer); }