From 1cd0ae5c87fb33125ce71cafa3f353095f00b1dc Mon Sep 17 00:00:00 2001 From: PixieCore <41352111+IcePixelx@users.noreply.github.com> Date: Sat, 6 Aug 2022 00:16:11 +0200 Subject: [PATCH] General code cleanup, Rebuild and hooked RTech::OpenFile * RTech std namespace removal * RTech::OpenFile Rebuild. * FileHandleTracker_t fully reversed, grabbing m_FileHandles from memory now. * RTech::FindFreeSlotInFiles needs more research. * --- r5dev/public/module.cpp | 4 +- r5dev/rtech/rtech_utils.cpp | 331 ++++++++++++++++++++---------------- r5dev/rtech/rtech_utils.h | 161 +++++++++++------- r5dev/vpklib/packedstore.h | 12 ++ 4 files changed, 294 insertions(+), 214 deletions(-) diff --git a/r5dev/public/module.cpp b/r5dev/public/module.cpp index 657da6f0..e2e9b567 100644 --- a/r5dev/public/module.cpp +++ b/r5dev/public/module.cpp @@ -260,7 +260,7 @@ CMemory CModule::GetExportedFunction(const string& svFunctionName) const CMemory CModule::GetVirtualMethodTable(const std::string& tableName) { const auto tableNameInfo = StringToMaskedBytes(tableName, false); - CMemory rttiTypeDescriptor = FindPatternSIMD(tableNameInfo.first.data(), tableNameInfo.second.c_str(), {".data", m_RunTimeData.m_pSectionBase, m_RunTimeData.m_nSectionSize}).OffsetSelf(-0x10); + CMemory rttiTypeDescriptor = FindPatternSIMD(tableNameInfo.first.data(), tableNameInfo.second.c_str(), { ".data", m_RunTimeData.m_pSectionBase, m_RunTimeData.m_nSectionSize }).OffsetSelf(-0x10); if (!rttiTypeDescriptor) return CMemory(); @@ -270,7 +270,7 @@ CMemory CModule::GetVirtualMethodTable(const std::string& tableName) const uintptr_t rttiTDRva = rttiTypeDescriptor.GetPtr() - m_pModuleBase; // The RTTI gets referenced by a 4-Byte RVA address. We need to scan for that address. while (scanStart < scanEnd) { - CMemory reference = FindPatternSIMD(reinterpret_cast(&rttiTDRva), "xxxx", {".rdata", scanStart, m_ReadOnlyData.m_nSectionSize}); + CMemory reference = FindPatternSIMD(reinterpret_cast(&rttiTDRva), "xxxx", { ".rdata", scanStart, m_ReadOnlyData.m_nSectionSize }); if (!reference) break; diff --git a/r5dev/rtech/rtech_utils.cpp b/r5dev/rtech/rtech_utils.cpp index face9775..272da61e 100644 --- a/r5dev/rtech/rtech_utils.cpp +++ b/r5dev/rtech/rtech_utils.cpp @@ -24,20 +24,20 @@ History: //----------------------------------------------------------------------------- // Purpose: calculate 'GUID' from input data //----------------------------------------------------------------------------- -std::uint64_t __fastcall RTech::StringToGuid(const char* pData) +uint64_t __fastcall RTech::StringToGuid(const char* pData) { - std::uint32_t* v1; // r8 - std::uint64_t v2; // r10 - std::int32_t v3; // er11 - std::uint32_t v4; // er9 - std::uint32_t i; // edx - std::uint64_t v6; // rcx - std::int32_t v7; // er9 - std::int32_t v8; // edx - std::int32_t v9; // eax - std::uint32_t v10; // er8 - std::int32_t v12; // ecx - std::uint32_t* a1 = (std::uint32_t*)pData; + uint32_t* v1; // r8 + uint64_t v2; // r10 + int32_t v3; // er11 + uint32_t v4; // er9 + uint32_t i; // edx + uint64_t v6; // rcx + int32_t v7; // er9 + int32_t v8; // edx + int32_t v9; // eax + uint32_t v10; // er8 + int32_t v12; // ecx + uint32_t* a1 = (uint32_t*)pData; v1 = a1; v2 = 0i64; @@ -49,7 +49,7 @@ std::uint64_t __fastcall RTech::StringToGuid(const char* pData) v7 = v1[1]; ++v1; v3 += 4; - v2 = ((((std::uint64_t)(0xFB8C4D96501i64 * v6) >> 24) + 0x633D5F1 * v2) >> 61) ^ (((std::uint64_t)(0xFB8C4D96501i64 * v6) >> 24) + v2 = ((((uint64_t)(0xFB8C4D96501i64 * v6) >> 24) + 0x633D5F1 * v2) >> 61) ^ (((uint64_t)(0xFB8C4D96501i64 * v6) >> 24) + 0x633D5F1 * v2); v8 = ~v7 & (v7 - 0x1010101); v4 = (v7 - 45 * ((~(v7 ^ 0x5C5C5C5Cu) >> 7) & (((v7 ^ 0x5C5C5C5Cu) - 0x1010101) >> 7) & 0x1010101)) & 0xDFDFDFDF; @@ -60,38 +60,38 @@ std::uint64_t __fastcall RTech::StringToGuid(const char* pData) { v9 = v12; } - return 0x633D5F1 * v2 + ((0xFB8C4D96501i64 * (std::uint64_t)(v4 & v10)) >> 24) - 0xAE502812AA7333i64 * (std::uint32_t)(v3 + v9 / 8); + return 0x633D5F1 * v2 + ((0xFB8C4D96501i64 * (uint64_t)(v4 & v10)) >> 24) - 0xAE502812AA7333i64 * (uint32_t)(v3 + v9 / 8); } //----------------------------------------------------------------------------- // Purpose: calculate 'decompressed' size and commit parameters //----------------------------------------------------------------------------- -std::uint64_t __fastcall RTech::DecompressPakFileInit(RPakDecompState_t* state, std::uint8_t* fileBuffer, std::uint64_t fileSize, std::uint64_t offNoHeader, std::uint64_t headerSize) +uint64_t __fastcall RTech::DecompressPakFileInit(RPakDecompState_t* state, uint8_t* fileBuffer, uint64_t fileSize, uint64_t offNoHeader, uint64_t headerSize) { - std::int64_t input_byte_pos_init; // r9 - std::uint64_t byte_init; // r11 - std::int32_t decompressed_size_bits; // ecx - std::int64_t byte_1_low; // rdi - std::uint64_t input_byte_pos_1; // r10 - std::uint32_t bit_pos_final; // ebp - std::uint64_t byte_1; // rdi - std::uint32_t brih_bits; // er11 - std::uint64_t inv_mask_in; // r8 - std::uint64_t byte_final_full; // rbx - std::uint64_t bit_pos_final_1; // rax - std::int32_t byte_bit_offset_final; // ebp - std::uint64_t input_byte_pos_final; // r10 - std::uint64_t byte_final; // rbx - std::uint32_t brih_bytes; // er11 - std::uint64_t byte_tmp; // rdx - std::uint64_t stream_len_needed; // r14 - std::uint64_t result; // rax - std::uint64_t inv_mask_out; // r8 - std::uint64_t qw70; // rcx - std::uint64_t stream_compressed_size_new; // rdx + int64_t input_byte_pos_init; // r9 + uint64_t byte_init; // r11 + int32_t decompressed_size_bits; // ecx + int64_t byte_1_low; // rdi + uint64_t input_byte_pos_1; // r10 + uint32_t bit_pos_final; // ebp + uint64_t byte_1; // rdi + uint32_t brih_bits; // er11 + uint64_t inv_mask_in; // r8 + uint64_t byte_final_full; // rbx + uint64_t bit_pos_final_1; // rax + int32_t byte_bit_offset_final; // ebp + uint64_t input_byte_pos_final; // r10 + uint64_t byte_final; // rbx + uint32_t brih_bytes; // er11 + uint64_t byte_tmp; // rdx + uint64_t stream_len_needed; // r14 + uint64_t result; // rax + uint64_t inv_mask_out; // r8 + uint64_t qw70; // rcx + uint64_t stream_compressed_size_new; // rdx - const std::uintptr_t mask = UINT64_MAX; - const std::uintptr_t file_buf = std::uintptr_t(fileBuffer); + const uintptr_t mask = UINT64_MAX; + const uintptr_t file_buf = uintptr_t(fileBuffer); state->m_nInputBuf = file_buf; state->m_nOut = 0i64; @@ -100,25 +100,25 @@ std::uint64_t __fastcall RTech::DecompressPakFileInit(RPakDecompState_t* state, state->m_nTotalFileLen = fileSize + offNoHeader; state->m_nMask = mask; input_byte_pos_init = offNoHeader + headerSize + 8; - byte_init = *(std::uint64_t*)((mask & (offNoHeader + headerSize)) + file_buf); + byte_init = *(uint64_t*)((mask & (offNoHeader + headerSize)) + file_buf); state->m_nDecompPosition = headerSize; decompressed_size_bits = byte_init & 0x3F; byte_init >>= 6; state->input_byte_pos = input_byte_pos_init; state->m_nDecompSize = byte_init & ((1i64 << decompressed_size_bits) - 1) | (1i64 << decompressed_size_bits); - byte_1_low = *(std::uint64_t*)((mask & input_byte_pos_init) + file_buf) << (64 - - ((std::uint8_t)decompressed_size_bits + byte_1_low = *(uint64_t*)((mask & input_byte_pos_init) + file_buf) << (64 + - ((uint8_t)decompressed_size_bits + 6)); - input_byte_pos_1 = input_byte_pos_init + ((std::uint64_t)(std::uint32_t)(decompressed_size_bits + 6) >> 3); + input_byte_pos_1 = input_byte_pos_init + ((uint64_t)(uint32_t)(decompressed_size_bits + 6) >> 3); state->input_byte_pos = input_byte_pos_1; bit_pos_final = ((decompressed_size_bits + 6) & 7) + 13; byte_1 = (0xFFFFFFFFFFFFFFFFui64 >> ((decompressed_size_bits + 6) & 7)) & ((byte_init >> decompressed_size_bits) | byte_1_low); - brih_bits = (((std::uint8_t)byte_1 - 1) & 0x3F) + 1; - inv_mask_in = 0xFFFFFFFFFFFFFFFFui64 >> (64 - (std::uint8_t)brih_bits); + brih_bits = (((uint8_t)byte_1 - 1) & 0x3F) + 1; + inv_mask_in = 0xFFFFFFFFFFFFFFFFui64 >> (64 - (uint8_t)brih_bits); state->m_nInvMaskIn = inv_mask_in; state->m_nInvMaskOut = 0xFFFFFFFFFFFFFFFFui64 >> (63 - (((byte_1 >> 6) - 1) & 0x3F)); - byte_final_full = (byte_1 >> 13) | (*(std::uint64_t*)((mask & input_byte_pos_1) + file_buf) << (64 - - (std::uint8_t)bit_pos_final)); + byte_final_full = (byte_1 >> 13) | (*(uint64_t*)((mask & input_byte_pos_1) + file_buf) << (64 + - (uint8_t)bit_pos_final)); bit_pos_final_1 = bit_pos_final; byte_bit_offset_final = bit_pos_final & 7; input_byte_pos_final = (bit_pos_final_1 >> 3) + input_byte_pos_1; @@ -133,9 +133,9 @@ std::uint64_t __fastcall RTech::DecompressPakFileInit(RPakDecompState_t* state, { brih_bytes = brih_bits >> 3; state->header_skip_bytes_bs = brih_bytes + 1; - byte_tmp = *(std::uint64_t*)((mask & input_byte_pos_final) + file_buf); + byte_tmp = *(uint64_t*)((mask & input_byte_pos_final) + file_buf); state->input_byte_pos = input_byte_pos_final + brih_bytes + 1; - stream_len_needed = byte_tmp & ((1i64 << (8 * ((std::uint8_t)brih_bytes + 1))) - 1); + stream_len_needed = byte_tmp & ((1i64 << (8 * ((uint8_t)brih_bytes + 1))) - 1); } result = state->m_nDecompSize; inv_mask_out = state->m_nInvMaskOut; @@ -160,65 +160,65 @@ std::uint64_t __fastcall RTech::DecompressPakFileInit(RPakDecompState_t* state, //----------------------------------------------------------------------------- // Purpose: decompress input data //----------------------------------------------------------------------------- -std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std::uint64_t inLen, std::uint64_t outLen) +uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, uint64_t inLen, uint64_t outLen) { - std::uint64_t decompressed_position; // r15 - std::uint32_t byte_bit_offset; // ebp - std::uint64_t byte; // rsi - std::uint64_t input_byte_pos; // rdi - std::uint64_t some_size; // r12 - std::uint32_t dword6C; // ecx MAPDST - std::uint64_t v12; // rsi - std::uint64_t i; // rax - std::uint64_t dword6c_shl8; // r8 - std::int64_t dword6c_old; // r9 - std::int32_t LUT_200_val; // ecx - std::uint64_t v17; // rax - std::uint64_t byte_new; // rsi - std::int64_t LUT_0_VAL; // r14 - std::int32_t byte_4bits_1; // ecx - std::uint64_t v21; // r11 - std::int32_t v22; // edx - std::uint64_t out_mask; // rax - std::int32_t v24; // er8 - std::uint32_t LUT_400_seek_backwards; // er13 - std::uint64_t out_seek_back; // r10 - std::uint64_t out_seekd_1; // rax - std::uint64_t* out_seekd_back; // r10 - std::uint64_t decompressed_size; // r9 - std::uint64_t inv_mask_in; // r10 - std::uint64_t header_skip_bytes_bs; // r8 - std::uint64_t v32; // rax - std::uint64_t v33; // rax - std::uint64_t v34; // rax - std::uint64_t stream_decompressed_size_new; // rcx - std::int64_t v36; // rdx - std::uint64_t len_needed_new; // r14 - std::uint64_t stream_compressed_size_new; // r11 + uint64_t decompressed_position; // r15 + uint32_t byte_bit_offset; // ebp + uint64_t byte; // rsi + uint64_t input_byte_pos; // rdi + uint64_t some_size; // r12 + uint32_t dword6C; // ecx MAPDST + uint64_t v12; // rsi + uint64_t i; // rax + uint64_t dword6c_shl8; // r8 + int64_t dword6c_old; // r9 + int32_t LUT_200_val; // ecx + uint64_t v17; // rax + uint64_t byte_new; // rsi + int64_t LUT_0_VAL; // r14 + int32_t byte_4bits_1; // ecx + uint64_t v21; // r11 + int32_t v22; // edx + uint64_t out_mask; // rax + int32_t v24; // er8 + uint32_t LUT_400_seek_backwards; // er13 + uint64_t out_seek_back; // r10 + uint64_t out_seekd_1; // rax + uint64_t* out_seekd_back; // r10 + uint64_t decompressed_size; // r9 + uint64_t inv_mask_in; // r10 + uint64_t header_skip_bytes_bs; // r8 + uint64_t v32; // rax + uint64_t v33; // rax + uint64_t v34; // rax + uint64_t stream_decompressed_size_new; // rcx + int64_t v36; // rdx + uint64_t len_needed_new; // r14 + uint64_t stream_compressed_size_new; // r11 char v39; // cl MAPDST - std::uint64_t v40; // rsi MAPDST + uint64_t v40; // rsi MAPDST uint64_t v46; // rcx - std::int64_t v47; // r9 - std::int64_t m; // r8 - std::uint32_t v49; // er9 - std::int64_t v50; // r8 - std::int64_t v51; // rdx - std::int64_t k; // r8 + int64_t v47; // r9 + int64_t m; // r8 + uint32_t v49; // er9 + int64_t v50; // r8 + int64_t v51; // rdx + int64_t k; // r8 char* v53; // r10 - std::int64_t v54; // rdx - std::uint32_t lut0_val_abs; // er14 - std::int64_t* in_seekd; // rdx - std::int64_t* out_seekd; // r8 - std::int64_t byte_3bits; // rax MAPDST - std::uint64_t byte_new_tmp; // r9 MAPDST - std::int32_t LUT_4D0_480; // er10 MAPDST - std::uint8_t LUT_4D8_4C0_nBits; // cl MAPDST - std::uint64_t byte_4bits; // rax MAPDST - std::uint32_t copy_bytes_ammount; // er14 - std::uint32_t j; // ecx - std::int64_t v67; // rax - std::uint64_t v68; // rcx - std::uint8_t result; // al + int64_t v54; // rdx + uint32_t lut0_val_abs; // er14 + int64_t* in_seekd; // rdx + int64_t* out_seekd; // r8 + int64_t byte_3bits; // rax MAPDST + uint64_t byte_new_tmp; // r9 MAPDST + int32_t LUT_4D0_480; // er10 MAPDST + uint8_t LUT_4D8_4C0_nBits; // cl MAPDST + uint64_t byte_4bits; // rax MAPDST + uint32_t copy_bytes_ammount; // er14 + uint32_t j; // ecx + int64_t v67; // rax + uint64_t v68; // rcx + uint8_t result; // al if (inLen < state->m_nLengthNeeded) return 0; @@ -238,27 +238,27 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: if (!byte_bit_offset) goto LABEL_9; - v12 = (*(std::uint64_t*)((input_byte_pos & state->m_nMask) + state->m_nInputBuf) << (64 - (std::uint8_t)byte_bit_offset)) | byte; + v12 = (*(uint64_t*)((input_byte_pos & state->m_nMask) + state->m_nInputBuf) << (64 - (uint8_t)byte_bit_offset)) | byte; for (i = byte_bit_offset; ; i = byte_bit_offset) { byte_bit_offset &= 7u; input_byte_pos += i >> 3; byte = (0xFFFFFFFFFFFFFFFFui64 >> byte_bit_offset) & v12; LABEL_9: - dword6c_shl8 = (std::uint64_t)dword6C << 8; + dword6c_shl8 = (uint64_t)dword6C << 8; dword6c_old = dword6C; - LUT_200_val = LUT_200[(std::uint8_t)byte + dword6c_shl8];// LUT_200 - u8 - ammount of bits - v17 = (std::uint8_t)byte + dword6c_shl8; + LUT_200_val = LUT_200[(uint8_t)byte + dword6c_shl8];// LUT_200 - u8 - ammount of bits + v17 = (uint8_t)byte + dword6c_shl8; byte_bit_offset += LUT_200_val; byte_new = byte >> LUT_200_val; LUT_0_VAL = LUT_0[v17];// LUT_0 - i32 - signed, ammount of bytes if (LUT_0_VAL < 0) { - lut0_val_abs = -(std::int32_t)LUT_0_VAL; - in_seekd = (std::int64_t*)(state->m_nInputBuf + (input_byte_pos & state->m_nMask)); + lut0_val_abs = -(int32_t)LUT_0_VAL; + in_seekd = (int64_t*)(state->m_nInputBuf + (input_byte_pos & state->m_nMask)); dword6C = 1; - out_seekd = (std::int64_t*)(state->m_nOut + (decompressed_position & state->m_nOutMask)); + out_seekd = (int64_t*)(state->m_nOut + (decompressed_position & state->m_nOutMask)); if (lut0_val_abs == LUT_4E0[dword6c_old]) { if ((~input_byte_pos & state->m_nInvMaskIn) < 0xF @@ -299,20 +299,20 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: if ((copy_bytes_ammount & 4) != 0) // copy by 4 { - *(std::uint32_t*)out_seekd = *(std::uint32_t*)in_seekd; - out_seekd = (std::int64_t*)((char*)out_seekd + 4); - in_seekd = (std::int64_t*)((char*)in_seekd + 4); + *(uint32_t*)out_seekd = *(uint32_t*)in_seekd; + out_seekd = (int64_t*)((char*)out_seekd + 4); + in_seekd = (int64_t*)((char*)in_seekd + 4); } if ((copy_bytes_ammount & 2) != 0) // copy by 2 { - *(std::uint16_t*)out_seekd = *(std::uint16_t*)in_seekd; - out_seekd = (std::int64_t*)((char*)out_seekd + 2); - in_seekd = (std::int64_t*)((char*)in_seekd + 2); + *(uint16_t*)out_seekd = *(uint16_t*)in_seekd; + out_seekd = (int64_t*)((char*)out_seekd + 2); + in_seekd = (int64_t*)((char*)in_seekd + 2); } if ((copy_bytes_ammount & 1) != 0) // copy by 1 - *(std::uint8_t*)out_seekd = *(std::uint8_t*)in_seekd; + *(uint8_t*)out_seekd = *(uint8_t*)in_seekd; input_byte_pos += copy_bytes_ammount; decompressed_position += copy_bytes_ammount; @@ -329,26 +329,26 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: { byte_4bits_1 = byte_new & 0xF; dword6C = 0; - v21 = ((std::uint64_t)(std::uint32_t)byte_new >> (((std::uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6)) & 0x3F;// 6 bits after shift for who knows how much??? - v22 = 1 << (byte_4bits_1 + ((byte_new >> 4) & ((24 * (((std::uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 2)) >> 4)));// ammount of bits to read??? - byte_bit_offset += (((std::uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6)// shit shit gets shifted by ammount of bits it read or something + v21 = ((uint64_t)(uint32_t)byte_new >> (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6)) & 0x3F;// 6 bits after shift for who knows how much??? + v22 = 1 << (byte_4bits_1 + ((byte_new >> 4) & ((24 * (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 2)) >> 4)));// ammount of bits to read??? + byte_bit_offset += (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6)// shit shit gets shifted by ammount of bits it read or something + LUT_440[v21] + byte_4bits_1 - + ((byte_new >> 4) & ((24 * (((std::uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 2)) >> 4)); + + ((byte_new >> 4) & ((24 * (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 2)) >> 4)); out_mask = state->m_nOutMask; v24 = 16 * (v22 - + ((v22 - 1) & (byte_new >> ((((std::uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6) + + ((v22 - 1) & (byte_new >> ((((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6) + LUT_440[v21])))); - byte_new >>= (((std::uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6) + byte_new >>= (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6) + LUT_440[v21] + byte_4bits_1 - + ((byte_new >> 4) & ((24 * (((std::uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 2)) >> 4)); + + ((byte_new >> 4) & ((24 * (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 2)) >> 4)); LUT_400_seek_backwards = v24 + LUT_400[v21] - 16;// LUT_400 - u8 - seek backwards out_seek_back = out_mask & (decompressed_position - LUT_400_seek_backwards); out_seekd_1 = state->m_nOut + (decompressed_position & out_mask); - out_seekd_back = (std::uint64_t*)(state->m_nOut + out_seek_back); - if ((std::int32_t)LUT_0_VAL == 17) + out_seekd_back = (uint64_t*)(state->m_nOut + out_seek_back); + if ((int32_t)LUT_0_VAL == 17) { v39 = byte_new; v40 = byte_new >> 3; @@ -369,14 +369,14 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: if (state->m_nInputBuf && byte_bit_offset + LUT_4D8_4C0_nBits >= 0x3D) { v46 = input_byte_pos++ & state->m_nMask; - byte_new_tmp |= (std::uint64_t) * (std::uint8_t*)(v46 + state->m_nInputBuf) << (61 - - (std::uint8_t)byte_bit_offset); + byte_new_tmp |= (uint64_t) * (uint8_t*)(v46 + state->m_nInputBuf) << (61 + - (uint8_t)byte_bit_offset); byte_bit_offset -= 8; } } byte_bit_offset += LUT_4D8_4C0_nBits + 3; byte_new = byte_new_tmp >> LUT_4D8_4C0_nBits; - v47 = ((std::uint32_t)byte_new_tmp & ((1 << LUT_4D8_4C0_nBits) - 1)) + LUT_4D0_480 + 17; + v47 = ((uint32_t)byte_new_tmp & ((1 << LUT_4D8_4C0_nBits) - 1)) + LUT_4D0_480 + 17; decompressed_position += v47; if (LUT_400_seek_backwards < 8) { @@ -384,10 +384,10 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: decompressed_position -= 13i64; if (LUT_400_seek_backwards == 1) // 1 means copy v49 qwords? { - v50 = *(std::uint8_t*)out_seekd_back; + v50 = *(uint8_t*)out_seekd_back; v51 = 0i64; - for (k = 0x101010101010101i64 * v50; (std::uint32_t)v51 < v49; v51 = (std::uint32_t)(v51 + 8)) - *(std::uint64_t*)(v51 + out_seekd_1) = k; + for (k = 0x101010101010101i64 * v50; (uint32_t)v51 < v49; v51 = (uint32_t)(v51 + 8)) + *(uint64_t*)(v51 + out_seekd_1) = k; } else { @@ -397,7 +397,7 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: v54 = v49; do { - *(std::uint8_t*)out_seekd_1 = v53[out_seekd_1];// seekd = seek_back; increment ptrs + *(uint8_t*)out_seekd_1 = v53[out_seekd_1];// seekd = seek_back; increment ptrs ++out_seekd_1; --v54; } while (v54); @@ -406,22 +406,22 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: } else { - for (m = 0i64; (std::uint32_t)m < (std::uint32_t)v47; m = (std::uint32_t)(m + 8)) - *(std::uint64_t*)(m + out_seekd_1) = *(std::uint64_t*)((char*)out_seekd_back + m); + for (m = 0i64; (uint32_t)m < (uint32_t)v47; m = (uint32_t)(m + 8)) + *(uint64_t*)(m + out_seekd_1) = *(uint64_t*)((char*)out_seekd_back + m); } } else { decompressed_position += LUT_0_VAL; - *(std::uint64_t*)out_seekd_1 = *out_seekd_back; - *(std::uint64_t*)(out_seekd_1 + 8) = out_seekd_back[1]; + *(uint64_t*)out_seekd_1 = *out_seekd_back; + *(uint64_t*)(out_seekd_1 + 8) = out_seekd_back[1]; } } if (input_byte_pos >= some_size) break; LABEL_26: - v12 = (*(std::uint64_t*)((input_byte_pos & state->m_nMask) + state->m_nInputBuf) << (64 - (std::uint8_t)byte_bit_offset)) | byte_new; + v12 = (*(uint64_t*)((input_byte_pos & state->m_nMask) + state->m_nInputBuf) << (64 - (uint8_t)byte_bit_offset)) | byte_new; } if (decompressed_position != state->m_nDecompStreamSize) @@ -438,7 +438,7 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: inv_mask_in = state->m_nInvMaskIn; header_skip_bytes_bs = state->header_skip_bytes_bs; - v32 = inv_mask_in & -(std::int64_t)input_byte_pos; + v32 = inv_mask_in & -(int64_t)input_byte_pos; byte_new >>= 1; ++byte_bit_offset; @@ -453,7 +453,7 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: v34 = input_byte_pos & state->m_nMask; input_byte_pos += header_skip_bytes_bs; stream_decompressed_size_new = decompressed_position + state->m_nInvMaskOut + 1; - v36 = *(std::uint64_t*)(v34 + state->m_nInputBuf) & ((1LL << (8 * (std::uint8_t)header_skip_bytes_bs)) - 1); + v36 = *(uint64_t*)(v34 + state->m_nInputBuf) & ((1LL << (8 * (uint8_t)header_skip_bytes_bs)) - 1); len_needed_new = v36 + state->m_nLengthNeeded; stream_compressed_size_new = v36 + state->m_nCompressedStreamSize; state->m_nLengthNeeded = len_needed_new; @@ -517,7 +517,7 @@ void RTech::CreateDXTexture(RTechTextureInfo_t* textureHeader, int64_t imageData __int64 initialData[4096]{}; textureHeader->m_nTextureMipLevels = textureHeader->m_nMipLevels; - int totalStreamedMips = textureHeader->m_nMipLevelsStreamedOpt + textureHeader->m_nMipLevelsStreamed; + const int totalStreamedMips = textureHeader->m_nMipLevelsStreamedOpt + textureHeader->m_nMipLevelsStreamed; uint32_t mipLevel = textureHeader->m_nMipLevels + totalStreamedMips; if (mipLevel != totalStreamedMips) { @@ -560,7 +560,7 @@ void RTech::CreateDXTexture(RTechTextureInfo_t* textureHeader, int64_t imageData } while (mipLevel != totalStreamedMips); } - DXGI_FORMAT dxgiFormat = rpakToDxgiFormat[textureHeader->m_nFormat]; // Get dxgi format + const DXGI_FORMAT dxgiFormat = rpakToDxgiFormat[textureHeader->m_nFormat]; // Get dxgi format D3D11_TEXTURE2D_DESC textureDesc{}; textureDesc.Width = textureHeader->m_nWidth >> mipLevel; @@ -574,9 +574,9 @@ void RTech::CreateDXTexture(RTechTextureInfo_t* textureHeader, int64_t imageData textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; textureDesc.MiscFlags = 0; - uint32_t offsetStartResourceData = mipLevel << 4u; - D3D11_SUBRESOURCE_DATA* subResData = (D3D11_SUBRESOURCE_DATA*)((uint8_t*)initialData + offsetStartResourceData); - HRESULT createTextureRes = (*g_ppGameDevice)->CreateTexture2D(&textureDesc, subResData, &textureHeader->m_ppTexture); + const uint32_t offsetStartResourceData = mipLevel << 4u; + const D3D11_SUBRESOURCE_DATA* subResData = (D3D11_SUBRESOURCE_DATA*)((uint8_t*)initialData + offsetStartResourceData); + const HRESULT createTextureRes = (*g_ppGameDevice)->CreateTexture2D(&textureDesc, subResData, &textureHeader->m_ppTexture); if (createTextureRes < S_OK) Error(eDLL_T::RTECH, "Couldn't create texture \"%s\": error code %08x\n", textureHeader->m_nDebugName, createTextureRes); @@ -594,7 +594,7 @@ void RTech::CreateDXTexture(RTechTextureInfo_t* textureHeader, int64_t imageData shaderResource.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; } - HRESULT createShaderResourceRes = (*g_ppGameDevice)->CreateShaderResourceView(textureHeader->m_ppTexture, &shaderResource, &textureHeader->m_ppShaderResourceView); + const HRESULT createShaderResourceRes = (*g_ppGameDevice)->CreateShaderResourceView(textureHeader->m_ppTexture, &shaderResource, &textureHeader->m_ppShaderResourceView); if (createShaderResourceRes < S_OK) Error(eDLL_T::RTECH, "Couldn't create shader resource view for texture \"%s\": error code %08x\n", textureHeader->m_nDebugName, createShaderResourceRes); } @@ -602,6 +602,9 @@ void RTech::CreateDXTexture(RTechTextureInfo_t* textureHeader, int64_t imageData #endif #ifndef DEDICATED +//---------------------------------------------------------------------------------- +// Purpose: start loading shader sets, assign vtable pointer +//---------------------------------------------------------------------------------- void** RTech::LoadShaderSet(void** VTablePtr) { *VTablePtr = &g_pCShaderGlue_VTable; @@ -609,6 +612,35 @@ void** RTech::LoadShaderSet(void** VTablePtr) } #endif +//---------------------------------------------------------------------------------- +// Purpose: open a file and add it to m_FileHandles. +//---------------------------------------------------------------------------------- +int32_t RTech::OpenFile(const char* szFilePath, void* unused, int64_t* fileSizeOut) +{ + const HANDLE hFile = CreateFileA(szFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_SUPPORTS_GHOSTING, 0); + if (hFile == INVALID_HANDLE_VALUE) + return -1; + + if (fileSizeOut) + { + LARGE_INTEGER fileSize{}; + if (GetFileSizeEx(hFile, &fileSize)) + *fileSizeOut = fileSize.QuadPart; + } + + AcquireSRWLockExclusive(reinterpret_cast(&*g_pPakFileSlotLock)); + const int32_t pakIdx = RTech_FindFreeSlotInFiles(s_pFileArray); + ReleaseSRWLockExclusive(reinterpret_cast(&*g_pPakFileSlotLock)); + + const int32_t pakHandleIdx = pakIdx & 0x3FF; // Something with ArraySize. + + m_FileHandles->self[pakHandleIdx].m_nFileNumber = pakIdx; + m_FileHandles->self[pakHandleIdx].m_hFileHandle = hFile; + m_FileHandles->self[pakHandleIdx].m_nCurOfs = 1; + + return pakIdx; +} + //----------------------------------------------------------------------------- // Purpose: gets information about loaded pak file via pak ID //----------------------------------------------------------------------------- @@ -656,6 +688,8 @@ RPakLoadedInfo_t* RTech::GetPakLoadedInfo(const char* szPakName) void RTech_Utils_Attach() { + DetourAttach((LPVOID*)&RTech_OpenFile, &RTech::OpenFile); + #if not defined DEDICATED && defined (GAMEDLL_S3) DetourAttach((LPVOID*)&RTech_CreateDXTexture, &RTech::CreateDXTexture); #endif @@ -663,6 +697,9 @@ void RTech_Utils_Attach() void RTech_Utils_Detach() { + // [ PIXIE ]: Everything related to RTech::OpenFile should be compatible across seasons. + DetourDetach((LPVOID*)&RTech_OpenFile, &RTech::OpenFile); + #if not defined DEDICATED && defined (GAMEDLL_S3) DetourDetach((LPVOID*)&RTech_CreateDXTexture, &RTech::CreateDXTexture); #endif diff --git a/r5dev/rtech/rtech_utils.h b/r5dev/rtech/rtech_utils.h index 1e688631..cff238c4 100644 --- a/r5dev/rtech/rtech_utils.h +++ b/r5dev/rtech/rtech_utils.h @@ -1,5 +1,5 @@ #pragma once - +#include "vpklib/packedstore.h" #define PAK_PARAM_SIZE 0xB0 #define DCMP_BUF_SIZE 0x400000 @@ -46,7 +46,7 @@ inline std::array LUT_4E0 }; #pragma warning( pop ) -enum class RPakStatus_t : std::int32_t +enum class RPakStatus_t : int32_t { PAK_STATUS_FREED = 0, PAK_STATUS_LOAD_PENDING = 1, @@ -66,7 +66,7 @@ enum class RPakStatus_t : std::int32_t PAK_STATUS_BUSY = 15 }; -const std::map RPakStatusToString { +const std::map RPakStatusToString { { RPakStatus_t::PAK_STATUS_FREED, "PAK_STATUS_FREED" }, { RPakStatus_t::PAK_STATUS_LOAD_PENDING, "PAK_STATUS_LOAD_PENDING" }, { RPakStatus_t::PAK_STATUS_REPAK_RUNNING, "PAK_STATUS_REPAK_RUNNING" }, @@ -109,60 +109,60 @@ struct RPakUnknownStruct_t struct RPakHeader_t { - std::uint32_t m_nMagic; // 'RPak' - std::uint16_t m_nVersion; // R2 = '7' R5 = '8' - std::uint8_t m_nFlags[0x2]; // - std::uint8_t m_nHash0[0x8]; // - std::uint8_t m_nHash1[0x8]; // - std::uint64_t m_nSizeDisk; // Compressed size - std::uint64_t m_nEmbeddedStarpakOffset; // - std::uint8_t unk0[0x8]; // - std::uint64_t m_nSizeMemory; // Decompressed size - std::uint64_t m_nEmbeddedStarpakSize; // - std::uint8_t unk1[0x8]; // + uint32_t m_nMagic; // 'RPak' + uint16_t m_nVersion; // R2 = '7' R5 = '8' + uint8_t m_nFlags[0x2]; // + uint8_t m_nHash0[0x8]; // + uint8_t m_nHash1[0x8]; // + uint64_t m_nSizeDisk; // Compressed size + uint64_t m_nEmbeddedStarpakOffset; // + uint8_t unk0[0x8]; // + uint64_t m_nSizeMemory; // Decompressed size + uint64_t m_nEmbeddedStarpakSize; // + uint8_t unk1[0x8]; // - std::uint16_t m_nStarpakReferenceSize; // - std::uint16_t m_nStarpakOptReferenceSize; // - std::uint16_t m_nVirtualSegmentCount; // * 0x10 - std::uint16_t m_nVirtualSegmentBlockCount; // * 0xC + uint16_t m_nStarpakReferenceSize; // + uint16_t m_nStarpakOptReferenceSize; // + uint16_t m_nVirtualSegmentCount; // * 0x10 + uint16_t m_nVirtualSegmentBlockCount; // * 0xC - std::uint32_t m_nPatchIndex; // + uint32_t m_nPatchIndex; // - std::uint32_t m_nDescriptorCount; // - std::uint32_t m_nAssetEntryCount; // File entry count - std::uint32_t m_nGuidDescriptorCount; // - std::uint32_t m_nRelationsCounts; // + uint32_t m_nDescriptorCount; // + uint32_t m_nAssetEntryCount; // File entry count + uint32_t m_nGuidDescriptorCount; // + uint32_t m_nRelationsCounts; // - std::uint8_t unk2[0x1C]; // + uint8_t unk2[0x1C]; // }; struct __declspec(align(8)) RPakPatchCompressedHeader_t { - std::uint64_t m_nSizeDisk; - std::uint64_t m_nSizeMemory; + uint64_t m_nSizeDisk; + uint64_t m_nSizeMemory; }; struct __declspec(align(8)) RPakDecompState_t { - std::uint64_t m_nInputBuf; - std::uint64_t m_nOut; - std::uint64_t m_nMask; - std::uint64_t m_nOutMask; - std::uint64_t m_nTotalFileLen; - std::uint64_t m_nDecompSize; - std::uint64_t m_nInvMaskIn; - std::uint64_t m_nInvMaskOut; - std::uint32_t header_skip_bytes_bs; - std::uint32_t dword44; - std::uint64_t input_byte_pos; - std::uint64_t m_nDecompPosition; - std::uint64_t m_nLengthNeeded; - std::uint64_t byte; - std::uint32_t byte_bit_offset; - std::uint32_t dword6C; - std::uint64_t qword70; - std::uint64_t m_nCompressedStreamSize; - std::uint64_t m_nDecompStreamSize; + uint64_t m_nInputBuf; + uint64_t m_nOut; + uint64_t m_nMask; + uint64_t m_nOutMask; + uint64_t m_nTotalFileLen; + uint64_t m_nDecompSize; + uint64_t m_nInvMaskIn; + uint64_t m_nInvMaskOut; + uint32_t header_skip_bytes_bs; + uint32_t dword44; + uint64_t input_byte_pos; + uint64_t m_nDecompPosition; + uint64_t m_nLengthNeeded; + uint64_t byte; + uint32_t byte_bit_offset; + uint32_t dword6C; + uint64_t qword70; + uint64_t m_nCompressedStreamSize; + uint64_t m_nDecompStreamSize; }; #if not defined DEDICATED && defined (GAMEDLL_S3) @@ -431,19 +431,19 @@ static std::map rpakToDxgiFormat { class RPakLoadedInfo_t { public: - std::int32_t m_nPakId; //0x0000 + int32_t m_nPakId; //0x0000 RPakStatus_t m_nStatus; //0x0004 - std::uint64_t m_nUnk1; //0x0008 - std::uint32_t m_nUnk2; //0x0010 - std::uint32_t m_nAssetCount; //0x0014 + uint64_t m_nUnk1; //0x0008 + uint32_t m_nUnk2; //0x0010 + uint32_t m_nAssetCount; //0x0014 char* m_pszFileName; //0x0018 void* m_pMalloc; //0x0020 - std::uint64_t* m_pAssetGuids; //0x0028 size of the array is m_nAssetCount + uint64_t* m_pAssetGuids; //0x0028 size of the array is m_nAssetCount char pad_0030[128]; //0x0030 #ifndef GAMEDLL_S3 char pad_00B0[48]; #endif // !GAMEDLL_S3 - std::uint64_t m_nUnkEnd; //0x00B0 + uint64_t m_nUnkEnd; //0x00B0 }; //Size: 0x00B8/0x00E8 /* ==== RTECH =========================================================================================================================================================== */ @@ -455,21 +455,33 @@ inline CMemory p_GetStreamOverlay; inline auto GetStreamOverlay = p_GetStreamOverlay.RCast(); #endif +// [ PIXIE ]: I'm very unsure about this, but it really seems like it +inline CMemory p_RTech_FindFreeSlotInFiles; +inline auto RTech_FindFreeSlotInFiles = p_RTech_FindFreeSlotInFiles.RCast(); + +inline CMemory p_RTech_OpenFile; +inline auto RTech_OpenFile = p_RTech_OpenFile.RCast(); + inline RPakLoadedInfo_t* g_pLoadedPakInfo; -inline std::int16_t* s_pLoadedPakCount; +inline int16_t* s_pLoadedPakCount; inline RPakUnknownStruct_t* g_pUnknownPakStruct; +inline int32_t* s_pFileArray; +inline PSRWLOCK* g_pPakFileSlotLock; +inline pFileHandleTracker_t* m_FileHandles; + class RTech { public: - std::uint64_t __fastcall StringToGuid(const char* pData); - std::uint8_t __fastcall DecompressPakFile(RPakDecompState_t* state, std::uint64_t inLen, std::uint64_t outLen); - std::uint64_t __fastcall DecompressPakFileInit(RPakDecompState_t* state, std::uint8_t* fileBuffer, std::uint64_t fileSize, std::uint64_t offNoHeader, std::uint64_t headerSize); + uint64_t __fastcall StringToGuid(const char* pData); + uint8_t __fastcall DecompressPakFile(RPakDecompState_t* state, uint64_t inLen, uint64_t outLen); + uint64_t __fastcall DecompressPakFileInit(RPakDecompState_t* state, uint8_t* fileBuffer, uint64_t fileSize, uint64_t offNoHeader, uint64_t headerSize); RPakLoadedInfo_t* GetPakLoadedInfo(int nPakId); RPakLoadedInfo_t* GetPakLoadedInfo(const char* szPakName); + static int32_t OpenFile(const char* szFilePath, void* unused, int64_t* fileSizeOut); #if not defined DEDICATED && defined (GAMEDLL_S3) - static void __fastcall CreateDXTexture(RTechTextureInfo_t* textureHeader, int64_t cpuArg); + static void CreateDXTexture(RTechTextureInfo_t* textureHeader, int64_t cpuArg); #endif #ifndef DEDICATED @@ -488,27 +500,46 @@ class VPakFile : public IDetour { virtual void GetAdr(void) const { - spdlog::debug("| VAR: g_pLoadedPakInfo : {:#18x} |\n", reinterpret_cast(g_pLoadedPakInfo )); + spdlog::debug("| FUN: GetStreamOverlay : {:#18x} |\n", p_GetStreamOverlay.GetPtr()); + spdlog::debug("| FUN: RTech::CreateDXTexture : {:#18x} |\n", p_RTech_CreateDXTexture.GetPtr()); + spdlog::debug("| FUN: RTech::FindFreeSlotInFiles : {:#18x} |\n", p_RTech_FindFreeSlotInFiles.GetPtr()); + spdlog::debug("| FUN: RTech::OpenFile : {:#18x} |\n", p_RTech_OpenFile.GetPtr()); + spdlog::debug("| VAR: g_pLoadedPakInfo : {:#18x} |\n", reinterpret_cast(g_pLoadedPakInfo)); spdlog::debug("| VAR: s_pLoadedPakCount : {:#18x} |\n", reinterpret_cast(s_pLoadedPakCount)); + spdlog::debug("| VAR: s_pFileArray : {:#18x} |\n", reinterpret_cast(s_pFileArray)); + spdlog::debug("| VAR: g_pPakFileSlotLock : {:#18x} |\n", reinterpret_cast(g_pPakFileSlotLock)); + spdlog::debug("| VAR: m_FileHandles : {:#18x} |\n", reinterpret_cast(m_FileHandles)); + spdlog::debug("| VAR: g_pUnknownPakStruct : {:#18x} |\n", reinterpret_cast(g_pUnknownPakStruct)); spdlog::debug("+----------------------------------------------------------------+\n"); } virtual void GetFun(void) const { #if not defined DEDICATED && defined (GAMEDLL_S3) - p_RTech_CreateDXTexture = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xE8\x00\x00\x00\x00\x4C\x8B\xC7\x48\x8B\xD5\x48\x8B\xCB\x48\x83\xC4\x60"), "x????xxxxxxxxxxxxx").FollowNearCallSelf(); - RTech_CreateDXTexture = p_RTech_CreateDXTexture.RCast(); /*E8 ? ? ? ? 4C 8B C7 48 8B D5 48 8B CB 48 83 C4 60*/ - p_GetStreamOverlay = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xE8\x00\x00\x00\x00\x80\x7C\x24\x00\x00\x0F\x84\x00\x00\x00\x00\x48\x89\x9C\x24\x00\x00\x00\x00"), "x????xxx??xx????xxxx????").FollowNearCallSelf(); - GetStreamOverlay = p_GetStreamOverlay.RCast(); + GetStreamOverlay = p_GetStreamOverlay.RCast(); /*E8 ? ? ? ? 80 7C 24 ? ? 0F 84 ? ? ? ? 48 89 9C 24 ? ? ? ?*/ + + p_RTech_CreateDXTexture = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xE8\x00\x00\x00\x00\x4C\x8B\xC7\x48\x8B\xD5\x48\x8B\xCB\x48\x83\xC4\x60"), "x????xxxxxxxxxxxxx").FollowNearCallSelf(); + RTech_CreateDXTexture = p_RTech_CreateDXTexture.RCast(); /*E8 ? ? ? ? 4C 8B C7 48 8B D5 48 8B CB 48 83 C4 60*/ #endif + p_RTech_FindFreeSlotInFiles = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x44\x8B\x51\x0C\x4C\x8B\xC1"), "xxxxxxx"); + RTech_FindFreeSlotInFiles = p_RTech_FindFreeSlotInFiles.RCast(); /*44 8B 51 0C 4C 8B C1*/ + + p_RTech_OpenFile = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xE8\x00\x00\x00\x00\x89\x85\x08\x01\x00\x00"), "x????xxxxxx").FollowNearCallSelf(); + RTech_OpenFile = p_RTech_OpenFile.RCast(); /*E8 ? ? ? ? 89 85 08 01 00 00*/ } virtual void GetVar(void) const { - g_pUnknownPakStruct = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8D\x1D\x00\x00\x00\x00\x45\x8D\x5A\x0E"), "xxx????xxxx").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); /*48 8D 1D ? ? ? ? 45 8D 5A 0E*/ - CMemory RTech_UnloadPak = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x8B\xC1"), "xxxx?xxxx?xxxxxxx"); - g_pLoadedPakInfo = RTech_UnloadPak.FindPattern("48 8D 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - s_pLoadedPakCount = RTech_UnloadPak.FindPattern("66 89", CMemory::Direction::DOWN, 450).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_pLoadedPakInfo = RTech_UnloadPak.FindPattern("48 8D 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + s_pLoadedPakCount = RTech_UnloadPak.FindPattern("66 89", CMemory::Direction::DOWN, 450).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + + /*48 8D 0D ? ? ? ? E8 ? ? ? ? 48 8D 0D ? ? ? ? 8B D8 FF 15 ? ? ? ? 4C 8D 25 ? ? ? ?*/ + CMemory Offset_StreamDB_Init = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\x8B\xD8\xFF\x15\x00\x00\x00\x00\x4C\x8D\x25\x00\x00\x00\x00"), "xxx????x????xxx????xxxx????xxx????"); + s_pFileArray = Offset_StreamDB_Init.ResolveRelativeAddress(0x3, 0x7).RCast(); + g_pPakFileSlotLock = Offset_StreamDB_Init.Offset(-0xD).ResolveRelativeAddress(0x3, 0x7).RCast(); + m_FileHandles = Offset_StreamDB_Init.Offset(0x1B).ResolveRelativeAddress(0x3, 0x7).RCast(); + + g_pUnknownPakStruct = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8D\x1D\x00\x00\x00\x00\x45\x8D\x5A\x0E"), "xxx????xxxx").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); /*48 8D 1D ? ? ? ? 45 8D 5A 0E*/ } virtual void GetCon(void) const { } virtual void Attach(void) const { } diff --git a/r5dev/vpklib/packedstore.h b/r5dev/vpklib/packedstore.h index c549c674..93f4618c 100644 --- a/r5dev/vpklib/packedstore.h +++ b/r5dev/vpklib/packedstore.h @@ -28,6 +28,18 @@ enum class EPackedTextureFlags : short TEXTURE_ENVIRONMENT_MAP = 1 << 10, }; +struct FileHandleTracker_t +{ + int m_nFileNumber; + int m_nCurOfs; + HANDLE m_hFileHandle; +}; + +struct pFileHandleTracker_t +{ + FileHandleTracker_t self[1024]; +}; + #pragma pack(push, 1) struct VPKFileEntry_t {