diff --git a/src/decrypt.c b/src/decrypt.c index 2209303..121ceb3 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -16,11 +16,13 @@ void initDecryptor(uint32_t key0, uint32_t key1, uint32_t key2) { } /** Decrypts the given input in-place. The input buffer will be modified. */ -void decrypt(unsigned char chunk[], unsigned long length) { +void decrypt(uint8_t* chunk, unsigned long length) { for (unsigned long i = 0; i < length; i += 1) { - unsigned char testChar = chunk[i]; - testChar = testChar ^ decryptByte((uint16_t)(decryptor.key2 | 2)); + //uint8_t testChar = chunk[i]; + uint8_t testChar = *(chunk + i); + testChar = testChar ^ decryptByte((uint16_t)((uint16_t)(decryptor.key2 & (uint16_t)0xFFFF) | (uint16_t)2)); updateKeys(&(decryptor.key0), &(decryptor.key1), &(decryptor.key2), testChar); - chunk[i] = testChar; + //chunk[i] = testChar; + *(chunk + i) = testChar; } } diff --git a/src/decrypt.h b/src/decrypt.h index afc3529..3c7c557 100644 --- a/src/decrypt.h +++ b/src/decrypt.h @@ -5,4 +5,4 @@ void initDecryptor(uint32_t key0, uint32_t key1, uint32_t key2); /** Decrypts the given input in-place. The input buffer will be modified. */ -void decrypt(unsigned char chunk[], unsigned long length); +void decrypt(uint8_t* chunk, unsigned long length); diff --git a/src/fileReader.c b/src/fileReader.c index 0872082..0f25a2e 100644 --- a/src/fileReader.c +++ b/src/fileReader.c @@ -32,7 +32,7 @@ void initFileReader(char path[], unsigned long offset) { //Reads the given amount of bytes from the file and returns them. Automatically opens next file if EOF is reached. -void getBytes(char* buffer, unsigned long numBytes) { +void getBytes(uint8_t* buffer, unsigned long numBytes) { char* bufferPosition = buffer; unsigned long remainingBytes = numBytes; diff --git a/src/fileReader.h b/src/fileReader.h index fb76723..fdf15bb 100644 --- a/src/fileReader.h +++ b/src/fileReader.h @@ -1,5 +1,7 @@ #pragma once +#include + void initFileReader(char path[], unsigned long offset); -void getBytes(char* buffer, unsigned long numBytes); +void getBytes(uint8_t* buffer, unsigned long numBytes); diff --git a/src/inflate.c b/src/inflate.c index 2abed28..458cd78 100644 --- a/src/inflate.c +++ b/src/inflate.c @@ -14,25 +14,25 @@ #include "inflate.h" //The compressed and uncompressed buffer arrays -const char* comprBuffer; -char* uncomprBuffer; +static const uint8_t* comprBuffer; +static uint8_t* uncomprBuffer; //Position of the inflater in the buffer arrays -const char* comprBufferNext; -char* uncomprBufferNext; +static const uint8_t* comprBufferNext; +static uint8_t* uncomprBufferNext; //Buffer lengths -unsigned long uncomprBufferSize; -unsigned long remainingInput; -unsigned long spaceInOutput; +static unsigned long uncomprBufferSize; +static size_t remainingInput; +static size_t spaceInOutput; //Internal variables used by miniz -tinfl_decompressor inflator; -tdefl_status status; -size_t in_bytes, out_bytes; +static tinfl_decompressor decompressor; +static tdefl_status status; +static size_t in_bytes, out_bytes; -void inflateInit(char* comprBufferIn, char* uncomprBufferIn, unsigned long uncomprBufferSizeIn) { +void inflateInit(uint8_t* comprBufferIn, uint8_t* uncomprBufferIn, unsigned long uncomprBufferSizeIn) { comprBuffer = comprBufferIn; uncomprBuffer = uncomprBufferIn; uncomprBufferSize = uncomprBufferSizeIn; - tinfl_init(&inflator); + tinfl_init(&decompressor); } struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreBytes) { @@ -40,12 +40,13 @@ struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreByt //continue in input buffer where we were before } else { //go back to beginning of input buffer + comprBufferNext = comprBuffer; remainingInput = numInputBytes; - comprBufferNext = (const mz_uint8 *)comprBuffer; } - //output buffer has been emptied - spaceInOutput = uncomprBufferSize; + + //output buffer was previously fully filled and all output was processed. New uncompressed data can be written starting at offset 0 uncomprBufferNext = (mz_uint8 *)uncomprBuffer; + spaceInOutput = uncomprBufferSize; struct InflateOutput out; out.hasReachedEnd = false; @@ -56,19 +57,19 @@ struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreByt //Call decompression status = tinfl_decompress( - &inflator, + &decompressor, (const mz_uint8 *)comprBufferNext, &in_bytes, - uncomprBuffer, + (mz_uint8 *)uncomprBuffer, (mz_uint8 *)uncomprBufferNext, &out_bytes, (hasMoreBytes ? TINFL_FLAG_HAS_MORE_INPUT : 0) ); //Adjust buffer positions by the amount of bytes processed - comprBufferNext = (const mz_uint8 *)comprBufferNext + in_bytes; + comprBufferNext = (const uint8_t *)(comprBufferNext + in_bytes); remainingInput -= in_bytes; - uncomprBufferNext = (mz_uint8 *)uncomprBufferNext + out_bytes; + uncomprBufferNext = (uint8_t *)(uncomprBufferNext + out_bytes); spaceInOutput -= out_bytes; //Check for errors @@ -84,15 +85,25 @@ struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreByt } } - //If output buffer is filled, we need to clear it before decompressing more data - if (spaceInOutput == 0) { - break; + if (status == TINFL_STATUS_NEEDS_MORE_INPUT && remainingInput != 0) { + fprintf(stderr, "Received status NEEDS_MORE_INPUT, with remaining input %lu and space in output %lu.\n", remainingInput, spaceInOutput); } + if (status == TINFL_STATUS_HAS_MORE_OUTPUT && spaceInOutput != 0) { + fprintf(stderr, "Received status HAS_MORE_OUTPUT, with remaining input %lu and space in output %lu.\n", remainingInput, spaceInOutput); + } + + //commented out because we immediately exit while loop if it is zero + //If output buffer is filled, we need to clear it before decompressing more data + /*if (spaceInOutput == 0) { + break; + }*/ } //Return output if (remainingInput == 0) { out.needMoreInput = hasMoreBytes; + } else { + out.needMoreInput = false; } out.numBytesWrittenToOutput = uncomprBufferSize - spaceInOutput; diff --git a/src/inflate.h b/src/inflate.h index d557a9b..3d7c3b2 100644 --- a/src/inflate.h +++ b/src/inflate.h @@ -1,6 +1,8 @@ #pragma once -void inflateInit(char* comprBuffer, char* uncomprBuffer, unsigned long uncomprBufferSize); +#include + +void inflateInit(uint8_t* comprBuffer, uint8_t* uncomprBuffer, unsigned long uncomprBufferSize); struct InflateOutput { bool needMoreInput; diff --git a/src/main.c b/src/main.c index 569345f..4182678 100644 --- a/src/main.c +++ b/src/main.c @@ -11,15 +11,15 @@ #include "inflate.h" #include "utils/min.h" -#define BUFFER_SIZE 512UL * 1024UL //512 KiB +#define BUFFER_SIZE 32UL * 1024UL //512 KiB #define ENCRYPTION_HEADER_LENGTH 12UL #define LOCAL_FILE_HEADER_MAGIC (uint32_t)0x04034b50 -uint16_t getUint16(char* buffer) { +uint16_t getUint16(uint8_t* buffer) { return (uint16_t)buffer[0] | \ (uint16_t)buffer[1] << 8; } -uint32_t getUint32(char* buffer) { +uint32_t getUint32(uint8_t* buffer) { return (uint32_t)buffer[0] | \ (uint32_t)buffer[1] << 8 | \ (uint32_t)buffer[2] << 16 | \ @@ -47,19 +47,19 @@ int main(int argc, unsigned char *argv[]) { //------------------------------------------------- - char* compressedChunk = malloc(BUFFER_SIZE); + uint8_t* compressedChunk = malloc(BUFFER_SIZE); if (compressedChunk == NULL) { fprintf(stderr, "Could not allocate %lu bytes for compressed buffer.\n", BUFFER_SIZE); exit(1); } + //memset(compressedChunk, (uint8_t)0, BUFFER_SIZE); - char* uncompressedChunk = malloc(BUFFER_SIZE); + uint8_t* uncompressedChunk = malloc(BUFFER_SIZE); if (uncompressedChunk == NULL) { fprintf(stderr, "Could not allocate %lu bytes for uncompressed buffer.\n", BUFFER_SIZE); exit(1); } - memset(compressedChunk, 0, BUFFER_SIZE); - memset(uncompressedChunk, 0, BUFFER_SIZE); + memset(uncompressedChunk, (uint8_t)0, BUFFER_SIZE); //------------------------------------------------- @@ -97,7 +97,7 @@ int main(int argc, unsigned char *argv[]) { while (remainingBytes > 0 || !hasReachedEnd) { if (needToRead) { chunkSize = min(BUFFER_SIZE, remainingBytes); - memset(compressedChunk, 0, chunkSize); + //memset(compressedChunk, 0, chunkSize); getBytes(compressedChunk, chunkSize); remainingBytes -= chunkSize; @@ -110,11 +110,12 @@ int main(int argc, unsigned char *argv[]) { //Decompress file //bytes are contained in uncompressedChunk from [0, inflateResult.numBytesWrittenToOutput - 1] - memset(uncompressedChunk, 0, BUFFER_SIZE); inflateResult = inflateInflate(needToRead ? chunkSize : 0, remainingBytes > 0); needToRead = inflateResult.needMoreInput; hasReachedEnd = inflateResult.hasReachedEnd; + //important: we must not modify uncompressedChunk since miniz may use it as dictionary and read from it during the next invocation of inflateInflate() + write(1, uncompressedChunk, inflateResult.numBytesWrittenToOutput); //Optionally perform xdelta3 diff --git a/src/utils/decryptUtilities.c b/src/utils/decryptUtilities.c index 2c88aca..dab1b39 100644 --- a/src/utils/decryptUtilities.c +++ b/src/utils/decryptUtilities.c @@ -46,16 +46,16 @@ const uint32_t crc32_tab[] = { 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; -uint32_t getCrc(uint32_t old_crc, unsigned char c) { -return (old_crc >> 8) ^ crc32_tab[(old_crc & 0xffU) ^ c]; +uint32_t getCrc(uint32_t old_crc, uint8_t c) { +return (old_crc >> 8) ^ crc32_tab[(old_crc & (uint32_t)0xff) ^ c]; } -void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, unsigned char c) { +void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, uint8_t c) { *key_0 = getCrc(*key_0, c); *key_1 = ((*key_1) + ((*key_0) & (uint32_t)0xffU)) * ((uint32_t)134775813U) + ((uint32_t)1U); *key_2 = getCrc(*key_2, (*key_1) >> 24); } -unsigned char decryptByte(uint16_t keyPart) { +uint8_t decryptByte(uint16_t keyPart) { return (keyPart * (keyPart ^ 1)) >> 8; } diff --git a/src/utils/decryptUtilities.h b/src/utils/decryptUtilities.h index 411fe5a..b9386f9 100644 --- a/src/utils/decryptUtilities.h +++ b/src/utils/decryptUtilities.h @@ -2,6 +2,6 @@ #include -void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, unsigned char c); +void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, uint8_t c); -unsigned char decryptByte(unsigned short keyPart); +uint8_t decryptByte(uint16_t keyPart); diff --git a/src/utils/fileUtilities.c b/src/utils/fileUtilities.c index 838c016..53786c0 100644 --- a/src/utils/fileUtilities.c +++ b/src/utils/fileUtilities.c @@ -8,7 +8,7 @@ //Reads the given amount of bytes from the currently open file into the given buffer. -void readBytesIntoBuffer(char* buffer, long numBytes) { +void readBytesIntoBuffer(uint8_t* buffer, long numBytes) { const size_t result = fread(buffer, 1, numBytes, file.filePointer); file.offset += result; diff --git a/src/utils/fileUtilities.h b/src/utils/fileUtilities.h index 0fc68ef..ffd3fd9 100644 --- a/src/utils/fileUtilities.h +++ b/src/utils/fileUtilities.h @@ -1,5 +1,7 @@ #pragma once +#include + //A structure to store various information needed when reading from a file. struct FILE_INFO { char* name; @@ -12,7 +14,7 @@ struct FILE_INFO file; //Reads the given amount of bytes from the currently open file into the given buffer. -void readBytesIntoBuffer(char* buffer, long numBytes); +void readBytesIntoBuffer(uint8_t* buffer, long numBytes); //Closes the currently opened file and opens the next file at its beginning.