Skip to content

Instantly share code, notes, and snippets.

@kris7t
Created May 31, 2012 18:46
Show Gist options
  • Save kris7t/2845346 to your computer and use it in GitHub Desktop.
Save kris7t/2845346 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
@dw5
Copy link

dw5 commented Nov 3, 2017

Would be cool if you/I had a way to chat about S.W.I.N.E. related things, It anyways could help modding and etc...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment