Skip to content

Instantly share code, notes, and snippets.

@Alyinghood
Last active January 17, 2024 12:29
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Alyinghood/e1052b715426320257d7591613ad740a to your computer and use it in GitHub Desktop.
Save Alyinghood/e1052b715426320257d7591613ad740a to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
// This doesn't work properly in all cases. You would be better off using https://gist.github.com/Alyinghood/21bdb81d6f83114604082bd019482ae3 instead
// See https://forums.nrvnqsr.com/showthread.php/9708-Mahoutsukai-no-Yoru-HD-PC-file-format-deciphering
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#define __int8 char
#define __int16 short
#define __int32 int
#define __int64 long long
#define x_sub_7FF6BF52C1F0_memset memset
#define qmemcpy memcpy
#define x_sub_7FF6BF52BD90_memcpy memcpy
#define x_sub_7FF6BF50D8FC_malloc malloc
#define x_sub_7FF6BF50D4C4_free free
#ifndef __cdecl
#define __cdecl
#endif
#define __fastcall
#ifndef _WIN32
typedef uint8_t BYTE;
typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef uint64_t QWORD;
#endif
typedef uint8_t _BYTE;
typedef uint16_t _WORD;
typedef uint32_t _DWORD;
typedef uint64_t _QWORD;
#define LAST_IND(x,part_type) (sizeof(x)/sizeof(part_type) - 1)
#define HIGH_IND(x,part_type) LAST_IND(x,part_type)
#define LOW_IND(x,part_type) 0
#define BYTEn(x, n) (*((_BYTE*)&(x)+n))
#define WORDn(x, n) (*((_WORD*)&(x)+n))
#define DWORDn(x, n) (*((_DWORD*)&(x)+n))
#ifdef LOBYTE
#undef LOBYTE
#endif
#define LOBYTE(x) BYTEn(x,LOW_IND(x,_BYTE))
#ifdef LOWORD
#undef LOWORD
#endif
#define LOWORD(x) WORDn(x,LOW_IND(x,_WORD))
#define LODWORD(x) DWORDn(x,LOW_IND(x,_DWORD))
#ifdef HIBYTE
#undef HIBYTE
#endif
#define HIBYTE(x) BYTEn(x,HIGH_IND(x,_BYTE))
#ifdef HIWORD
#undef HIWORD
#endif
#define HIWORD(x) WORDn(x,HIGH_IND(x,_WORD))
#define HIDWORD(x) DWORDn(x,HIGH_IND(x,_DWORD))
#define BYTE1(x) BYTEn(x, 1)
#define BYTE2(x) BYTEn(x, 2)
#define BYTE3(x) BYTEn(x, 3)
#define BYTE4(x) BYTEn(x, 4)
#define BYTE5(x) BYTEn(x, 5)
#define BYTE6(x) BYTEn(x, 6)
#define BYTE7(x) BYTEn(x, 7)
#define BYTE8(x) BYTEn(x, 8)
#define BYTE9(x) BYTEn(x, 9)
#define BYTE10(x) BYTEn(x, 10)
#define BYTE11(x) BYTEn(x, 11)
#define BYTE12(x) BYTEn(x, 12)
#define BYTE13(x) BYTEn(x, 13)
#define BYTE14(x) BYTEn(x, 14)
#define BYTE15(x) BYTEn(x, 15)
#define WORD1(x) WORDn(x, 1)
#define WORD2(x) WORDn(x, 2) // third word of the object, unsigned
#define WORD3(x) WORDn(x, 3)
#define WORD4(x) WORDn(x, 4)
#define WORD5(x) WORDn(x, 5)
#define WORD6(x) WORDn(x, 6)
#define WORD7(x) WORDn(x, 7)
// now signed macros (the same but with sign extension)
#define SBYTEn(x, n) (*((int8_t*)&(x)+n))
#define SWORDn(x, n) (*((int16_t*)&(x)+n))
#define SDWORDn(x, n) (*((int32_t*)&(x)+n))
#define SLOBYTE(x) SBYTEn(x,LOW_IND(x,int8_t))
#define SLOWORD(x) SWORDn(x,LOW_IND(x,int16_t))
#define SLODWORD(x) SDWORDn(x,LOW_IND(x,int32_t))
#define SHIBYTE(x) SBYTEn(x,HIGH_IND(x,int8_t))
#define SHIWORD(x) SWORDn(x,HIGH_IND(x,int16_t))
#define SHIDWORD(x) SDWORDn(x,HIGH_IND(x,int32_t))
#define SBYTE1(x) SBYTEn(x, 1)
#define SBYTE2(x) SBYTEn(x, 2)
#define SBYTE3(x) SBYTEn(x, 3)
#define SBYTE4(x) SBYTEn(x, 4)
#define SBYTE5(x) SBYTEn(x, 5)
#define SBYTE6(x) SBYTEn(x, 6)
#define SBYTE7(x) SBYTEn(x, 7)
#define SBYTE8(x) SBYTEn(x, 8)
#define SBYTE9(x) SBYTEn(x, 9)
#define SBYTE10(x) SBYTEn(x, 10)
#define SBYTE11(x) SBYTEn(x, 11)
#define SBYTE12(x) SBYTEn(x, 12)
#define SBYTE13(x) SBYTEn(x, 13)
#define SBYTE14(x) SBYTEn(x, 14)
#define SBYTE15(x) SBYTEn(x, 15)
#define SWORD1(x) SWORDn(x, 1)
#define SWORD2(x) SWORDn(x, 2)
#define SWORD3(x) SWORDn(x, 3)
#define SWORD4(x) SWORDn(x, 4)
#define SWORD5(x) SWORDn(x, 5)
#define SWORD6(x) SWORDn(x, 6)
#define SWORD7(x) SWORDn(x, 7)
#define __SPAIR16__(high, low) (((int16_t) (high) << 8) | (uint8_t) (low))
#define __SPAIR32__(high, low) (((int32_t) (high) << 16) | (uint16_t)(low))
#define __SPAIR64__(high, low) (((int64_t) (high) << 32) | (uint32_t)(low))
#define __PAIR16__(high, low) (((uint16_t) (high) << 8) | (uint8_t) (low))
#define __PAIR32__(high, low) (((uint32_t) (high) << 16) | (uint16_t)(low))
#define __PAIR64__(high, low) (((uint64_t) (high) << 32) | (uint32_t)(low))
typedef struct ptr_range_lz_
{
unsigned __int8 *dataptr;
unsigned __int32 datasz;
unsigned __int32 padd;
unsigned __int64 dataszused;
} ptr_range_lz;
struct huffman_parameters
{
int huffman_tbl_bit_count_raw;
int huffman_tbl_bit_count_min;
int back_reference_low_bit_count_x_upper;
int back_reference_low_bit_count;
int back_reference_base_distance;
int unk1;
int pad2;
};
#ifdef WIP
__int64 *__fastcall x_sub_7FF6BF4BE500_somecalloc(__int64 *a1, unsigned __int64 a2)
{
__int64 v4; // rax
__int64 v5; // rbx
v4 = x_sub_7FF6BF50D8FC_malloc(a2);
v5 = v4;
if ( v4 )
x_sub_7FF6BF52C1F0_memset(v4, 0, a2);
else
v5 = 0ll;
*a1 = v5;
return a1;
}
__int64 __fastcall x_sub_7FF6BF3EFA80_csentry(__int64 a1)
{
if ( *(_DWORD *)(a1 + 8) <= 1u || !*(_DWORD *)(a1 + 52) )
return 0ll;
EnterCriticalSection((LPCRITICAL_SECTION)(a1 + 64));
return 1ll;
}
__int64 __fastcall x_sub_7FF6BF4BCD20_cbmt4(__int64 a1)
{
__int64 result; // rax
*(_BYTE *)a1 = 0;
result = a1;
*(_DWORD *)(a1 + 4) = 0;
*(_BYTE *)(a1 + 8) = 0;
*(_QWORD *)(a1 + 12) = -1ll;
*(_DWORD *)(a1 + 20) = -1;
return result;
}
__int64 __fastcall x_sub_7FF6BF4BD8F0_cbmt5(__int64 a1, int *a2)
{
__int64 v3; // rax
__int64 v4; // r8
__int64 v5; // rcx
__int64 v6; // r8
int v7; // eax
unsigned int v8; // r9d
unsigned int v9; // ebp
__int64 v10; // rdx
__int64 v11; // rax
int v12; // ecx
_QWORD *v13; // r14
unsigned int v14; // esi
unsigned int v15; // r11d
unsigned int v16; // eax
_BYTE *v17; // rcx
__int64 v18; // rbx
unsigned int v19; // edx
__int64 v20; // r8
unsigned int *v21; // r10
__int64 v22; // rcx
__int64 v23; // rcx
_BYTE v25[24]; // [rsp+0h] [rbp-38h]
__int64 v26; // [rsp+50h] [rbp+18h] BYREF
v3 = a1;
v4 = 511ll;
do
{
*(_QWORD *)&v25[12] = -1ll;
v3 += 24ll;
v25[0] = 0;
*(_DWORD *)&v25[4] = 0;
v25[8] = 0;
*(_DWORD *)&v25[20] = -1;
*(_OWORD *)(v3 - 24) = *(_OWORD *)v25;
*(_QWORD *)(v3 - 8) = *(_QWORD *)&v25[16];
--v4;
}
while ( v4 );
v5 = a1 + 28;
v6 = 128ll;
do
{
v7 = *a2;
a2 += 2;
*(_DWORD *)(v5 - 24) = v7;
v5 += 48ll;
*(_DWORD *)(v5 - 48) = *(a2 - 1);
--v6;
}
while ( v6 );
v8 = 256;
v9 = 0;
v10 = 256ll;
v11 = a1;
do
{
v12 = *(_DWORD *)(v11 + 4);
if ( v12 )
{
*(_BYTE *)v11 = 1;
v9 += v12;
}
v11 += 24ll;
--v10;
}
while ( v10 );
v13 = (_QWORD *)(a1 + 6160);
do
{
v14 = 0;
v26 = -1ll;
v15 = 0;
do
{
v16 = 0;
if ( v8 )
{
v17 = (_BYTE *)a1;
while ( !*v17 )
{
++v16;
v17 += 24;
if ( v16 >= v8 )
goto LABEL_17;
}
*((_DWORD *)&v26 + v15) = v16;
}
LABEL_17:
v18 = v15 + 1;
v19 = v18;
if ( (unsigned int)v18 < v8 )
{
v20 = a1 + 24 * v18;
do
{
if ( *(_BYTE *)v20 )
{
v21 = (unsigned int *)&v26 + v15;
if ( *(_DWORD *)(v20 + 4) < *(_DWORD *)(a1 + 24ll * *v21 + 4) )
*v21 = v19;
}
++v19;
v20 += 24ll;
}
while ( v19 < v8 );
}
v22 = *((unsigned int *)&v26 + v15);
if ( (_DWORD)v22 == -1 )
break;
v23 = 3 * v22;
*(_BYTE *)(a1 + 8 * v23) = 0;
*(_DWORD *)(a1 + 8 * v23 + 12) = v8;
*(_BYTE *)(a1 + 8 * v23 + 8) = v15++;
v14 += *(_DWORD *)(a1 + 8 * v23 + 4);
}
while ( (unsigned int)v18 < 2 );
*v13 = v26;
*((_BYTE *)v13 - 16) = 1;
*((_DWORD *)v13 - 3) = v14;
*((_BYTE *)v13 - 8) = -1;
if ( v14 >= v9 )
break;
++v8;
v13 += 3;
}
while ( v8 < 0x1FF );
return v8;
}
__int64 __fastcall x_sub_7FF6BF4BD6B0_cbmt3(__int64 a1, unsigned int a2, __int64 a3, unsigned int a4)
{
unsigned int v7; // ebx
unsigned int i; // r10d
int v9; // r9d
unsigned int v10; // r8d
int v11; // ecx
char v12; // dl
__int64 v13; // rdi
char *v14; // rsi
__int64 v15; // rax
unsigned int v16; // r10d
char v17; // dl
unsigned int k; // r9d
unsigned int v19; // ecx
unsigned int v20; // r8d
int pExceptionObject[4]; // [rsp+48h] [rbp-3450h] BYREF
__int64 v24; // [rsp+58h] [rbp-3440h]
char *j; // [rsp+60h] [rbp-3438h]
__int64 v26; // [rsp+68h] [rbp-3430h]
int v27[256]; // [rsp+70h] [rbp-3428h] BYREF
char v28[12272]; // [rsp+470h] [rbp-3028h] BYREF
v26 = -2ll;
v7 = 0;
x_sub_7FF6BF52C1F0_memset((__int64)v27, 0, 0x400ull);
for ( i = 0; i < 0x100; ++i )
{
v9 = 0;
v10 = 0;
v11 = 0;
do
{
v12 = *(_BYTE *)(v10++ + a3 + v7);
v9 |= (v12 & 0x7F) << v11;
v11 += 7;
}
while ( v12 < 0 );
pExceptionObject[1] = v10;
v27[i] = v9;
v7 += v10;
}
v13 = 511ll;
v24 = 511ll;
v14 = v28;
for ( j = v28; ; j = v14 )
{
v15 = v13--;
v24 = v13;
if ( !v15 )
break;
x_sub_7FF6BF4BCD20_cbmt4((__int64)v14);
v14 += 24;
}
v16 = x_sub_7FF6BF4BD8F0_cbmt5((__int64)v28, v27);
v17 = 1;
for ( k = 0; v7 < a4 && k < a2; ++k )
{
LOBYTE(v19) = v16;
v20 = v16;
while ( v20 >= 0x100 )
{
if ( ((unsigned __int8)v17 & *(_BYTE *)(v7 + a3)) != 0 )
v19 = *(_DWORD *)&v28[24 * v20 + 20];
else
v19 = *(_DWORD *)&v28[24 * v20 + 16];
v20 = v19;
v17 *= 2;
if ( !v17 )
{
++v7;
v17 = 1;
}
}
*(_BYTE *)(k + a1) = v19;
}
if ( (unsigned __int8)v17 > 1u )
++v7;
if ( v7 != a4 )
{
pExceptionObject[0] = 6;
CxxThrowException(pExceptionObject, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
return 0ll;
}
__int64 __fastcall x_sub_7FF6BF4BD570_cbmt6(__int64 a1, __int64 a2, __int64 a3, unsigned int a4)
{
__int64 v5; // r9
__int64 v6; // r10
char v7; // r12
unsigned int v8; // r14d
unsigned int v9; // esi
unsigned int v10; // ebx
unsigned int v11; // edi
int v12; // ecx
char v13; // dl
int pExceptionObject; // [rsp+38h] [rbp-50h] BYREF
__int64 v16; // [rsp+40h] [rbp-48h]
v16 = -2ll;
v5 = a3;
v6 = a1;
v7 = 0;
v8 = 0;
v9 = 0;
while ( v9 < a4 )
{
v10 = 0;
v11 = 0;
v12 = 0;
do
{
v13 = *(_BYTE *)(v11++ + v5 + v9);
v10 |= (v13 & 0x7F) << v12;
v12 += 7;
}
while ( v13 < 0 );
v9 += v11;
if ( v7 )
{
memset((void *)(v6 + v8), 0, v10);
v8 += v10;
}
else
{
x_sub_7FF6BF52BD90_memcpy((__m128i *)(v6 + v8), (const __m128i *)(v5 + v9), v10);
v8 += v10;
v9 += v10;
v5 = a3;
v6 = a1;
}
v7 ^= 1u;
}
if ( v9 != a4 )
{
pExceptionObject = 6;
CxxThrowException(&pExceptionObject, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
return 0ll;
}
__int64 __fastcall x_sub_7FF6BF4BD350_cbmt7(__int64 a1, __int64 a2, __int64 a3, int a4, int a5, int a6, unsigned __int16 a7)
{
unsigned __int16 v8; // bx
int v9; // r8d
int v10; // r13d
int v11; // esi
int v12; // edx
int i; // eax
int v14; // edi
int j; // r15d
unsigned __int16 ii; // r10
unsigned __int16 n; // r11
unsigned __int16 m; // r11
unsigned __int16 k; // r10
int v21; // [rsp+30h] [rbp-58h]
int v22; // [rsp+34h] [rbp-54h]
int pExceptionObject; // [rsp+48h] [rbp-40h] BYREF
__int64 v24; // [rsp+50h] [rbp-38h]
v24 = -2ll;
v8 = a7 >> 3;
v9 = a5;
v10 = a5 * (a7 >> 3);
v11 = 0;
v12 = 0;
v21 = 0;
for ( i = 0; ; ++i )
{
v22 = i;
if ( i >= a6 )
break;
v14 = v12;
for ( j = 0; j < v9; ++j )
{
if ( i )
{
if ( j )
{
for ( k = 0; k < v8; ++k )
*(_BYTE *)((unsigned int)k + v14 + a1) = *(_BYTE *)((unsigned int)k + v11 + a3)
+ ((*(unsigned __int8 *)(v14 + (unsigned int)k - v10 + a1)
+ (unsigned int)*(unsigned __int8 *)(v14 + k - (unsigned int)v8 + a1)) >> 1);
}
else
{
for ( m = 0; m < v8; ++m )
*(_BYTE *)((unsigned int)m + v14 + a1) = *(_BYTE *)((unsigned int)m + v11 + a3)
+ *(_BYTE *)(v14 + (unsigned int)m - v10 + a1);
}
}
else if ( j )
{
for ( n = 0; n < v8; ++n )
*(_BYTE *)((unsigned int)n + v14 + a1) = *(_BYTE *)((unsigned int)n + v11 + a3)
+ *(_BYTE *)(v14 + n - (unsigned int)v8 + a1);
}
else
{
for ( ii = 0; ii < v8; ++ii )
*(_BYTE *)((unsigned int)ii + v14 + a1) = *(_BYTE *)((unsigned int)ii + v11 + a3);
}
v14 += v8;
v11 += v8;
i = v22;
v9 = a5;
}
v12 = v10 + v21;
v21 += v10;
}
if ( v11 != a4 )
{
pExceptionObject = 6;
CxxThrowException(&pExceptionObject, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
return 0ll;
}
__int64 __fastcall x_sub_7FF6BF4BD170_cbmt2(__int64 a1)
{
__int64 v2; // rbx
int v3; // edi
int v4; // edx
int v5; // r14d
int v6; // eax
__int64 v7; // rcx
unsigned int v8; // esi
int v9; // eax
unsigned int v10; // edi
__int64 v11; // rdx
int v12; // eax
int v13; // eax
unsigned int v15; // [rsp+44h] [rbp-54h]
int pExceptionObject; // [rsp+50h] [rbp-48h] BYREF
int v17; // [rsp+54h] [rbp-44h] BYREF
int v18; // [rsp+58h] [rbp-40h] BYREF
__int64 v19; // [rsp+60h] [rbp-38h]
__int64 v20; // [rsp+A8h] [rbp+10h] BYREF
__int64 v21; // [rsp+B0h] [rbp+18h] BYREF
v19 = -2ll;
v2 = 0ll;
v15 = 0;
v3 = 1;
v4 = x_sub_7FF6BF3EFA80_csentry(*(_QWORD *)(a1 + 8));
v5 = -1;
v6 = *(_DWORD *)(a1 + 24);
if ( v6 < *(_DWORD *)(a1 + 28) )
{
v5 = *(_DWORD *)(a1 + 24);
*(_DWORD *)(a1 + 24) = v6 + 1;
}
v7 = *(_QWORD *)(a1 + 8);
if ( *(_DWORD *)(v7 + 8) > 1u && *(_DWORD *)(v7 + 52) || v4 )
LeaveCriticalSection((LPCRITICAL_SECTION)(v7 + 64));
if ( v5 >= 0 )
{
v2 = *(_QWORD *)(a1 + 16) + 48ll * v5;
v8 = **(_DWORD **)v2;
x_sub_7FF6BF4BE500_somecalloc(&v21, v8);
v9 = x_sub_7FF6BF4BD6B0_cbmt3(v21, v8, *(_QWORD *)v2 + 4ll, *(_DWORD *)(v2 + 8) - 4);
if ( v9 )
{
pExceptionObject = v9;
CxxThrowException(&pExceptionObject, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
v10 = *(_DWORD *)(v2 + 24);
x_sub_7FF6BF4BE500_somecalloc(&v20, v10);
v12 = x_sub_7FF6BF4BD570_cbmt6(v20, v11, v21, v8);
if ( v12 )
{
v17 = v12;
CxxThrowException(&v17, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
v13 = x_sub_7FF6BF4BD350_cbmt7(
*(_QWORD *)(v2 + 16),
*(unsigned int *)(v2 + 32),
v20,
v10,
*(_DWORD *)(v2 + 28),
*(_DWORD *)(v2 + 32),
*(_WORD *)(v2 + 36));
v3 = v13;
if ( v13 )
{
v18 = v13;
CxxThrowException(&v18, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
v15 = 1;
if ( v20 )
x_sub_7FF6BF50D4C4_free(v20);
if ( v21 )
x_sub_7FF6BF50D4C4_free(v21);
}
if ( v2 )
*(_DWORD *)(v2 + 40) = v3;
return v15;
}
__int64 __fastcall x_sub_7FF6BF4BD170_cbmt2(__int64 a1)
{
__int64 v2; // rbx
int v3; // edi
int v4; // edx
int v5; // r14d
int v6; // eax
__int64 v7; // rcx
unsigned int v8; // esi
int v9; // eax
unsigned int v10; // edi
__int64 v11; // rdx
int v12; // eax
int v13; // eax
unsigned int v15; // [rsp+44h] [rbp-54h]
int pExceptionObject; // [rsp+50h] [rbp-48h] BYREF
int v17; // [rsp+54h] [rbp-44h] BYREF
int v18; // [rsp+58h] [rbp-40h] BYREF
__int64 v19; // [rsp+60h] [rbp-38h]
__int64 v20; // [rsp+A8h] [rbp+10h] BYREF
__int64 v21; // [rsp+B0h] [rbp+18h] BYREF
v19 = -2ll;
v2 = 0ll;
v15 = 0;
v3 = 1;
v4 = x_sub_7FF6BF3EFA80_csentry(*(_QWORD *)(a1 + 8));
v5 = -1;
v6 = *(_DWORD *)(a1 + 24);
if ( v6 < *(_DWORD *)(a1 + 28) )
{
v5 = *(_DWORD *)(a1 + 24);
*(_DWORD *)(a1 + 24) = v6 + 1;
}
v7 = *(_QWORD *)(a1 + 8);
if ( *(_DWORD *)(v7 + 8) > 1u && *(_DWORD *)(v7 + 52) || v4 )
LeaveCriticalSection((LPCRITICAL_SECTION)(v7 + 64));
if ( v5 >= 0 )
{
v2 = *(_QWORD *)(a1 + 16) + 48ll * v5;
v8 = **(_DWORD **)v2;
x_sub_7FF6BF4BE500_somecalloc(&v21, v8);
v9 = x_sub_7FF6BF4BD6B0_cbmt3(v21, v8, *(_QWORD *)v2 + 4ll, *(_DWORD *)(v2 + 8) - 4);
if ( v9 )
{
pExceptionObject = v9;
CxxThrowException(&pExceptionObject, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
v10 = *(_DWORD *)(v2 + 24);
x_sub_7FF6BF4BE500_somecalloc(&v20, v10);
v12 = x_sub_7FF6BF4BD570_cbmt6(v20, v11, v21, v8);
if ( v12 )
{
v17 = v12;
CxxThrowException(&v17, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
v13 = x_sub_7FF6BF4BD350_cbmt7(
*(_QWORD *)(v2 + 16),
*(unsigned int *)(v2 + 32),
v20,
v10,
*(_DWORD *)(v2 + 28),
*(_DWORD *)(v2 + 32),
*(_WORD *)(v2 + 36));
v3 = v13;
if ( v13 )
{
v18 = v13;
CxxThrowException(&v18, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
v15 = 1;
if ( v20 )
x_sub_7FF6BF50D4C4_free(v20);
if ( v21 )
x_sub_7FF6BF50D4C4_free(v21);
}
if ( v2 )
*(_DWORD *)(v2 + 40) = v3;
return v15;
}
// attributes: thunk
__int64 __fastcall x_sub_7FF6BF4BD160_cbmt_worker(__int64 a1)
{
return x_sub_7FF6BF4BD170_cbmt2(a1);
}
__int64 __fastcall x_sub_7FF6BF3EF7F0_waitjob(__int64 a1)
{
unsigned int v1; // esi
unsigned int v3; // eax
unsigned int i; // edi
unsigned int v5; // ecx
unsigned int j; // edi
unsigned int v7; // ecx
__int64 (__fastcall *v8)(__int64); // rax
__int64 v9; // rcx
__int64 result; // rax
unsigned int k; // edi
unsigned int v13; // ecx
unsigned int v14; // ecx
__int64 v15; // rcx
v1 = 1;
*(_DWORD *)(a1 + 52) = 1;
if ( *(_DWORD *)(a1 + 8) <= 1u )
{
do
{
result = *(_QWORD *)(a1 + 24);
if ( !result && !*(_QWORD *)(a1 + 32) )
break;
if ( !*(_DWORD *)(a1 + 12) )
{
WaitForSingleObjectEx(*(HANDLE *)(*(_QWORD *)(a1 + 56) + 24ll), 0xFFFFFFFF, 0);
result = *(_QWORD *)(a1 + 24);
}
v15 = *(_QWORD *)(a1 + 40);
result = result
? ((__int64 (__fastcall *)(__int64))result)(v15)
: (*(__int64 (__fastcall **)(__int64, _QWORD))(a1 + 32))(v15, 0ll);
}
while ( (_DWORD)result );
goto LABEL_51;
}
*(_DWORD *)(a1 + 104) = 0;
x_sub_7FF6BF3EFD80_jobinituninit(a1, 1);
v3 = *(_DWORD *)(a1 + 8);
for ( i = 1; i < v3; ++i )
{
v5 = v3;
if ( i && i < v3 )
{
EnterCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 96ll + 216ll * i));
v5 = *(_DWORD *)(a1 + 8);
}
v3 = v5;
if ( i && i < v5 )
{
LeaveCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 136ll + 216ll * i));
v3 = *(_DWORD *)(a1 + 8);
}
}
for ( j = 1; j < v3; ++j )
{
v7 = v3;
if ( j && j < v3 )
{
EnterCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 176ll + 216ll * j));
v7 = *(_DWORD *)(a1 + 8);
}
v3 = v7;
if ( j && j < v7 )
{
LeaveCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 176ll + 216ll * j));
v3 = *(_DWORD *)(a1 + 8);
}
}
do
{
v8 = *(__int64 (__fastcall **)(__int64))(a1 + 24);
if ( !v8 && !*(_QWORD *)(a1 + 32) )
break;
if ( !*(_DWORD *)(a1 + 12) )
{
WaitForSingleObjectEx(*(HANDLE *)(*(_QWORD *)(a1 + 56) + 24ll), 0xFFFFFFFF, 0);
v8 = *(__int64 (__fastcall **)(__int64))(a1 + 24);
}
v9 = *(_QWORD *)(a1 + 40);
}
while ( v8 ? v8(v9) : (*(unsigned int (__fastcall **)(__int64, _QWORD))(a1 + 32))(v9, 0ll) );
x_sub_7FF6BF3EFD80_jobinituninit(a1, 0);
result = *(unsigned int *)(a1 + 8);
for ( k = 1; k < (unsigned int)result; ++k )
{
v13 = result;
if ( k && k < (unsigned int)result )
{
EnterCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 136ll + 216ll * k));
v13 = *(_DWORD *)(a1 + 8);
}
result = v13;
if ( k && k < v13 )
{
LeaveCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 96ll + 216ll * k));
result = *(unsigned int *)(a1 + 8);
}
}
if ( (unsigned int)result <= 1 )
{
LABEL_51:
*(_DWORD *)(a1 + 52) = 0;
return result;
}
do
{
v14 = result;
if ( v1 && v1 < (unsigned int)result )
{
EnterCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 56ll + 216ll * v1));
v14 = *(_DWORD *)(a1 + 8);
}
result = v14;
if ( v1 )
{
if ( v1 < v14 )
{
LeaveCriticalSection((LPCRITICAL_SECTION)(*(_QWORD *)(a1 + 56) + 56ll + 216ll * v1));
result = *(unsigned int *)(a1 + 8);
}
}
++v1;
}
while ( v1 < (unsigned int)result );
*(_DWORD *)(a1 + 52) = 0;
return result;
}
__int64 __fastcall x_sub_7FF6BF4BCE80_cbmt_inner(__int64 a1, __int64 a2, int a3, __int64 a4, int a5)
{
unsigned int v6; // ecx
unsigned __int64 v7; // r12
unsigned int v8; // r15d
__int64 v9; // rdi
__int64 v10; // rax
__int64 v11; // rbx
__int64 v12; // rcx
__int64 v13; // rax
__int64 *v14; // rbx
__int64 v15; // rcx
unsigned int j; // r9d
__int64 v17; // r10
__int64 v18; // rdx
int v19; // ecx
unsigned int v20; // ecx
__int64 v21; // rax
__int64 v22; // rax
unsigned int v23; // r9d
__int64 v24; // rcx
int v26; // [rsp+28h] [rbp-A0h]
unsigned int v27; // [rsp+2Ch] [rbp-9Ch]
unsigned int v28; // [rsp+30h] [rbp-98h]
int pExceptionObject; // [rsp+3Ch] [rbp-8Ch] BYREF
unsigned int v30; // [rsp+40h] [rbp-88h]
__int64 v31; // [rsp+48h] [rbp-80h] BYREF
unsigned __int64 v32; // [rsp+58h] [rbp-70h]
__int64 i; // [rsp+60h] [rbp-68h]
__int64 v34; // [rsp+68h] [rbp-60h]
__int64 v35; // [rsp+70h] [rbp-58h]
unsigned __int64 v36; // [rsp+78h] [rbp-50h]
__int64 v37; // [rsp+80h] [rbp-48h]
v35 = -2ll;
v28 = *(_DWORD *)(a4 + 24);
v27 = (*(_WORD *)(a4 + 28) >> 3) * *(_DWORD *)(a4 + 16) * v28;
v6 = *(_DWORD *)(a4 + 20);
v26 = v6 % v28;
v7 = (v28 + v6 - 1) / v28;
v8 = 0;
v9 = v7;
v36 = v7;
v10 = x_sub_7FF6BF50D8FC_malloc(saturated_mul(v7, 0x30ull));
v34 = v10;
v37 = v10;
if ( v10 )
{
v32 = v7;
v11 = v10;
for ( i = v10; ; i = v11 )
{
v12 = v9--;
v32 = v9;
if ( !v12 )
break;
x_sub_7FF6BF4BCCF0_cbmt_structinit(v11);
v11 += 48ll;
}
v13 = v34;
}
else
{
v13 = 0ll;
}
v31 = v13;
v14 = (__int64 *)(a1 + 16);
if ( (__int64 *)(a1 + 16) != &v31 )
{
v31 = 0ll;
v15 = *v14;
*v14 = v13;
if ( v15 )
x_sub_7FF6BF50D4C4_free(v15);
}
if ( v31 )
x_sub_7FF6BF50D4C4_free(v31);
*(_DWORD *)(a1 + 28) = v7;
for ( j = 0; j < (unsigned int)v7; ++j )
{
v17 = a4 + 4ll * j;
*(_QWORD *)(*v14 + 48ll * j) = a4 + *(unsigned int *)(v17 + 48);
v18 = j + 1;
if ( (unsigned int)v18 >= (unsigned int)v7 )
v19 = a5;
else
v19 = *(_DWORD *)(a4 + 4 * v18 + 48);
*(_DWORD *)(*v14 + 48ll * j + 8) = v19 - *(_DWORD *)(v17 + 48);
*(_QWORD *)(*v14 + 48ll * j + 16) = a2 + v8;
*(_DWORD *)(*v14 + 48ll * j + 24) = v27;
*(_DWORD *)(*v14 + 48ll * j + 28) = *(_DWORD *)(a4 + 16);
*(_DWORD *)(*v14 + 48ll * j + 32) = v28;
*(_WORD *)(*v14 + 48ll * j + 36) = *(_WORD *)(a4 + 28);
v20 = a3 - v27 * j;
if ( v20 < v27 )
{
*(_DWORD *)(*v14 + 48ll * j + 24) = v20;
*(_DWORD *)(*v14 + 48ll * j + 32) = v26;
}
v8 += v27;
}
*(_DWORD *)(a1 + 24) = 0;
v21 = *(_QWORD *)(a1 + 8);
*(_QWORD *)(v21 + 24) = x_sub_7FF6BF4BD160_cbmt_worker;
*(_QWORD *)(v21 + 40) = a1;
x_sub_7FF6BF3EF7F0_waitjob(*(_QWORD *)(a1 + 8));
v22 = *(_QWORD *)(a1 + 8);
*(_QWORD *)(v22 + 24) = 0ll;
*(_QWORD *)(v22 + 40) = 0ll;
v23 = 0;
v30 = 0;
while ( v23 < (unsigned int)v7 )
{
if ( *(_DWORD *)(*v14 + 48ll * v23 + 40) )
{
pExceptionObject = *(_DWORD *)(x_sub_7FF6BF4BDAC0_cbmt_exc((_QWORD *)(a1 + 16), v23) + 40);
CxxThrowException(&pExceptionObject, (_ThrowInfo *)&_TI1_AW4YECBGMTReturn_YCCBGMT__);
}
v30 = ++v23;
}
v24 = *(_QWORD *)(a1 + 16);
*(_QWORD *)(a1 + 16) = 0ll;
if ( v24 )
x_sub_7FF6BF50D4C4_free(v24);
return 0ll;
}
_BOOL8 __fastcall x_sub_7FF6BF4BCDF0_check_cbgmt(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rdi
v2 = a2;
return a1
&& a2 >= 0x30
&& !(unsigned int)x_sub_7FF6BF52C580_memcmp((unsigned __int64 *)a1, (__int64)"CompressedBG_MT", 0xFull)
&& v2 >= 4
* (unsigned __int64)((unsigned int)(*(_DWORD *)(a1 + 24) + *(_DWORD *)(a1 + 20) - 1) / *(_DWORD *)(a1 + 24))
+ 48;
}
#endif
__int64 __fastcall x_sub_7FF6BF505110_lz_get_int(
_DWORD *outres,
ptr_range_lz *inrange,
int offs,
unsigned int bitindex,
int maxbitrange)
{
unsigned __int8 *v7; // r11
unsigned int v8; // r9d
int v9; // ebx
unsigned __int8 v10; // dl
int v11; // ebp
signed __int32 datasz; // r13d
int v13; // edi
unsigned __int8 v14; // al
int v15; // r10d
v7 = &inrange->dataptr[offs];
v8 = 0;
v9 = 0;
*outres = 0;
v10 = 0;
v11 = (maxbitrange - 1) / 8 + 1;
if ( v11 > 0 )
{
datasz = inrange->datasz;
v13 = 0;
do
{
if ( (int)(v8 + offs) >= datasz )
break;
v14 = *v7 & (255 >> (7 - bitindex));
if ( bitindex > 7 )
{
v15 = -1;
}
else
{
v15 = 0;
if ( (int)(bitindex - 7) <= 0 )
{
v15 = 1;
v10 = (v14 << (7 - bitindex)) | (v7[1] >> (bitindex - 7 + 8));
}
else
{
v10 = v14 >> (bitindex - 7);
}
}
v8 += v15;
*outres |= v10 << v13;
++v9;
v13 += 8;
v7 += v15;
}
while ( v9 < v11 );
}
if ( v9 != v11 )
return -v8;
return v8;
}
char __fastcall x_sub_7FF6BF505640_lz_check_hfp(struct huffman_parameters *a1)
{
int huffman_tbl_bit_count_raw; // edx
char v2; // r8
int huffman_tbl_bit_count_min; // eax
int back_reference_low_bit_count_x_upper; // r9d
int back_reference_low_bit_count; // r10d
int back_reference_base_distance; // eax
huffman_tbl_bit_count_raw = a1->huffman_tbl_bit_count_raw;
v2 = 1;
if ( a1->huffman_tbl_bit_count_raw < 3 )
{
a1->huffman_tbl_bit_count_raw = 3;
v2 = 0;
huffman_tbl_bit_count_raw = 3;
}
if ( huffman_tbl_bit_count_raw > 15 )
{
a1->huffman_tbl_bit_count_raw = 15;
v2 = 0;
huffman_tbl_bit_count_raw = 15;
}
huffman_tbl_bit_count_min = a1->huffman_tbl_bit_count_min;
if ( huffman_tbl_bit_count_min < 3 )
{
a1->huffman_tbl_bit_count_min = 3;
v2 = 0;
huffman_tbl_bit_count_min = 3;
}
if ( huffman_tbl_bit_count_min > 15 )
{
a1->huffman_tbl_bit_count_min = 15;
v2 = 0;
huffman_tbl_bit_count_min = 15;
}
a1->unk1 = huffman_tbl_bit_count_raw;
if ( huffman_tbl_bit_count_raw < huffman_tbl_bit_count_min )
{
a1->unk1 = huffman_tbl_bit_count_min;
huffman_tbl_bit_count_raw = huffman_tbl_bit_count_min;
}
back_reference_low_bit_count_x_upper = a1->back_reference_low_bit_count_x_upper;
if ( back_reference_low_bit_count_x_upper < huffman_tbl_bit_count_min )
{
a1->back_reference_low_bit_count_x_upper = huffman_tbl_bit_count_min;
v2 = 0;
back_reference_low_bit_count_x_upper = huffman_tbl_bit_count_min;
}
if ( back_reference_low_bit_count_x_upper > 15 )
{
a1->back_reference_low_bit_count_x_upper = 15;
v2 = 0;
back_reference_low_bit_count_x_upper = 15;
}
back_reference_low_bit_count = a1->back_reference_low_bit_count;
if ( back_reference_low_bit_count < 0 )
{
back_reference_low_bit_count = 0;
a1->back_reference_low_bit_count = 0;
v2 = 0;
}
if ( back_reference_low_bit_count >= back_reference_low_bit_count_x_upper )
{
back_reference_low_bit_count = back_reference_low_bit_count_x_upper - 1;
v2 = 0;
a1->back_reference_low_bit_count = back_reference_low_bit_count_x_upper - 1;
}
if ( back_reference_low_bit_count_x_upper - back_reference_low_bit_count > huffman_tbl_bit_count_raw )
{
a1->back_reference_low_bit_count = back_reference_low_bit_count_x_upper - huffman_tbl_bit_count_raw;
v2 = 0;
}
back_reference_base_distance = a1->back_reference_base_distance;
if ( back_reference_base_distance >= 2 )
{
if ( back_reference_base_distance <= 8 )
{
return v2;
}
else
{
a1->back_reference_base_distance = 8;
return 0;
}
}
else
{
a1->back_reference_base_distance = 2;
return 0;
}
}
__int64 __fastcall x_sub_7FF6BF5053E0_lz_get_hfp(
struct huffman_parameters *a1,
ptr_range_lz *a2,
int a3,
unsigned int a4,
unsigned int *a5)
{
unsigned __int8 *v5; // r8
int v6; // edx
int v7; // ebx
unsigned __int8 v8; // r10
unsigned __int8 v9; // di
int v10; // r11d
unsigned __int8 *v11; // r8
unsigned __int8 v12; // di
int v13; // esi
unsigned __int8 *v14; // r8
unsigned __int8 v15; // di
int v16; // esi
unsigned __int8 *v17; // r8
unsigned __int8 v18; // di
int v19; // esi
unsigned __int8 *v20; // r8
unsigned __int8 v21; // di
int v22; // esi
unsigned __int8 v23; // bl
unsigned int v24; // r11d
v5 = &a2->dataptr[a3];
v6 = a4 - 7;
v7 = 255 >> (7 - a4);
v8 = 0;
v9 = *v5 & v7;
if ( a4 > 7 )
{
v10 = -1;
}
else
{
v10 = 0;
if ( v6 <= 0 )
{
v10 = 1;
v8 = (v9 << (7 - a4)) | (v5[1] >> (a4 - 7 + 8));
}
else
{
v8 = v9 >> v6;
}
}
v11 = &v5[v10];
a1->pad2 = v8;
v12 = *v11 & v7;
if ( a4 > 7 )
{
v13 = -1;
}
else
{
v13 = 0;
if ( v6 <= 0 )
{
v13 = 1;
v8 = (v12 << (7 - a4)) | (v11[1] >> (a4 - 7 + 8));
}
else
{
v8 = v12 >> v6;
}
}
a1->huffman_tbl_bit_count_raw = v8;
v14 = &v11[v13];
v15 = *v14 & v7;
if ( a4 > 7 )
{
v16 = -1;
}
else
{
v16 = 0;
if ( v6 <= 0 )
{
v16 = 1;
v8 = (v15 << (7 - a4)) | (v14[1] >> (a4 - 7 + 8));
}
else
{
v8 = v15 >> v6;
}
}
a1->huffman_tbl_bit_count_min = v8;
v17 = &v14[v16];
v18 = *v17 & v7;
if ( a4 > 7 )
{
v19 = -1;
}
else
{
v19 = 0;
if ( v6 <= 0 )
{
v19 = 1;
v8 = (v18 << (7 - a4)) | (v17[1] >> (a4 - 7 + 8));
}
else
{
v8 = v18 >> v6;
}
}
a1->back_reference_low_bit_count_x_upper = v8;
v20 = &v17[v19];
v21 = *v20 & v7;
if ( a4 > 7 )
{
v22 = -1;
}
else
{
v22 = 0;
if ( v6 <= 0 )
{
v22 = 1;
v8 = (v21 << (7 - a4)) | (v20[1] >> (a4 - 7 + 8));
}
else
{
v8 = v21 >> v6;
}
}
a1->back_reference_low_bit_count = v8;
v23 = v20[v22] & v7;
if ( a4 <= 7 )
{
if ( v6 <= 0 )
v8 = (v23 << (7 - a4)) | (v20[v22 + 1] >> (a4 - 7 + 8));
else
v8 = v23 >> v6;
}
a1->back_reference_base_distance = v8;
*a5 = a4;
#if 1
v24 = 0;
#endif
if ( !x_sub_7FF6BF505640_lz_check_hfp(a1) )
return -v24;
return v24;
}
__int64 __fastcall x_sub_7FF6BF505BA0_lzentry3(
unsigned __int8 *a1,
int a2,
int a3,
unsigned int a4,
_DWORD *a5,
unsigned int a6,
unsigned int *a7)
{
unsigned int v7; // eax
int v8; // ebp
unsigned int v11; // ebx
int v12; // r8d
unsigned int v13; // esi
unsigned int v14; // r11d
_DWORD *v15; // rcx
__int64 v17; // rdi
unsigned int v18; // r9d
char v19; // dl
__int64 v20; // r8
int v21; // ecx
int v22; // edx
int v23; // r8d
__int64 v24; // rcx
v7 = 0;
v8 = a2;
v11 = -1;
if ( (int)a4 >= 1 )
{
if ( a4 <= 0x1F )
v12 = (1 << a4) - 1;
else
v12 = -1;
}
else
{
v12 = 0;
}
v13 = v12 + 1;
if ( (unsigned int)(v12 + 1) <= 0x16A09 )
v11 = (unsigned int)((v12 + 1) * (v12 + 2)) >> 1;
v14 = -1;
if ( a6 > v13 )
{
v17 = a2;
if ( v12 == -1 || !v11 )
{
return 0xFFFFFFFFll;
}
else
{
v18 = a6 - 1;
while ( v18 >= v13 )
{
v19 = (a1[v17] >> a3) & 1;
v20 = 2ll * v18;
v18 = a5[4 * v18 + 2];
if ( LOBYTE(a5[4 * v18 + 3]) != v19 )
{
v18 = a5[2 * v20 + 1];
if ( LOBYTE(a5[4 * v18 + 3]) != v19 )
{
*a7 = v7;
return 0xFFFFFFFFll;
}
}
--a3;
v21 = v8 + 1;
v22 = a3;
v23 = a3;
if ( a3 < 0 )
a3 = 7;
if ( v22 >= 0 )
v21 = v8;
v8 = v21;
v24 = v17 + 1;
if ( v23 >= 0 )
v24 = v17;
++v7;
v17 = v24;
}
*a7 = v7;
return v18;
}
}
else
{
if ( a6 )
{
v15 = a5;
do
{
if ( *v15 )
{
v14 = v7;
*a7 = 1;
}
++v7;
v15 += 4;
}
while ( v7 < a6 );
}
return v14;
}
}
__int64 __fastcall x_sub_7FF6BF505730_lz_unzmain(
struct huffman_parameters *a1,
ptr_range_lz *outrange,
ptr_range_lz *inrange,
int a4,
unsigned int a5,
int a6,
_DWORD *a7,
unsigned int a8)
{
signed int v8; // ebx
unsigned __int8 v9; // si
unsigned __int8 *dataptr; // r14
int v11; // r10d
struct huffman_parameters *v12; // rdx
unsigned __int8 *v13; // r13
signed __int32 v14; // ebp
int v15; // eax
int v16; // r12d
unsigned __int8 v17; // di
int unk1; // r13d
char v19; // di
int v20; // ebx
int v21; // eax
int v22; // eax
int v23; // r15d
int v24; // ecx
int v25; // ebx
int v26; // eax
int v27; // edi
unsigned int v28; // r9d
int v29; // r15d
int v30; // r12d
int v31; // ecx
int v32; // r11d
int back_reference_low_bit_count; // edx
int v34; // r12d
unsigned __int8 v35; // r8
int v36; // edi
unsigned __int8 v37; // r8
int v38; // edi
int v39; // eax
int v40; // ebx
int v41; // eax
__int64 v42; // rdx
__int64 v43; // rcx
int v44; // ecx
int v45; // r15d
__int64 v46; // r11
unsigned __int8 v47; // dl
int v48; // r9d
unsigned __int8 *v50; // [rsp+40h] [rbp-58h]
ptr_range_lz *v53; // [rsp+B0h] [rbp+18h]
int v54; // [rsp+B8h] [rbp+20h]
v54 = a4;
v53 = inrange;
v8 = a5;
v9 = 0;
dataptr = outrange->dataptr;
v11 = 0;
v12 = a1;
v13 = &inrange->dataptr[a4];
v14 = 0;
a5 = 0;
v15 = a6;
v50 = v13;
while ( v14 < v15 && v11 + a4 < (signed __int32)inrange->datasz )
{
v16 = v11 + 1;
v17 = v13[v11];
unk1 = v12->unk1;
v19 = v17 >> v8;
v20 = v8 - 1;
v21 = v20;
if ( v20 < 0 )
v20 = 7;
if ( v21 >= 0 )
v16 = v11;
v22 = x_sub_7FF6BF505BA0_lzentry3(v50, v16, v20, v12->unk1, a7, a8, &a5);
v23 = v22;
if ( (v19 & 1) != 0 )
{
if ( v22 < 0 )
return (unsigned int)-v16;
v24 = (int)a5 / 8;
v25 = v20 - (int)a5 % 8;
v26 = (int)a5 / 8;
if ( v25 > 7 )
{
v26 = v24 - 1;
v25 -= 8;
--v24;
}
if ( v25 < 0 )
{
v25 += 8;
v24 = v26 + 1;
}
v27 = v16 + v24;
v28 = unk1;
v13 = v50;
v29 = a1->back_reference_base_distance + v23;
v30 = x_sub_7FF6BF505BA0_lzentry3(v50, v16 + v24, v25, v28, a7, a8, &a5);
if ( v30 < 0 )
return (unsigned int)-v27;
v31 = (int)a5 / 8;
v8 = v25 - (int)a5 % 8;
if ( v8 > 7 )
{
v8 -= 8;
--v31;
}
if ( v8 < 0 )
{
v8 += 8;
++v31;
}
v11 = v27 + v31;
v32 = 0;
back_reference_low_bit_count = a1->back_reference_low_bit_count;
v34 = v30 << back_reference_low_bit_count;
if ( back_reference_low_bit_count > 8 )
{
v35 = v50[v11] & (255 >> (7 - v8));
if ( (unsigned int)v8 > 7 )
{
v36 = -1;
}
else
{
v36 = 0;
if ( v8 - 7 <= 0 )
{
v36 = 1;
v9 = (v35 << (7 - v8)) | (v50[v11 + 1] >> (v8 - 7 + 8));
}
else
{
v9 = v35 >> (v8 - 7);
}
}
back_reference_low_bit_count -= 8;
v11 += v36;
v32 = v9 << back_reference_low_bit_count;
}
if ( back_reference_low_bit_count > 0 )
{
v37 = v50[v11] & (255 >> (7 - v8));
if ( (unsigned int)v8 > 7 || (unsigned int)(back_reference_low_bit_count - 1) > 7 )
{
v38 = -1;
}
else
{
v38 = 0;
v39 = v8 - back_reference_low_bit_count + 1;
if ( v39 <= 0 )
{
v38 = 1;
v9 = (v37 << -(char)(v8 - back_reference_low_bit_count + 1)) | (v50[v11 + 1] >> (v8
- back_reference_low_bit_count
+ 9));
}
else
{
v9 = v37 >> v39;
}
}
v40 = v8 - (back_reference_low_bit_count & 7);
v41 = v40 - 8;
if ( v40 <= 7 )
v41 = v40;
v8 = v41 + 8;
if ( v41 >= 0 )
v8 = v41;
v11 += v38;
v32 |= v9;
}
v15 = a6;
a4 = v54;
inrange = v53;
if ( v29 > 0 )
{
v42 = a1->back_reference_base_distance + v32 + v34;
v15 = a6;
v43 = (unsigned int)v29;
do
{
if ( v14 < v15 )
{
*dataptr = dataptr[-v42];
++dataptr;
v15 = a6;
++v14;
}
--v43;
}
while ( v43 );
a4 = v54;
inrange = v53;
}
LABEL_2:
v12 = a1;
}
else
{
if ( v22 < 0 )
return (unsigned int)-v16;
v44 = (int)a5 / 8;
v8 = v20 - (int)a5 % 8;
if ( v8 > 7 )
{
v8 -= 8;
--v44;
}
if ( v8 < 0 )
{
v8 += 8;
++v44;
}
v15 = a6;
v11 = v16 + v44;
v13 = v50;
v45 = v23 + 1;
v12 = a1;
a4 = v54;
inrange = v53;
if ( v45 > 0 )
{
v46 = (unsigned int)v45;
do
{
v13 = v50;
if ( v14 < v15 )
{
v47 = v50[v11] & (255 >> (7 - v8));
if ( (unsigned int)v8 > 7 )
{
v48 = -1;
}
else
{
v48 = 0;
if ( v8 - 7 <= 0 )
{
v48 = 1;
v9 = (v47 << (7 - v8)) | (v50[v11 + 1] >> (v8 - 7 + 8));
}
else
{
v9 = v47 >> (v8 - 7);
}
}
v15 = a6;
v11 += v48;
*dataptr++ = v9;
++v14;
}
--v46;
}
while ( v46 );
a4 = v54;
inrange = v53;
goto LABEL_2;
}
}
}
outrange->datasz = v14;
return (unsigned int)v14;
}
__int64 __fastcall x_sub_7FF6BF505210_lz_checkheader(ptr_range_lz *a1)
{
unsigned __int8 *dataptr; // rdi
int v2; // ebx
int v3; // edx
__int64 v4; // rcx
__int64 v5; // rax
bool v6; // cf
_BYTE v7[16]; // xmm0
__int64 v8; // rcx
__int64 v10; // rax
__int64 v11; // rcx
_BYTE v12[16]; // [rsp+28h] [rbp-E0h] BYREF
__int8 v13[129]; // [rsp+37h] [rbp-D1h] BYREF
_BYTE v14[16]; // [rsp+B8h] [rbp-50h]
char v15[128]; // [rsp+C8h] [rbp-40h] BYREF
char v16[4]; // [rsp+148h] [rbp+40h] BYREF
char v17; // [rsp+14Ch] [rbp+44h]
char v18[4]; // [rsp+150h] [rbp+48h]
char v19; // [rsp+154h] [rbp+4Ch]
_BYTE v20[16]; // [rsp+158h] [rbp+50h] BYREF
// __int128 v21; // [rsp+168h] [rbp+60h]
dataptr = a1->dataptr;
// v21 = 0ll;
x_sub_7FF6BF52C1F0_memset(v13, 0, 0x79);
v2 = 0;
v3 = 0;
v4 = 0;
memcpy(v20, dataptr, sizeof(v20));
qmemcpy(v12, "LenZuCompressor", sizeof(v12));
do
{
if ( v20[v4] != v12[v4] )
return -1;
++v4;
++v3;
}
while ( v3 < 16 );
v5 = 0;
v6 = 1;
do
{
if ( !v6 )
{
// _report_rangecheckfailure(v4);
// __debugbreak();
printf("Failure\n");
exit(1);
}
v6 = (unsigned __int64)++v5 < 0x20;
}
while ( v5 < 32 );
x_sub_7FF6BF52C1F0_memset(v15, 0, 0x78);
memset(v18, 0, sizeof(v18));
v19 = 0;
memset(v16, 0, sizeof(v16));
v17 = 0;
x_sub_7FF6BF52C1F0_memset(v13, 0, 0x79);
memcpy(v7, dataptr, sizeof(v7));
v8 = 0;
qmemcpy(v12, "LenZuCompressor", sizeof(v12));
memcpy(v14, v7, sizeof(v14));
while ( v14[v8] == v12[v8] )
{
++v8;
if ( ++v2 >= 16 )
{
memcpy(&v18, ((_DWORD *)dataptr + 4), sizeof(v18));
memcpy(&v16, ((_DWORD *)dataptr + 5), sizeof(v16));
v10 = -1;
v11 = -1;
v19 = 0;
v17 = 0;
do
++v11;
while ( v16[v11] );
do
++v10;
while ( v18[v10] );
x_sub_7FF6BF52BD90_memcpy(&v20[(int)v10 + 1], (const unsigned __int8 *)v16, (int)v11 + 1);
return 32;
}
}
return 32;
}
bool mul_overflow_check(unsigned int cnt, unsigned int es)
{
if (es == 0 || cnt == 0)
return true;
return cnt <= ((unsigned int)(-1)) / es;
}
unsigned int saturated_mul(unsigned int cnt, unsigned int es)
{
return mul_overflow_check(cnt, es) ? cnt * es : (unsigned int)(-1);
}
__int64 __fastcall x_sub_7FF6BF504C50_lz_decompressmain(ptr_range_lz *outrange, ptr_range_lz *inrange)
{
unsigned __int64 checksum_calc; // rsi
int hdrrdoffset; // eax
__int64 decompressed_length_1; // rax
int readoffset2; // ebx
int readoffset3; // ebx
unsigned __int64 v9; // r14
int readoffset4; // ebx
int readoffset5; // ebx
int unk1; // r13d
int v13; // eax
unsigned int v14; // eax
unsigned int v15; // edi
__int64 v16; // rbx
unsigned __int32 *v17; // rax
unsigned __int32 *v18; // r15
unsigned __int32 *v19; // rax
int v20; // eax
int readoffset5_1; // ebx
unsigned int v22; // eax
unsigned int v23; // edi
int v24; // r13d
int maxbitrange5_1; // r12d
int v26; // eax
unsigned __int32 v27; // r14d
int v28; // r12d
unsigned int v29; // r12d
unsigned int v30; // edi
unsigned __int32 v31; // ebx
unsigned int v32; // r11d
unsigned int v33; // r9d
unsigned __int32 v34; // r10d
unsigned int v35; // r14d
unsigned __int32 v36; // edx
unsigned __int32 *v37; // r8
unsigned __int32 v38; // eax
unsigned __int32 v39; // ecx
unsigned __int32 v40; // ecx
__int64 v41; // rcx
ptr_range_lz *outrange_1; // rdi
int v43; // ebx
unsigned __int32 datasz; // r9d
unsigned __int32 v45; // edx
unsigned __int8 *dataptr; // r8
__int64 v47; // rax
bool v48; // zf
unsigned int v49; // [rsp+38h] [rbp-71h]
unsigned int outres1; // [rsp+40h] [rbp-69h] BYREF
unsigned __int32 outres5_1; // [rsp+44h] [rbp-65h] BYREF
unsigned int bitindex5; // [rsp+48h] [rbp-61h] BYREF
unsigned int outres5; // [rsp+4Ch] [rbp-5Dh] BYREF
ptr_range_lz *inrange_2; // [rsp+50h] [rbp-59h]
unsigned int v55; // [rsp+58h] [rbp-51h]
int maxbitrange5; // [rsp+5Ch] [rbp-4Dh]
int decompressed_length_2; // [rsp+60h] [rbp-49h]
struct huffman_parameters hfp; // [rsp+68h] [rbp-41h] BYREF
unsigned __int64 checksum_orig; // [rsp+88h] [rbp-21h]
struct huffman_parameters v60; // [rsp+90h] [rbp-19h] BYREF
ptr_range_lz *v61; // [rsp+B0h] [rbp+7h] OVERLAPPED
ptr_range_lz *v62; // [rsp+B0h] [rbp+7h] FORCED
int ar[4] = {0x0E9, 0x115, 0x137, 0x1B1};
v61 = outrange;
memset(&hfp, 0, sizeof(hfp));
checksum_calc = 0ll;
outres1 = 0;
inrange_2 = inrange;
bitindex5 = 7;
hdrrdoffset = x_sub_7FF6BF505210_lz_checkheader(inrange);
if ( hdrrdoffset < 0 )
return -1ll;
readoffset2 = x_sub_7FF6BF505110_lz_get_int(&outres1, inrange, hdrrdoffset, 7u, 32) + hdrrdoffset;
decompressed_length_1 = outres1;
decompressed_length_2 = outres1;
if ( outrange )
{
readoffset3 = x_sub_7FF6BF505110_lz_get_int(&outres1, inrange, readoffset2, 7u, 32) + readoffset2;
v9 = (unsigned __int64)outres1 << 32;
readoffset4 = x_sub_7FF6BF505110_lz_get_int(&outres1, inrange, readoffset3, 7u, 32) + readoffset3;
checksum_orig = outres1 + v9;
readoffset5 = x_sub_7FF6BF505110_lz_get_int(&outres1, inrange, readoffset4, 7u, 32) + readoffset4;
outres1 = readoffset5 + x_sub_7FF6BF5053E0_lz_get_hfp(&hfp, inrange, readoffset5, 7u, &bitindex5);
if ( (int)outres1 >= 1 )
{
unk1 = hfp.unk1;
if ( hfp.unk1 >= 1 )
{
if ( hfp.unk1 <= 0x1Fu )
v13 = (1 << SLOBYTE(hfp.unk1)) - 1;
else
v13 = -1;
}
else
{
v13 = 0;
}
v14 = v13 + 1;
if ( v14 <= 0x16A09 )
v15 = (v14 * (v14 + 1)) >> 1;
else
v15 = -1;
v16 = v15;
v17 = (unsigned __int32 *)x_sub_7FF6BF50D8FC_malloc(saturated_mul(v15, 0x10ull));
v18 = v17;
if ( v17 )
{
if ( !v15 )
return 0xFFFFFFFDll;
v19 = v17 + 2;
do
{
*(v19 - 2) = 0;
*(_QWORD *)(v19 - 1) = -1ll;
*((_BYTE *)v19 + 4) = -1;
v19 += 4;
--v16;
}
while ( v16 );
if ( unk1 >= 1 )
{
if ( (unsigned int)unk1 <= 0x1F )
v20 = (1 << unk1) - 1;
else
v20 = -1;
}
else
{
v20 = 0;
}
v55 = v20 + 1;
outres5_1 = 1;
outres5 = 0;
maxbitrange5 = (unk1 + 7) / 8;
readoffset5_1 = x_sub_7FF6BF505110_lz_get_int(&outres5, inrange_2, outres1, bitindex5, maxbitrange5);
v22 = outres5;
if ( !outres5 )
v22 = v55;
outres5 = v22;
if ( v22 * ((unk1 + 7) / 8 + 4) > 4 * v55 )
{
v22 = v55;
outres5_1 = -1;
outres5 = v55;
}
v23 = 0;
if ( v22 )
{
v24 = outres5_1;
maxbitrange5_1 = maxbitrange5;
do
{
if ( v24 <= 0 )
{
v27 = v23;
}
else
{
outres5_1 = 0;
v26 = x_sub_7FF6BF505110_lz_get_int(
&outres5_1,
inrange_2,
readoffset5_1 + outres1,
bitindex5,
maxbitrange5_1);
v27 = outres5_1;
readoffset5_1 += v26;
}
outres5_1 = 0;
readoffset5_1 += x_sub_7FF6BF505110_lz_get_int(
&outres5_1,
inrange_2,
readoffset5_1 + outres1,
bitindex5,
32);
++v23;
v18[4 * v27] = outres5_1;
}
while ( v23 < outres5 );
unk1 = hfp.unk1;
}
outres1 += readoffset5_1;
if ( unk1 >= 1 )
v28 = (unsigned int)unk1 <= 0x1F ? (1 << unk1) - 1 : -1;
else
v28 = 0;
v29 = v28 + 1;
v30 = v29;
while ( 1 )
{
v31 = -1;
v32 = 0xFFFFFFF;
v33 = 0xFFFFFFF;
v34 = -1;
v35 = 0;
v36 = 0;
if ( !v30 )
break;
v37 = v18;
do
{
v38 = *v37;
if ( *v37 && *((_BYTE *)v37 + 12) == 0xFF )
{
++v35;
v39 = v36;
if ( v38 >= v33 )
v39 = v34;
v34 = v39;
v40 = *v37;
if ( v38 >= v33 )
v40 = v33;
v33 = v40;
if ( v38 < v32 )
{
v33 = v32;
v34 = v31;
v32 = *v37;
v31 = v36;
}
}
++v36;
v37 += 4;
}
while ( v36 < v30 );
if ( v35 <= 1 )
break;
v41 = 2ll * v30;
v18[2 * v41] = v18[4 * v31] + v18[4 * v34];
++v30;
v18[2 * v41 + 1] = v31;
v18[2 * v41 + 2] = v34;
LOBYTE(v18[4 * v31 + 3]) = 1;
LOBYTE(v18[4 * v34 + 3]) = 0;
}
if ( v30 <= v29 )
LOBYTE(v18[4 * v31 + 3]) = 1;
if ( v30
&& (v49 = v30,
outrange_1 = v61,
v60 = hfp,
v43 = x_sub_7FF6BF505730_lz_unzmain(
&v60,
v61,
inrange_2,
outres1,
bitindex5,
decompressed_length_2,
v18,
v49),
v43 >= 1) )
{
x_sub_7FF6BF50D4C4_free(v18);
datasz = outrange_1->datasz;
v45 = 0;
dataptr = outrange_1->dataptr;
for (; v45 < datasz; v45 += 1 )
{
checksum_calc = (checksum_calc + dataptr[v45]) * (unsigned __int64)ar[v45 & 3];
}
v48 = checksum_calc == checksum_orig;
outrange_1->dataszused = checksum_calc;
if ( !v48 )
return 0xFFFFFFF6;
return (unsigned int)v43;
}
else
{
return 0xFFFFFFFDll;
}
}
else
{
return 0xFFFFFFF7ll;
}
}
else
{
return 0xFFFFFFFEll;
}
}
return decompressed_length_1;
}
__int64 __fastcall sub_7FF6BF455670(
__int64 *a1,
unsigned int *a2,
unsigned __int8 *a3,
unsigned int a4,
__int64 a5,
__int64 a6)
{
unsigned int v11; // r12d
int v12; // edi
#if 0
_OWORD *v13; // r15
#endif
void *v14; // rbx
int v15; // eax
unsigned int v16; // esi
int v17; // ebx
__int64 v18; // rcx
int hdrrdoffset; // eax
unsigned __int8 *v20; // rdi
unsigned __int8 *v21; // rbx
unsigned int v22; // eax
_DWORD v23[2]; // [rsp+30h] [rbp-D0h] BYREF
unsigned int *v24; // [rsp+38h] [rbp-C8h]
__int64 *v25; // [rsp+40h] [rbp-C0h]
ptr_range_lz inrange; // [rsp+48h] [rbp-B8h] BYREF
__int64 v27[2]; // [rsp+60h] [rbp-A0h] BYREF
void *v28; // [rsp+70h] [rbp-90h]
__int64 v29; // [rsp+78h] [rbp-88h]
__int64 v30; // [rsp+80h] [rbp-80h]
__int128 v31; // [rsp+88h] [rbp-78h]
_BYTE v32[15]; // [rsp+A0h] [rbp-60h] BYREF
char v33[129]; // [rsp+AFh] [rbp-51h] BYREF
ptr_range_lz outrange; // [rsp+130h] [rbp+30h] BYREF
v30 = -2;
v24 = a2;
v25 = a1;
#ifdef WIP
if ( a3 && a4 >= 8 && *(_DWORD *)a3 == 'dgrm' && *((_WORD *)a3 + 2) == '00' )
return x_sub_7FF6BF3A70B0_unmzp(a1, a2, (__int64)a3, a4, a5, a6);
if ( x_sub_7FF6BF4BCDF0_check_cbgmt((__int64)a3, a4) )
{
v11 = 0x80000000;
if ( x_sub_7FF6BF4BCDF0_check_cbgmt((__int64)a3, a4) )
{
v31 = *(_OWORD *)a3;
*(_OWORD *)&inrange.dataptr = *((_OWORD *)a3 + 1);
*(_OWORD *)&outrange.dataptr = *((_OWORD *)a3 + 2);
v27[0] = (__int64)&YCCBGMT::vftable;
v28 = 0ll;
v27[1] = a6;
v29 = 0ll;
v12 = LODWORD(inrange.dataptr)
* HIDWORD(inrange.dataptr)
* ((unsigned __int16)WORD2(_mm_srli_si128(*(__m128i *)&inrange.dataptr, 8).m128i_u64[0]) >> 3);
v13 = (_OWORD *)x_sub_7FF6BF50D8FC_malloc((unsigned int)(v12 + 48));
v14 = v13;
*(_QWORD *)v23 = v13;
v15 = x_sub_7FF6BF4BCE80_cbmt_inner((__int64)v27, (__int64)(v13 + 3), v12, (__int64)a3, a4);
if ( v15 )
{
if ( v15 == 6 )
v11 = 0x80000009;
}
else
{
*v13 = v31;
v13[1] = *(_OWORD *)&inrange.dataptr;
v13[2] = *(_OWORD *)&outrange.dataptr;
v14 = 0ll;
*(_QWORD *)v23 = 0ll;
*v25 = (__int64)v13;
*v24 = v12 + 48;
v11 = 0;
v13 = 0ll;
}
if ( v13 )
x_sub_7FF6BF50D4C4_free(v14);
v27[0] = (__int64)&YCCBGMT::vftable;
if ( v28 )
{
x_sub_7FF6BF50D4C4_free(v28);
return v11;
}
}
else
{
return 0x80000008;
}
return v11;
}
else
#endif
{
x_sub_7FF6BF52C1F0_memset(v33, 0, 0x79);
qmemcpy(v32, "LenZuCompressor", sizeof(v32));
memcpy(&outrange.dataptr, a3, 16);
v16 = 0;
v17 = 0;
v18 = 0;
do
{
if ( *((_BYTE *)&outrange.dataptr + v18) != v32[v18] )
break;
++v18;
++v17;
}
while ( v17 < 16 );
if ( v17 < 16 )
{
return 2;
}
else
{
outrange.dataptr = (unsigned __int8 *)a3;
outrange.datasz = a4;
outrange.dataszused = 0;
v23[0] = 0;
hdrrdoffset = x_sub_7FF6BF505210_lz_checkheader(&outrange);
if ( hdrrdoffset >= 0 )
{
x_sub_7FF6BF505110_lz_get_int(v23, &outrange, hdrrdoffset, 7u, 32);
if ( v23[0] )
v17 = v23[0];
}
v20 = (unsigned __int8 *)x_sub_7FF6BF50D8FC_malloc(v17);
v21 = v20;
v24 = (unsigned int *)v20;
outrange.dataptr = v20;
outrange.datasz = 0;
outrange.dataszused = 0;
inrange.dataptr = (unsigned __int8 *)a3;
inrange.datasz = a4;
inrange.dataszused = 0;
v22 = x_sub_7FF6BF504C50_lz_decompressmain(&outrange, &inrange);
if ( (int)outrange.datasz < 1 )
{
v16 = 0x80000009;
}
else
{
v21 = 0;
v24 = 0;
*a1 = (__int64)v20;
*a2 = v22;
v20 = 0;
}
if ( v20 )
x_sub_7FF6BF50D4C4_free(v21);
return v16;
}
}
}
int main(int argc, char** argv)
{
if (argc != 3)
return 1;
FILE* input_file = fopen(argv[1], "rb");
if (!input_file)
return 2;
fseek(input_file, 0, SEEK_END);
uint32_t input_file_size = ftell(input_file);
fseek(input_file, 0, SEEK_SET);
uint8_t *compressed_bytes = malloc(input_file_size);
if (!compressed_bytes)
return 3;
size_t input_file_bytes_read = fread(compressed_bytes, 1, input_file_size, input_file);
if (input_file_bytes_read != input_file_size)
return 4;
fclose(input_file);
if (memcmp(compressed_bytes, "LenZuCompressor", 16))
return 5;
{
int hdrrdoffset;
_DWORD uncompressed_size;
ptr_range_lz inrange;
ptr_range_lz outrange;
inrange.dataptr = compressed_bytes;
inrange.datasz = input_file_bytes_read;
inrange.dataszused = 0;
uncompressed_size = 0;
hdrrdoffset = x_sub_7FF6BF505210_lz_checkheader(&inrange);
if ( hdrrdoffset >= 0 )
{
x_sub_7FF6BF505110_lz_get_int(&uncompressed_size, &inrange, hdrrdoffset, 7u, 32);
}
if ( uncompressed_size == 0 )
{
return 6;
}
void *uncompressed_bytes = malloc(uncompressed_size * 4);
memset(uncompressed_bytes, 0, uncompressed_size * 4);
outrange.dataptr = ((unsigned __int8 *)uncompressed_bytes) + (uncompressed_size * 2);
outrange.datasz = 0;
outrange.dataszused = 0;
inrange.dataptr = compressed_bytes;
inrange.datasz = input_file_bytes_read;
inrange.dataszused = 0;
__int64 decres = x_sub_7FF6BF504C50_lz_decompressmain(&outrange, &inrange);
if ( decres < 1 )
{
return 7;
}
if ( (int)(outrange.datasz) < 1 )
{
return 8;
}
free(compressed_bytes);
FILE* out_file = fopen(argv[2], "wb");
if (!out_file)
return 9;
fwrite(((unsigned __int8 *)uncompressed_bytes) + (uncompressed_size * 2), 1, uncompressed_size, out_file);
fclose(out_file);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment