Skip to content

Instantly share code, notes, and snippets.

@x1nixmzeng
Created April 11, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save x1nixmzeng/c37804744e5b25531f1f to your computer and use it in GitHub Desktop.
Save x1nixmzeng/c37804744e5b25531f1f to your computer and use it in GitHub Desktop.
Kane And Lynch LOC Binary Template
//--------------------------------------
//--- 010 Editor v5.0 Binary Template
//
// File: kl_loc.bt
// Author: x1nixmzeng/WRS
// Revision: 1
// Purpose: KaneAndLynch LOC files
//--------------------------------------
//////////////////////////////////////////////
#include "prelen.bt"
//////////////////////////////////////////////
//////////////////////////////////////////////
// **uncomment to dump to tty window**
//#define DUMP_PLAINTEXT
//////////////////////////////////////////////
enum <uchar> t
{
tempty = 0x8, //
tenum = 0x9, // ?
tlist = 0x10, //
tint = 0x28, //
tstr = 0x29, //
};
// hack to get credits output correctly
void PrintString(str &s, int chk)
{
local int i=0;
while( (s.len-i) > chk ) {
Printf("%s", SubStr(s.val,i,chk));
i+=chk;
}
Printf("%s", SubStr(s.val,i));
}
struct node;
struct node(int max_size)
{
local uint cur_size = 0;
Assert(max_size > 0); //sanity
// string
str _str(pnt);
cur_size += _str.len +1;
#ifdef DUMP_PLAINTEXT
Printf("\"%s\"", _str.val);
#endif
if( cur_size < max_size )
{
t type;
cur_size += sizeof(t);
switch(type)
{
case tlist:
{
// item count
uchar cnt;
cur_size += 1;
#ifdef DUMP_PLAINTEXT
Printf(" [\n");
#endif
if( cnt > 0 )
{
if( cnt > 1 )
{
// item sizes
uint flags[cnt-1];
cur_size += sizeof(uint) * (cnt-1);
local int i; local int last = 0;
for(i=0;i<cnt-1;++i)
{
node child(flags[i]-last);
cur_size += child.cur_size;
last = flags[i];
}
} // cnt > 1
Assert(max_size > cur_size);
node child(max_size-cur_size);
cur_size += child.cur_size;
}
#ifdef DUMP_PLAINTEXT
Printf("]");
#endif
break;
}
case tint:
{
// odd edgecase. expected int but it's been removed
if( cur_size == max_size )
{
#ifdef DUMP_PLAINTEXT
Printf(" 0"); // assuming zero
#endif
} else {
int val;
cur_size += 4;
#ifdef DUMP_PLAINTEXT
Printf(" %i", val);
#endif
}
break;
}
case tstr:
{
str ntstr(pnt);
#ifdef DUMP_PLAINTEXT
Printf(" = \"");
PrintString(ntstr,512);
Printf("\"");
#endif
cur_size += ntstr.len +1;
break;
}
case tenum:
{
str ntstr(pnt);
#ifdef DUMP_PLAINTEXT
Printf(" = \"");
PrintString(ntstr,512);
Printf("\"");
#endif
cur_size += ntstr.len +1;
uint unknown;
cur_size += sizeof(uint); Assert(unknown==0);
break;
}
}
local uint pad = max_size-cur_size;
if( pad != 0 )
{
Assert((pad&3)==0); // aligned to 4 bytes
int other[pad>>2];
cur_size = max_size;
#ifdef DUMP_PLAINTEXT
local int j;
for(j=0;j<pad>>2;++j)Printf(" %i", other[j]);
Printf("\n");
#endif
}
#ifdef DUMP_PLAINTEXT
else
{
Printf("\n");
}
#endif
}
};
//////////////////////////////////////////////
// Entry point
node root(FileSize());
Assert(FEof());
//////////////////////////////////////////////
@x1nixmzeng
Copy link
Author

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