mirror of https://github.com/x64dbg/btparser
150 lines
3.6 KiB
Plaintext
150 lines
3.6 KiB
Plaintext
|
//-----------------------------------
|
||
|
//--- 010 Editor v2.0 Binary Template
|
||
|
//
|
||
|
// File: RIFFTemplate.bt
|
||
|
// Author: gocha
|
||
|
// Revision: 1.0
|
||
|
// Purpose: Defines a template for
|
||
|
// parsing generic RIFF files.
|
||
|
//-----------------------------------
|
||
|
|
||
|
typedef CHAR ID[4];
|
||
|
|
||
|
local int cOverTheRainbowIndex = 0;
|
||
|
local int cOverTheRainbow[12] = {
|
||
|
0xbfbfef,
|
||
|
0xbfcfef,
|
||
|
0xbfefef,
|
||
|
0xbfefcf,
|
||
|
0xbfefbf,
|
||
|
0xcfefbf,
|
||
|
0xefefbf,
|
||
|
0xefcfbf,
|
||
|
0xefbfbf,
|
||
|
0xefbfcf,
|
||
|
0xefbfef,
|
||
|
0xcfbfef
|
||
|
};
|
||
|
local int cGrayZone = 0xd9dadc;
|
||
|
local int COLOR_LUT_LENGTH = sizeof(cOverTheRainbow) / sizeof(cOverTheRainbow[0]);
|
||
|
|
||
|
//-----------------------------------
|
||
|
// Define structures used in RIFF files
|
||
|
|
||
|
typedef struct {
|
||
|
ID chunkID;
|
||
|
DWORD chunkSize;
|
||
|
UCHAR data[chunkSize];
|
||
|
|
||
|
// Padding so the next chunk starts on an even byte
|
||
|
if( (chunkSize & 1) && (FTell() < FileSize()) )
|
||
|
UCHAR padding;
|
||
|
} CHUNK <read=ReadCHUNK>;
|
||
|
|
||
|
string ReadCHUNK( struct CHUNK &s )
|
||
|
{
|
||
|
return s.chunkID;
|
||
|
}
|
||
|
|
||
|
//typedef struct LISTCHUNK LISTCHUNK;
|
||
|
struct LISTCHUNK {
|
||
|
ID chunkID;
|
||
|
DWORD chunkSize;
|
||
|
local quad pos = FTell();
|
||
|
ID chunkType;
|
||
|
|
||
|
// Read the subchunks
|
||
|
local char tag[5];
|
||
|
local DWORD size;
|
||
|
while( FTell() - pos < chunkSize )
|
||
|
{
|
||
|
// Read the chunk tag
|
||
|
ReadBytes( tag, FTell(), 4 );
|
||
|
tag[4] = 0;
|
||
|
|
||
|
// Read the chunk size
|
||
|
size = ReadUInt( FTell() + 4 );
|
||
|
if( FTell() - pos + size > chunkSize ){
|
||
|
Printf( "Chunk '%s' of size %d at position 0x%LX exceeds the parent chunk size boundary.\n", tag, size, FTell() );
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// See which chunk this is
|
||
|
switch( tag )
|
||
|
{
|
||
|
case "LIST":
|
||
|
SetBackColor( cGrayZone );
|
||
|
struct LISTCHUNK list;
|
||
|
break;
|
||
|
default:
|
||
|
SetBackColor( cOverTheRainbow[cOverTheRainbowIndex] );
|
||
|
cOverTheRainbowIndex = (cOverTheRainbowIndex + 1) % COLOR_LUT_LENGTH;
|
||
|
CHUNK subchunk;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Padding so the next chunk starts on an even byte
|
||
|
if( (chunkSize & 1) && (FTell() < FileSize()) )
|
||
|
UCHAR padding;
|
||
|
};
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
ID groupID;
|
||
|
DWORD size;
|
||
|
ID riffType;
|
||
|
} RIFFHEADER;
|
||
|
|
||
|
|
||
|
|
||
|
//---------------------------------------------
|
||
|
|
||
|
// Define the headers
|
||
|
local quad riff_pos = FTell();
|
||
|
LittleEndian();
|
||
|
SetBackColor( cGrayZone );
|
||
|
RIFFHEADER header;
|
||
|
|
||
|
// Check for valid header
|
||
|
if( header.groupID != "RIFF" )
|
||
|
{
|
||
|
Warning( "File is not a valid RIFF file. Template stopped." );
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Read the file as a set of chunks
|
||
|
local char tag[5];
|
||
|
local DWORD size;
|
||
|
while( FTell() + 8 <= FileSize() && FTell() - riff_pos != header.size + 8 )
|
||
|
{
|
||
|
// Read the chunk tag
|
||
|
ReadBytes( tag, FTell(), 4 );
|
||
|
tag[4] = 0;
|
||
|
|
||
|
// Read the chunk size
|
||
|
size = ReadUInt( FTell() + 4 );
|
||
|
|
||
|
// See which chunk this is
|
||
|
switch( tag )
|
||
|
{
|
||
|
case "LIST":
|
||
|
SetBackColor( cGrayZone );
|
||
|
LISTCHUNK list;
|
||
|
break;
|
||
|
default:
|
||
|
SetBackColor( cOverTheRainbow[cOverTheRainbowIndex] );
|
||
|
cOverTheRainbowIndex = (cOverTheRainbowIndex + 1) % COLOR_LUT_LENGTH;
|
||
|
CHUNK chunk;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Verify the whole file size
|
||
|
local quad actual_size = FTell() - riff_pos;
|
||
|
if( actual_size != 8 + header.size )
|
||
|
{
|
||
|
Printf( "RIFF file size mismatch (header value %Ld, actual size %Ld).\n", header.size, actual_size - 8 );
|
||
|
return -1;
|
||
|
}
|