Skip to content

Instantly share code, notes, and snippets.

@dw5
Forked from kris7t/FindInArchive.cxx
Created November 1, 2019 13:43
Show Gist options
  • Save dw5/b71e248edfc152ff0ef7291b51e0a17b to your computer and use it in GitHub Desktop.
Save dw5/b71e248edfc152ff0ef7291b51e0a17b to your computer and use it in GitHub Desktop.
PACK file decompilation
SLibEntryRef __thiscall SFileSystem__FindInArchive(SFileSystem *this, int index, const char *str)
{
SLibEntryRef result; // qax@3
char name_offset; // ST13_1@14
const char *name; // ST18_4@14
unsigned __int8 name_length; // ST12_1@14
SFileSystem *self; // [sp+0h] [bp-14h]@1
int cmp; // [sp+8h] [bp-Ch]@14
SLibEntryHead *lib_entry; // [sp+Ch] [bp-8h]@13
SLibEntryRef *ref; // [sp+Ch] [bp-8h]@14
SLibEntryTail *tail; // [sp+Ch] [bp-8h]@15
ptrdiff_t right_child; // [sp+Ch] [bp-8h]@19
int i; // [sp+10h] [bp-4h]@8
self = this;
if ( index < 0
|| index >= this->count
|| (result.offset = (int)str, *str == '/')
|| (result.offset = *str, result.offset == '\\')
|| *str && (result.offset = (int)str, str[1] == ':') )
{
result.size = 0;
}
else
{
strcpy(find_what, str);
_strlwr(find_what);
for ( i = (int)find_what; *(_BYTE *)i; ++i )
{
if ( *(_BYTE *)i == '\\' )
*(_BYTE *)i = '/';
}
for ( lib_entry = *(SLibEntryHead **)&self->libs[12 * index + 8];
;
lib_entry = (SLibEntryHead *)(*(_DWORD *)right_child + *(_DWORD *)&self->libs[12 * index + 8]) )
{
while ( 1 )
{
name_offset = lib_entry->name_offset;
name = &lib_entry->name_length;
name_length = *name++;
cmp = strncmp(&find_what[(unsigned __int8)name_offset], name, name_length);
result.offset = (int)&name[name_length];
ref = (SLibEntryRef *)&name[name_length];
if ( cmp >= 0 )
break;
tail = (SLibEntryTail *)&ref[1];
result.offset = tail->has_left_child;
if ( !tail->has_left_child )
{
result.size = 0;
return result;
}
lib_entry = (SLibEntryHead *)&tail[1];
}
if ( cmp <= 0 )
break;
right_child = (ptrdiff_t)((char *)&ref[1].size + 1);// SLibEntryTail.right_child
result.offset = right_child;
if ( !*(_DWORD *)right_child )
{
result.size = 0;
return result;
}
}
result.size = (int)ref;
}
return result;
}
void *__thiscall SFileSystem__LoadFile(SFileSystem *this, const char *archived_name, int loglevel)
{
void *result; // eax@8
void *file_open_read; // [sp+0h] [bp-3Ch]@15
void *archived_file; // [sp+4h] [bp-38h]@6
SFileSystem *self; // [sp+8h] [bp-34h]@1
void *file_open_read_mem; // [sp+Ch] [bp-30h]@14
void *archived_file_mem; // [sp+14h] [bp-28h]@5
int packfile; // [sp+1Ch] [bp-20h]@4
int offset; // [sp+20h] [bp-1Ch]@3
int index; // [sp+24h] [bp-18h]@1
int assetfile; // [sp+28h] [bp-14h]@13
int filename; // [sp+2Ch] [bp-10h]@13
self = this;
for ( index = 0; index < self->count; ++index )
{
offset = (unsigned __int64)SFileSystem__FindInArchive(self, index, archived_name);
if ( offset )
{
packfile = _open(*(const char **)&self->libs[12 * index], 0x8000u);
if ( packfile < 0 )
{
if ( loglevel )
panic(global_logger, "%s: Couldn't open (%s)", loglevel, *(_DWORD *)&self->libs[12 * index]);
result = 0;
}
else
{
logMessage(global_logger, 2, "ARCHIVED FILE(%s)", archived_name);
archived_file_mem = operator new(0x30u);
if ( archived_file_mem )
archived_file = SArchivedFile__ctor(
archived_file_mem,
packfile,
*(_DWORD *)offset + *(_DWORD *)&self->libs[12 * index + 4] + 16,
*(_DWORD *)(offset + 4));
else
archived_file = 0;
result = archived_file;
}
return result;
}
}
filename = getUnarchivedName((const char **)self, archived_name);
assetfile = _open((const char *)filename, 0x8000u);
if ( assetfile < 0 )
{
if ( loglevel )
panic(global_logger, "%s: Couldn't open (%s)", loglevel, filename);
result = 0;
}
else
{
logMessage(global_logger, 2, "FILE OPEN READ(%s) = %d", archived_name, assetfile);
file_open_read_mem = operator new(0x28u);
if ( file_open_read_mem )
file_open_read = SFileOpenRead__ctor(file_open_read_mem, assetfile, 1, 0);
else
file_open_read = 0;
result = file_open_read;
}
return result;
}
int __thiscall SFileSystem__OpenArchive(SFileSystem *this, const char *filename)
{
SFileSystem *self; // [sp+0h] [bp-14h]@1
int file; // [sp+8h] [bp-Ch]@1
int buf; // [sp+Ch] [bp-8h]@3
int r; // [sp+10h] [bp-4h]@3
self = this;
file = _open(filename, 0x8000u);
if ( file < 0 )
panic(global_logger, "SFileSystem::OpenArchive: Couldn't open (%s)", filename);
r = _read(file, &buf, 4u);
if ( r != 4 || buf != '\x1B\x1ArS' ) // ident 1
panic(global_logger, "SFileSystem::OpenArchive: %s: Not a Stormregion file", filename);
r = _read(file, &buf, 4u);
if ( r != 4 || buf != 0xA870A0D ) // ident 2
panic(global_logger, "SFileSystem::OpenArchive: %s: Not a Stormregion file", filename);
r = _read(file, &buf, 4u);
if ( r != 4 || buf != 'KCAP' ) // 'PACK'
panic(global_logger, "SFileSystem::OpenArchive: %s: Not a 'PACK' file", filename);
r = _read(file, &buf, 4u); // lib size
if ( r != 4 )
panic(global_logger, "SFileSystem::OpenArchive: %s: Read error", filename);
*(_DWORD *)&self->libs[12 * self->count] = _strdup(filename);
*(_DWORD *)&self->libs[12 * self->count + 4] = buf;
*(_DWORD *)&self->libs[12 * self->count + 8] = operator new(*(_DWORD *)&self->libs[12 * self->count + 4]);
r = _read(file, *(void **)&self->libs[12 * self->count + 8], *(_DWORD *)&self->libs[12 * self->count + 4]);
if ( r != *(_DWORD *)&self->libs[12 * self->count + 4] )
panic(global_logger, "SFileSystem::OpenArchive: %s: Read error", filename);
++self->count;
return _close(file);
}
00000000 SFileSystem struc ; (sizeof=0xFFFF)
00000000 field_0 dd ?
00000004 field_4 dd ?
00000008 field_8 dd ?
0000000C count dd ?
00000010 libs db 65519 dup(?)
0000FFFF SFileSystem ends
0000FFFF
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 SArchive struc ; (sizeof=0xC)
00000000 name dd ?
00000004 lib_length dd ?
00000008 lib dd ?
0000000C SArchive ends
0000000C
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 SLibEntryRef struc ; (sizeof=0x8)
00000000 size dd ?
00000004 offset dd ?
00000008 SLibEntryRef ends
00000008
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 SLibEntryTail struc ; (sizeof=0x5)
00000000 has_left_child db ?
00000001 right_child dd ?
00000005 SLibEntryTail ends
00000005
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 SLibEntryHead struc ; (sizeof=0x101)
00000000 name_offset db ?
00000001 name_length db ?
00000002 name db 255 dup(?) ; char
00000101 SLibEntryHead ends
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment