From 3e9abd62c9e412c72cbf42d1ff4b7ff33f57161e Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Fri, 21 Oct 2022 23:50:22 +0200 Subject: [PATCH] feat: Remove brute-forcing the uncompressed size We figured out Fatshark's chunk sizes, so this is now unneeded complexity. --- oodle-cli.cpp | 115 +++++++++++++++----------------------------------- 1 file changed, 35 insertions(+), 80 deletions(-) diff --git a/oodle-cli.cpp b/oodle-cli.cpp index 5dc4b09..7b446ca 100644 --- a/oodle-cli.cpp +++ b/oodle-cli.cpp @@ -25,26 +25,22 @@ const char* LIB_FILE = "oo2core_8_win64.dll"; typedef decltype(OodleLZ_Decompress)* decompress_func; typedef decltype(OodleCore_Plugins_SetPrintf)* setprintf_func; -#define OK 0 -#define GENERIC_ERROR -1 -#define DECOMPRESS_ERROR -2 void usage() { std::cerr << "Usage: oodle-cli [OPTIONS] [--] \n" "Decompress a to using the Oodle algorithm.\n" - "The size of the uncompressed data must be known. If 0 is given, the tool will\n" - "attempt to brute-force the correct number by incrementing from the compressed size.\n" + "The size of the uncompressed data must be known.\n" "\n" "Options:\n" " -v Increase Oodle's verbosity. May be specified up to three times.\n" " -c Only check if the library can be found and used.\n" - " --guess When guessing the uncompressed size, a maximum number as multiple of the compressed size prevents an infinite loop. This changes the factor. Defaults to 10." "\n" "The following environmental variables are recognized:\n" " DLL_SEARCH_PATH: A color (':') separated list of directories to search for the Oodle library. May be relative to the current working directory.\n"; } + void printf_callback(int verboseLevel, const char* file, int line, const char* fmt, ...) { std::cout << "[OODLE] "; @@ -66,51 +62,11 @@ void printf_callback(int verboseLevel, const char* file, int line, const char* f vfprintf(stdout, fmt, args); } -int do_decompress(decompress_func decompress, std::vector compressed_buffer, std::string out_name, size_t raw_buffer_size, OodleLZ_Verbosity verbosity) { - std::vector raw_buffer(raw_buffer_size); - - intptr_t res = decompress( - compressed_buffer.data(), - compressed_buffer.size(), - raw_buffer.data(), - raw_buffer_size, - OodleLZ_FuzzSafe_Yes, - OodleLZ_CheckCRC_No, - verbosity, - nullptr, - 0, - nullptr, - nullptr, - nullptr, - 0, - OodleLZ_Decode_Unthreaded - ); - - if (res != raw_buffer_size) { - return DECOMPRESS_ERROR; - } - - std::ofstream out_file(out_name, std::ios::binary); - if (!out_file) { - std::cerr << "ERROR: Failed to open output file!\n"; - return GENERIC_ERROR; - } - - out_file.write(raw_buffer.data(), res); - - if (out_file.fail()) { - std::cerr << "ERROR: Failed to write output file!\n"; - return GENERIC_ERROR; - } - - return OK; -} int main(int argc, char* argv[]) { int verbosity = 0; bool check_lib = FALSE; - int guess_factor = 10; int i = 1; for (; i < argc; i++) { @@ -130,12 +86,10 @@ int main(int argc, char* argv[]) else if (strcmp(arg, "-v") == 0) { verbosity++; } - else if (strcmp(arg, "--guess") == 0) { - i++; - guess_factor = std::stoi(argv[i]); - } else { - std::cerr << "WARN: Unknown option '" << arg << "'!\n\n"; + std::cerr << "ERROR: Unknown option '" << arg << "'!\n\n"; + usage(); + return 1; } } @@ -225,40 +179,41 @@ int main(int argc, char* argv[]) return 1; } - if (raw_buffer_size > 0) { - int res = do_decompress(decompress, compressed_buffer, out_name, raw_buffer_size, (OodleLZ_Verbosity)verbosity); + std::vector raw_buffer(raw_buffer_size); - if (res == DECOMPRESS_ERROR) { - std::cerr << "ERROR: Failed to decompress!\n"; - return 1; - } - else if (res == GENERIC_ERROR) { - return 1; - } + intptr_t res = decompress( + compressed_buffer.data(), + compressed_buffer.size(), + raw_buffer.data(), + raw_buffer_size, + OodleLZ_FuzzSafe_Yes, + OodleLZ_CheckCRC_No, + (OodleLZ_Verbosity)verbosity, + nullptr, + 0, + nullptr, + nullptr, + nullptr, + 0, + OodleLZ_Decode_Unthreaded + ); + + if (res != raw_buffer_size) { + std::cerr << "ERROR: Failed to decompress!\n"; + return 1; } - else { - size_t guessed_size = compressed_buffer.size(); - // I need some maximum value to avoid infinite loops. The factor is configurable. - size_t max = guessed_size * guess_factor; - while (true) { - int res = do_decompress(decompress, compressed_buffer, out_name, guessed_size, (OodleLZ_Verbosity)verbosity); - - if (res == GENERIC_ERROR) { - return 1; - } - else if (res == OK) { - std::cout << "INFO: Found decompressed size as " << guessed_size << "\n"; - break; - } + std::ofstream out_file(out_name, std::ios::binary); + if (!out_file) { + std::cerr << "ERROR: Failed to open output file!\n"; + return 1; + } - guessed_size++; + out_file.write(raw_buffer.data(), res); - if (guessed_size > max) { - std::cerr << "ERROR: Exceeded maximum value for guessing uncompressed size!\n"; - return 1; - } - } + if (out_file.fail()) { + std::cerr << "ERROR: Failed to write output file!\n"; + return 1; } std::cout << "INFO: Done!\n";