commit 7c18c0238fed36ccfc19b0b01ebfc5f0cdaf5e6d Author: mrexodia Date: Sun Jun 5 00:00:36 2016 +0200 initial commit (lexer working for very very simple files) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a909efd --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.sdf +*.opensdf +*.suo +Release/ +Debug/ diff --git a/cparser.sln b/cparser.sln new file mode 100644 index 0000000..589ba5e --- /dev/null +++ b/cparser.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cparser", "cparser\cparser.vcxproj", "{B0411C78-2F06-49E0-8DE9-5C52A466F5DE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0411C78-2F06-49E0-8DE9-5C52A466F5DE}.Debug|Win32.ActiveCfg = Debug|Win32 + {B0411C78-2F06-49E0-8DE9-5C52A466F5DE}.Debug|Win32.Build.0 = Debug|Win32 + {B0411C78-2F06-49E0-8DE9-5C52A466F5DE}.Release|Win32.ActiveCfg = Release|Win32 + {B0411C78-2F06-49E0-8DE9-5C52A466F5DE}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cparser/.gitignore b/cparser/.gitignore new file mode 100644 index 0000000..8624af0 --- /dev/null +++ b/cparser/.gitignore @@ -0,0 +1,2 @@ +Debug/ +Release/ diff --git a/cparser/AVITemplate.bt b/cparser/AVITemplate.bt new file mode 100644 index 0000000..255351e --- /dev/null +++ b/cparser/AVITemplate.bt @@ -0,0 +1,306 @@ +//------------------------------------ +//--- 010 Editor v1.2 Binary Template +// +// Name: AVITemplate.bt +// Original Author: Blaine Lefebvre [bl] +// Contributor: Elias Bachaalany [eb] +// Purpose: Parse an AVI file +// +// Last Updated: 10/02/2006, 04:40 PM +// +// History +// ----------- +// [bl] original version: Blaine Lefevre +// 10/02/2006: +// - [eb] Added BITMAPINFO and WAVEFORMATEX proper strfHEADER recognition +// - [eb] Fixed 'idx1' parsing +//------------------------------------ + + +typedef struct +{ + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + WORD wBitsPerSample; + WORD cbSize; +} WAVEFORMATEX; + +// head structure info +typedef struct +{ + DWORD dwMicroSecPerFrame; + DWORD dwMaxBytesPerSec; + DWORD dwReserved1; + DWORD dwFlags; + DWORD dwTotalFrames; + DWORD dwInitialFrames; + DWORD dwStreams; + DWORD dwSuggestedBufferSize; + DWORD dwWidth; + DWORD dwHeight; + DWORD dwScale; + DWORD dwRate; + DWORD dwStart; + DWORD dwLength; +} MainAVIHeader; + +typedef struct +{ + uint32 biSize; + uint32 biWidth; + uint32 biHeight; + uint16 biPlanes; + uint16 biBitCount; + uint32 biCompression; + uint32 biSizeImage; + uint32 biXPelsPerMeter; + uint32 biYPelsPerMeter; + uint32 biClrUsed; + uint32 biClrImportant; +} BITMAPINFOHEADER; + +typedef struct +{ + unsigned char rgbBlue; + unsigned char rgbGreen; + unsigned char rgbRed; + unsigned char rgbReserved; +} RGBQUAD; + +typedef struct +{ + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors; +} BITMAPINFO; + +typedef struct +{ + char id[4]; + uint32 datalen; + MainAVIHeader data; +} avihHEADER; + + +// header stream structure info +typedef struct +{ + char fccType[4]; + char fccHandler[4]; + DWORD dwFlags; + DWORD dwReserved1; + DWORD dwInitialFrames; + DWORD dwScale; + DWORD dwRate; + DWORD dwStart; + DWORD dwLength; + DWORD dwSuggestedBufferSize; + DWORD dwQuality; + DWORD dwSampleSize; + DWORD xdwQuality; + DWORD xdwSampleSize; +} AVIStreamHeader; + +typedef struct +{ + char id[4]; + uint32 datalen; + AVIStreamHeader data; +}strhHEADER; + + +// Generic strfHEADER +typedef struct +{ + char id[4]; + uint32 datalen; + if (datalen % 2) + char data[datalen+1]; + else + char data[datalen]; +} strfHEADER; + +// strfHEADER with BITMAPINFOHEADER +typedef struct +{ + char id[4]; + uint32 datalen; + BITMAPINFOHEADER bmiHeader; + local int sz = sizeof(bmiHeader); + if (datalen == (sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD))) + { + RGBQUAD bmiColors; + sz += sizeof(RGBQUAD); + } + Printf("left: %d\n", sz); + char exData[datalen - sz]; +} strfHEADER_BIH; + + +// strfHEADER with WAVEFORMAT +typedef struct +{ + char id[4]; + uint32 datalen; + WAVEFORMATEX wave; + char exData[datalen - sizeof(WAVEFORMATEX)]; +} strfHEADER_WAVE; + +// +typedef struct +{ + char id[4]; + uint32 datalen; + if ( datalen % 2 ) + char data[datalen+1]; + else + char data[datalen]; +} strnHEADER; + +// +typedef struct +{ + char id[4]; + uint32 datalen; + if ( datalen % 2 ) + char data[datalen+1]; + else + char data[datalen]; +} genericblock; + + + +typedef struct +{ + char id[4]; + uint32 datalen; + char type[4]; + + if (!Memcmp(type,"hdrl",4)) + { + avihHEADER avhi; + } + else if (!Memcmp(type,"strl",4)) + { + strhHEADER strh; + + // Printf("->%c%c%c%c\n", strh.data.fccHandler[0], strh.data.fccHandler[1],strh.data.fccHandler[2],strh.data.fccHandler[3]); + if (Memcmp(strh.data.fccType, "vids", 4) == 0) + { + strfHEADER_BIH strf; + } + else if (Memcmp(strh.data.fccType, "auds", 4) == 0) + { + strfHEADER_WAVE strf; + } + else + { + strfHEADER strf; + } + strnHEADER strn; + } + else if (Memcmp(type,"movi",4) == 0) + { + local int32 pointer = 0; + local int32 stop = datalen - 4; + + //Printf("stop=%d\n", stop); + + do + { + genericblock gb; + pointer += sizeof(gb); + //Printf("+%x = %d\n", gb.datalen, pointer); + } while (pointer != stop); + } + else + { + char data[datalen-4]; + } +} LISTHEADER; + + +// junk structure info +typedef struct +{ + char id[4]; + uint32 datalen; + if ( datalen % 2 ) + char data[datalen+1]; + else + char data[datalen]; +} JUNKHEADER; + + +// aviindex structure info +typedef struct +{ + DWORD ckid; + DWORD dwFlags; + DWORD dwChunkOffset; + DWORD dwChunkLength; +} AVIINDEXENTRY; + +const DWORD AVIINDEXENTRYLEN = 16; + +typedef struct +{ + char id[4]; + uint32 datalen; + AVIINDEXENTRY data[datalen/AVIINDEXENTRYLEN]; +} idx1HEADER; + +// root structure info +typedef struct xroot +{ + char id[4]; // RIFF + if (root.id[3] == 'X') + { + Printf("Motorola format\n"); + BigEndian(); + } + else + { + Printf("Intel format\n"); + LittleEndian(); + } + + uint32 datalen; + char form[4]; + + if (Strcmp(form, "AVI ")) + { + Warning("Not a valid AVI file"); + return -1; + } +} ROOT; + +local char nheader[4]; + +ROOT root; + +while (!FEof()) +{ + ReadBytes(nheader,FTell(), 4); + + if (Memcmp(nheader,"LIST",4) == 0) + { + LISTHEADER list; + } + else if (Memcmp(nheader, "JUNK",4) == 0) + { + JUNKHEADER junk; + } + else if (Memcmp(nheader, "idx1",4) == 0) + { + idx1HEADER idx1; + } + else + { + if (!FEof()) + Printf("unknown chunk: %c%c%c%c", nheader[0],nheader[1],nheader[2],nheader[3]); + return -1; + } +} diff --git a/cparser/AndroidManifestTemplate.bt b/cparser/AndroidManifestTemplate.bt new file mode 100644 index 0000000..d77d866 --- /dev/null +++ b/cparser/AndroidManifestTemplate.bt @@ -0,0 +1,188 @@ +//-------------------------------------- +//--- 010 Editor v5.0.2 Binary Template +// +// File: AndroidManifestTemplate.bt +// Author: dongmu +// Revision: 1.0 +// Purpose: Define a template for parsing +// AndroidManifest.xml binary files. +//-------------------------------------- + +// Define the structures used in a +// AndroidManifest.xml binary file + +// Define Header +typedef struct { + uint magicnumber; + uint filesize; +} HEADER; + +// Define the string format +typedef struct { + ushort sfSize; + if (sfSize > 0) + { + struct { + char c1; + char c2; + } ONECHAR[ sfSize ]; + } + ushort sfEnd; +} STRING_ITEM; + + +// Define the string chunk +typedef struct { + uint scSignature; + uint scSize; + uint scStringCount; + uint scStyleCount; + uint scUNKNOWN; + uint scStringPoolOffset; + uint scStylePoolOffset; + uint scStringOffsets[ scStringCount ] ; + + if (scStyleCount > 0) + uint scStyleOffset[ scStylePoolOffset ]; + + // The Strings + local int i; + for (i = 0; i < scStringCount; i++) + { + if ((0x8+scStringPoolOffset + scStringOffsets[ i ]) < (0x8+scSize)) + { + FSeek(0x8+scStringPoolOffset + scStringOffsets[ i ]); + STRING_ITEM strItem; + } + } + +} STRINGCHUNK; + +// Define the Resource chunk +typedef struct { + + local int pos = FTell(); + + uint rcSignature; + uint rcSize; + uint rcItem[ rcSize/4 - 2 ]; + +} RESOURCEIDCHUNK; + +// Define the Start Namespace Chunk +typedef struct { + uint sncSignature; + uint sncSize; + uint sncLineNumber; + uint sncUNKNOWN; + uint sncPrefix; + uint sncUri; +} SNCHUNK; + +// Define the End Namespace Chunk +typedef struct { + uint encSignature; + uint encSize; + uint encLineNumber; + uint encUNKNOWN; + uint encPrefix; + uint encUri; +} ENCHUNK; + +// Define the Attribute Chunk +typedef struct { + uint acNamespaceUri; + uint acName; + uint acValueStr; + uint acType ; + uint acData; +} ATTRIBUTECHUNK; + + +// Define the Start Tag Chunk +typedef struct { + local int pos = FTell(); + uint stcSignature; + uint stcSize; + uint stcLineNumber; + uint stcUNKNOWN; + uint stcNamespaceUri; + uint stcName; + uint stcFlags; + uint stcAttributeCount; + uint stcClassAttribute; + + while (FTell() != pos + stcSize) + ATTRIBUTECHUNK attributeChunk; +} STCHUNK; + +// Define the End Tag Chunk +typedef struct { + uint etcSignature; + uint etcSize; + uint etcLineNumber; + uint etcUNKNOWN; + uint etcNamespaceUri; + uint etcName; +} ETCHUNK; + +// Define the Text Chunk +typedef struct { + uint tcSignature; + uint tcSize; + uint tcLineNumber; + uint tcUNKNOWN; + uint tcName; + uint tcUNKNOWN; + uint tcUNNNOWN; +} TEXTCHUNK; + +//-------------------------------------- +// Define the file + +local uint tag; + +LittleEndian(); +HEADER header; + +SetBackColor( cLtGreen ); +STRINGCHUNK stringChunk; +// Sometimes there are some zeros padding after the string chunk +FSeek(0x8+stringChunk.scSize); + +SetBackColor( cLtBlue ); +RESOURCEIDCHUNK resourceChunk; +FSeek(resourceChunk.pos+resourceChunk.rcSize); + +while( !FEof() ) +{ + // Read a tag + tag = ReadUInt( FTell() ); + + // Read data depending upon tag + if (tag == 0x00100100) + { + SetBackColor( cLtPurple ); + SNCHUNK startNamespaceChunk; + } + else if (tag == 0x00100101) + { + SetBackColor( cLtPurple ); + ENCHUNK endNamespaceChunk; + } + else if (tag == 0x00100102) + { + SetBackColor( cLtGreen ); + STCHUNK startTagChunk; + } + else if (tag == 0x00100103) + { + SetBackColor( cLtGreen ); + ETCHUNK endTagChunk; + } + else if (tag == 0x00100104) + { + SetBackColor( cLtBlue ); + TEXTCHUNK TextChunk; + } +} diff --git a/cparser/BMPTemplate.bt b/cparser/BMPTemplate.bt new file mode 100644 index 0000000..3813816 --- /dev/null +++ b/cparser/BMPTemplate.bt @@ -0,0 +1,127 @@ +//----------------------------------- +//--- 010 Editor v2.0 Binary Template +// +// File: BMPTemplate.bt +// Author: SweetScape Software +// Revision: 2.2 +// Purpose: Defines a template for +// parsing BMP image files. +//----------------------------------- + +// Define structures used in BMP files + +typedef struct { // bmfh + CHAR bfType[2]; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; +} BITMAPFILEHEADER; + +typedef struct { // bmih + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +} BITMAPINFOHEADER; + +typedef struct { // rgbq + UBYTE rgbBlue; + UBYTE rgbGreen; + UBYTE rgbRed; + UBYTE rgbReserved; +} RGBQUAD ; + +typedef struct { // rgbt + UBYTE rgbBlue; + UBYTE rgbGreen; + UBYTE rgbRed; +} RGBTRIPLE ; + +//--------------------------------------------- +// Custom read functions for color types - this allows the +// color to be displayed without having to open up the structure. + +string ReadRGBQUAD( RGBQUAD &a ) +{ + string s; + SPrintf( s, "#%02X%02X%02X%02X", (int)a.rgbReserved, (int)a.rgbRed, (int)a.rgbGreen, (int)a.rgbBlue ); + return s; +} + +string ReadRGBTRIPLE( RGBTRIPLE &a ) +{ + string s; + SPrintf( s, "#%02X%02X%02X", (int)a.rgbRed, (int)a.rgbGreen, (int)a.rgbBlue ); + return s; +} + +//--------------------------------------------- + +// Define the headers +LittleEndian(); +SetBackColor( cLtGray ); +BITMAPFILEHEADER bmfh; +BITMAPINFOHEADER bmih; + +// Check for header +if( bmfh.bfType != "BM" ) +{ + Warning( "File is not a bitmap. Template stopped." ); + return -1; +} + +// Define the color table +if( (bmih.biBitCount != 24) && (bmih.biBitCount != 32) ) +{ + SetBackColor( cLtAqua ); + if( bmih.biClrUsed > 0 ) + RGBQUAD aColors[ bmih.biClrUsed ]; + else + RGBQUAD aColors[ 1 << bmih.biBitCount ]; +} + +// Define the bytes of the data +SetBackColor( cNone ); +if( bmih.biCompression > 0 ) +{ + // Bytes are compressed + if( bmih.biSizeImage > 0 ) + UBYTE rleData[ bmih.biSizeImage ]; + else + UBYTE rleData[ bmfh.bfSize - FTell() ]; +} +else +{ + // Calculate bytes per line and padding required + local int bytesPerLine = (int)Ceil( bmih.biWidth * bmih.biBitCount / 8.0 ); + local int padding = 4 - (bytesPerLine % 4); + if( padding == 4 ) + padding = 0; + + // Define each line of the image + struct BITMAPLINE { + + // Define color data + if( bmih.biBitCount < 8 ) + UBYTE imageData[ bytesPerLine ]; + else if( bmih.biBitCount == 8 ) + UBYTE colorIndex[ bmih.biWidth ]; + else if( bmih.biBitCount == 24 ) + RGBTRIPLE colors[ bmih.biWidth ]; + else if( bmih.biBitCount == 32 ) + RGBQUAD colors[ bmih.biWidth ]; + + // Pad if necessary + if( padding != 0 ) + UBYTE padBytes[ padding ]; + + } lines[ bmih.biHeight ] ; +} \ No newline at end of file diff --git a/cparser/CABTemplate.bt b/cparser/CABTemplate.bt new file mode 100644 index 0000000..c351883 --- /dev/null +++ b/cparser/CABTemplate.bt @@ -0,0 +1,117 @@ +//-------------------------------------- +//--- 010 Editor v3.2.2 Binary Template +// +// File: cabtemplate.bt +// Author: Alex McDonnell +// Revision: 0.1 +// Purpose: Parse Microsoft CAB files +// Changes: +// 0.2 (SweetScape): +// - Allow for multiple flags to be set at the same time +//-------------------------------------- + +// Define structures used in CAB files + +typedef struct { +//header + char signature[4]; /* 'MSCF' */ + uint reserved1; /* 0x00000000 */ + uint cbCabinet; /* size of this cabinet file in bytes */ + uint reserved2; /* 0x00000000 */ + uint coffFiles; /* offset of the first CFFILE entry */ + uint reserved3; /* 0x00000000 */ + ubyte versionMinor; /* cabinet file format version, minor 0x03 */ + ubyte versionMajor; /* cabinet file format version, major 0x01 */ + ushort cFolders; /* number of CFFOLDER entries in this cabinet */ + ushort cFiles; /* number of CFFILE entries in this cabinet */ + ushort flags; /* cabinet file option indicators 0x0001 0x0002 0x0004 only*/ + ushort setID; /* must be the same for all cabinets in a set */ + ushort iCabinet; /* number of this cabinet file in a set */ + + if(flags & 4){ + + ushort cbCFHeader; /* (optional) size of per-cabinet reserved area */ + ubyte cbCFFolder; /* (optional) size of per-folder reserved area */ + ubyte cbCFData; /* (optional) size of per-datablock reserved area */ + + if(cbCFHeader > 0) + char abReserve[cbCFHeader]; /* (optional) per-cabinet reserved area */ + + } + if(flags & 1){ + + char szCabinetPrev[];/* (optional) name of previous cabinet file */ + char szDiskPrev[]; /* (optional) name of previous disk */ + + } + if(flags & 2){ + + char szCabinetNext[]; /* (optional) name of next cabinet file */ + char szDiskNext[]; /* (optional) name of next disk */ + + } + +} CFHEADER; + +LittleEndian(); +CFHEADER header; +local uint counter = 0; + +typedef struct { +//folder + uint coffCabStart; /* offset of the first CFDATA block in this folder */ + ushort cCFData; /* number of CFDATA blocks in this folder */ + ushort typeCompress; /* compression type indicator */ + + if( exists(header.cbCFFolder)) + char abReserve[header.cbCFFolder]; /* (optional) per-folder reserved area */ + +} CFFOLDER; + +typedef struct { +//file + uint cbFile; /* uncompressed size of this file in bytes */ + uint uoffFolderStart; /* uncompressed offset of this file in the folder */ + ushort iFolder; /* index into the CFFOLDER area */ + DOSDATE date; /* date stamp for this file */ + DOSTIME time; /* time stamp for this file */ + ushort attribs; /* attribute flags for this file */ + char szName[]; /* name of this file */ +} CFFILE; + +typedef struct { +//data + uint csum; /* checksum of this CFDATA entry */ + ushort cbData; /* number of compressed bytes in this block */ + ushort cbUncomp; /* number of uncompressed bytes in this block */ + + if( exists(header.cbCFData)) + char abReserve[header.cbCFData]; /* (optional) per-datablock reserved area */ + + char ab[cbData]; /* compressed data bytes */ +} CFDATA; + +while(header.cFolders > counter){ + + counter++; + CFFOLDER folder; + +} + +counter = 0; + +while(header.cFiles > counter){ + + counter++; + CFFILE file; + +} + +counter = 0; + +while(folder.cCFData > counter){ + + counter++; + CFDATA data; + +} \ No newline at end of file diff --git a/cparser/CAPTemplate.bt b/cparser/CAPTemplate.bt new file mode 100644 index 0000000..be961bb --- /dev/null +++ b/cparser/CAPTemplate.bt @@ -0,0 +1,1292 @@ +//----------------------------------- +//--- 010 Editor v5.0 Binary Template +// +// File: CAPTemplate.bt +// Author: Agus Purwanto +// Revision: 1.0 +// Purpose: a template for parsing java card CAP file. + +// Define structures used in CAP files + +//enum used for compression format +local ushort method_offsets[256]; +local ushort method_codesize[256]; +local uint64 tail_index = 0; +local uint64 head_index = 0; + +void queue_push_method(ushort offset, ushort codesize) { + method_offsets[tail_index] = offset; + method_codesize[tail_index] = codesize; + tail_index ++; +} + +uint queue_pop_method() { + if(head_index != tail_index) { + head_index ++; + return 1; + } else { + return 0; + } +} + +uint queue_peek_method() { + if(head_index != tail_index) { + return 1; + } else { + return 0; + } +} + +typedef enum { + COMP_STORED = 0, + COMP_SHRUNK = 1, + COMP_REDUCED1 = 2, + COMP_REDUCED2 = 3, + COMP_REDUCED3 = 4, + COMP_REDUCED4 = 5, + COMP_IMPLODED = 6, + COMP_TOKEN = 7, + COMP_DEFLATE = 8, + COMP_DEFLATE64 = 9 +} COMPTYPE; + +typedef enum { //javacard list of supported opcode + aaload = 0x24, + aastore = 0x37, + aconst_null = 0x01, + aload = 0x15, + aload_0 = 0x18, + aload_1 = 0x19, + aload_2 = 0x1a, + aload_3 = 0x1b, + anewarray = 0x91, + areturn = 0x77, + arraylength = 0x92, + astore = 0x28, + astore_0 = 0x2b, + astore_1 = 0x2c, + astore_2 = 0x2d, + astore_3 = 0x2e, + athrow = 0x93, + baload = 0x25, + bastore = 0x38, + bipush = 0x12, + bspush = 0x10, + checkcast = 0x94, + dup = 0x3d, + dup_x = 0x3f, + dup2 = 0x3e, + getfield_a = 0x83, + getfield_b = 0x84, + getfield_s = 0x85, + getfield_i = 0x86, + getfield_a_this = 0xad, + getfield_b_this = 0xae, + getfield_s_this = 0xaf, + getfield_i_this = 0xb0, + getfield_a_w = 0xa9, + getfield_b_w = 0xaa, + getfield_s_w = 0xab, + getfield_i_w = 0xac, + getstatic_a = 0x7b, + getstatic_b = 0x7c, + getstatic_s = 0x7d, + getstatic_i = 0x7e, + goto = 0x70, + goto_w = 0xa8, + i2b = 0x5d, + i2s = 0x5e, + iadd = 0x42, + iaload = 0x27, + iand = 0x54, + iastore = 0x3a, + icmp = 0x5f, + iconst_m1 = 0x09, + iconst_0 = 0x0a, + iconst_1 = 0x0b, + iconst_2 = 0x0c, + iconst_3 = 0x0d, + iconst_4 = 0x0e, + iconst_5 = 0x0f, + idiv = 0x48, + if_acmpeq = 0x68, + if_acmpne = 0x69, + if_acmpeq_w = 0xa0, + if_acmpne_w = 0xa1, + if_scmpeq = 0x6a, + if_scmpne = 0x6b, + if_scmplt = 0x6c, + if_scmpge = 0x6d, + if_scmpgt = 0x6e, + if_scmple = 0x6f, + if_scmpeq_w = 0xa2, + if_scmpne_w = 0xa3, + if_scmplt_w = 0xa4, + if_scmpge_w = 0xa5, + if_scmpgt_w = 0xa6, + if_scmple_w = 0xa7, + ifeq = 0x60, + ifne = 0x61, + iflt = 0x62, + ifge = 0x63, + ifgt = 0x64, + ifle = 0x65, + ifeq_w = 0x98, + ifne_w = 0x99, + iflt_w = 0x9a, + ifge_w = 0x9b, + ifgt_w = 0x9c, + ifle_w = 0x9d, + ifnonnull = 0x67, + ifnonnull_w = 0x9f, + ifnull = 0x66, + ifnull_w = 0x9e, + iinc = 0x5a, + iinc_w = 0x97, + iipush = 0x14, + iload = 0x17, + iload_0 = 0x20, + iload_1 = 0x21, + iload_2 = 0x22, + iload_3 = 0x23, + ilookupswitch = 0x76, + imul = 0x46, + ineg = 0x4c, + instanceof = 0x95, + invokeinterface = 0x8e, + invokespecial = 0x8c, + invokestatic = 0x8d, + invokevirtual = 0x8b, + ior = 0x56, + irem = 0x4a, + ireturn = 0x79, + ishl = 0x4e, + ishr = 0x50, + istore = 0x2a, + istore_0 = 0x33, + istore_1 = 0x34, + istore_2 = 0x35, + istore_3 = 0x36, + isub = 0x44, + itableswitch = 0x74, + iushr = 0x52, + ixor = 0x58, + jsr = 0x71, + new = 0x8f, + newarray = 0x90, + nop = 0, + pop = 0x3b, + pop2 = 0x3c, + putfield_a = 0x87, + putfield_b = 0x88, + putfield_s = 0x89, + putfield_i = 0x8a, + putfield_a_this = 0xb5, + putfield_b_this = 0xb6, + putfield_s_this = 0xb7, + putfield_i_this = 0xb8, + putfield_a_w = 0xb1, + putfield_b_w = 0xb2, + putfield_s_w = 0xb3, + putfield_i_w = 0xb4, + putstatic_a = 0x7f, + putstatic_b = 0x80, + putstatic_s = 0x81, + putstatic_i = 0x82, + ret = 0x72, + Return = 0x7a, + s2b = 0x5b, + s2i = 0x5c, + sadd = 0x41, + saload = 0x46, + sand = 0x53, + sastore = 0x39, + sconst_m1 = 0x02, + sconst_0 = 0x03, + sconst_1 = 0x04, + sconst_2 = 0x05, + sconst_3 = 0x06, + sconst_4 = 0x07, + sconst_5 = 0x08, + sdiv = 0x47, + sinc = 0x59, + sinc_w = 0x96, + sipush = 0x13, + sload = 0x16, + sload_0 = 0x1c, + sload_1 = 0x1d, + sload_2 = 0x1e, + sload_3 = 0x1f, + slookupswitch = 0x75, + smul = 0x45, + sneg = 0x4b, + sor = 0x55, + srem = 0x49, + sreturn = 0x78, + sshl = 0x4d, + sshr = 0x4f, + sspush = 0x11, + sstore = 0x29, + sstore_0 = 0x2f, + sstore_1 = 0x30, + sstore_2 = 0x31, + sstore_3 = 0x32, + ssub = 0x43, + stableswitch = 0x73, + sushr = 0x51, + swap_x = 0x40, + sxor = 0x57 +} JVCODE; + +typedef struct { + char minor_version; + char major_version; + char AID_length; + if( AID_length > 0 ) + char AID[ AID_length ]; +} PACKAGE_INFO; + +typedef struct { + char name_length; + if( name_length > 0 ) + char name[ name_length ]; +} PACKAGE_NAME_INFO; + +typedef struct { + ushort image_size; + ushort array_init_count; + ushort array_init_size; +} STATIC_FIELD_SIZE_INFO; + +typedef struct { + uchar component_tag; + ushort size; + uchar AID_length; + if( AID_length > 0 ) + char AID[ AID_length ]; +} CUSTOM_COMPONENT_INFO; + +typedef struct { + char tag; + ushort size; + uint magic; + uchar minor_version; + uchar major_version; + uchar flags; + PACKAGE_INFO package; + PACKAGE_NAME_INFO package_name; +} HEADER_COMPONENT; + +typedef struct { + uchar tag; + ushort size; + ushort component_sizes[12]; + STATIC_FIELD_SIZE_INFO static_field_size; + uchar import_count; + uchar applet_count; + uchar custom_count; + if(custom_count > 0) + CUSTOM_COMPONENT_INFO custom_components[custom_count]; +} DIRECTORY_COMPONENT; + +typedef struct { + uchar AID_length; + if( AID_length > 0 ) + char AID[ AID_length ]; + ushort install_method_offset; +} APPLET_INFO; + +typedef struct { + uchar tag; + ushort size; + uchar count; + if(count > 0) + APPLET_INFO applets[count] ; +} APPLET_COMPONENT; + +typedef struct { + uchar tag; + ushort size; + uchar count; + if(count > 0) + PACKAGE_INFO packages[count] ; +} IMPORT_COMPONENT; + +typedef struct { + uchar nibble_count; + if(nibble_count > 0) + uchar type[(nibble_count + 1) / 2]; +} TYPE_DESCRIPTOR; + +typedef struct { + if(ReadByte(FTell()) & 0x80) { + ushort internal_class_ref; + } else { + uchar package_token; + uchar class_token; + } +} CLASS_REF; + +typedef struct { + uchar interface_name_length; + if(interface_name_length > 0) + uchar interface_name[interface_name_length]; +} INTERFACE_NAME_INFO; + +typedef struct { + CLASS_REF interface; + uchar count; + if(count > 0) + uchar index[count]; +} IMPLEMENTED_INTERFACE_INFO; + +typedef struct { + ushort remote_method_hash; + ushort signature_offset; + uchar virtual_method_token; +} REMOTE_METHOD_INFO; + +typedef struct { + uchar tag; + CLASS_REF class_ref; + uchar padding; +} CONST_CLASSREF_INFO; + +typedef struct { + uchar tag; + CLASS_REF class; + uchar token; +} CONST_INSTANCEFIELDREF_INFO; + +typedef struct { + uchar tag; + CLASS_REF class; + uchar token; +} CONST_VIRTUALMETHODREF_INFO; + +typedef struct { + uchar tag; + CLASS_REF class; + uchar token; +} CONST_SUPERMETHODREF_INFO; + +typedef struct { + if(ReadByte( FTell() ) == 0) { + uchar padding; + ushort offset; + } else { + uchar package_token; + uchar class_token; + uchar token; + } +} STATIC_FIELD_REF; + +typedef struct { + CLASS_REF class; + uchar token; +} INSTANCE_FIELD_REF; + +typedef struct { + if(ReadByte( FTell() ) == 0) { + uchar padding; + ushort offset; + } else { + uchar package_token; + uchar class_token; + uchar token; + } +} STATIC_METHOD_REF; + +typedef struct { + uchar tag; + STATIC_FIELD_REF static_field_ref; +} CONST_STATICFIELDREF_INFO; + +typedef struct { + uchar tag; + STATIC_METHOD_REF static_method_ref; +} CONST_STATICMETHODREF_INFO; + +typedef struct { + uchar remote_methods_count; + if(remote_methods_count > 0) + REMOTE_METHOD_INFO remote_methods[remote_methods_count] ; + uchar hash_modifier_length; + if(hash_modifier_length > 0) + uchar hash_modifier[hash_modifier_length] ; + uchar class_name_length; + if(class_name_length > 0) + uchar class_name[class_name_length] ; + uchar remote_interface_count; + if(remote_interface_count > 0) + CLASS_REF remote_interfaces[remote_interface_count] ; +} REMOTE_INTERFACE_INFO; + +typedef struct { + //uchar bitfield; + uchar flags:4; + uchar interface_count:4; + CLASS_REF super_class_ref; + uchar declared_instance_size; + uchar first_reference_token; + uchar reference_count; + uchar public_method_table_base; + uchar public_method_table_count; + uchar package_method_table_base; + uchar package_method_table_count; + if(public_method_table_count > 0) + ushort public_virtual_method_table[public_method_table_count] ; + if(package_method_table_count > 0) + ushort package_virtual_method_table[package_method_table_count] ; + if(interface_count > 0 ) + IMPLEMENTED_INTERFACE_INFO interfaces[interface_count] ; + if(flags & 0x2) + REMOTE_INTERFACE_INFO remote_interfaces; +} CLASS_INFO; + +typedef struct { + //uchar bitfield; + uchar flags:4; + uchar interface_count:4; + if(interface_count > 0) + CLASS_REF super_interfaces[interface_count] ; + if(flags & 0x2) + INTERFACE_NAME_INFO interface_name; +} INTERFACE_INFO; + +typedef struct { + uchar tag; + ushort size; + local uint64 start_index = FTell(); + ushort signature_pool_length; + local uint64 sign_index = FTell(); + if(signature_pool_length > 0) { + //uchar signature_pool[signature_pool_length]; + while(FTell() < (sign_index+signature_pool_length)) { + TYPE_DESCRIPTOR descriptor; + } + } + //start_index = start_index + signature_pool_length + 2; + //start_index = FTell(); + while(FTell() < (start_index+size)) { + if((ReadByte( FTell() ) & 0x80)) { + //FSkip( -1 ); + INTERFACE_INFO interface; + } else { + //FSkip( -1 ); + CLASS_INFO class; + } + } +} CLASS_COMPONENT; + +typedef struct { + uchar type; + ushort count; + uchar values[count]; +} ARRAY_INIT_INFO; + +typedef struct { + uchar tag; + ushort size; + ushort image_size; + ushort reference_count; + ushort array_init_count; + if(array_init_count > 0) + ARRAY_INIT_INFO array_init[array_init_count] ; + ushort default_value_count; + ushort non_default_value_count; + if(non_default_value_count > 0) + uchar non_default_values[non_default_value_count] ; +} STATICFIELD_COMPONENT; + +typedef struct { + uchar tag; + ushort size; + ushort byte_index_count; + uchar offsets_to_byte_indices[byte_index_count]; + ushort byte2_index_count; + uchar offsets_to_byte2_indices[byte2_index_count]; +} REFERENCELOC_COMPONENT; + +typedef struct { + uchar tag; + ushort size; + uchar class_count; + struct { + ushort class_offset; + uchar static_field_count; + uchar static_method_count; + ushort static_field_offsets[static_field_count]; + ushort static_method_offsets[static_method_count]; + } class_exports[class_count] ; +} EXPORT_COMPONENT; + +typedef struct { + ushort start_offset; + //ushort bitfield; + ushort stop_bit:1; + ushort active_length:15; + ushort handler_offset; + ushort catch_type_index; +} EXCEPTION_HANDLER_INFO; + +typedef struct { + uchar flags:4; + uchar max_stack:4; + uchar nargs:4; + uchar max_locals:4; +} METHOD_HEADER_INFO; + +typedef struct { + uchar flags:4; + uchar padding:4; + uchar max_stack; + uchar nargs; + uchar max_locals; +} EXTENDED_METHOD_HEADER_INFO; + +typedef struct { + JVCODE opcode; + + switch(opcode) { + case aaload: + case aastore : // 0x37, + case aconst_null : // 0x01, no operand + case aload_0 : // 0x18, + case aload_1 : // 0x19, + case aload_2 : // 0x1a, + case aload_3 : // 0x1b, + case areturn : // 0x77, + case arraylength : // 0x92, + case astore_0 : // 0x2b, + case astore_1 : // 0x2c, + case astore_2 : // 0x2d, + case astore_3 : // 0x2e, + case athrow : // 0x93, + case baload : // 0x25, + case bastore : // 0x38, + case dup : // 0x3d, + case dup2 : // 0x3e, + case i2b : // 0x5d, + case i2s : // 0x5e, + case iadd : // 0x42, + case iaload : // 0x27, + case iand : // 0x54, + case iastore : // 0x3a, + case icmp : // 0x5f, + case iconst_m1 : // 0x09, + case iconst_0 : // 0x0a, + case iconst_1 : // 0x0b, + case iconst_2 : // 0x0c, + case iconst_3 : // 0x0d, + case iconst_4 : // 0x0e, + case iconst_5 : // 0x0f, + case idiv : // 0x48, + case iload_0 : // 0x20, + case iload_1 : // 0x21, + case iload_2 : // 0x22, + case iload_3 : // 0x23, + case imul : // 0x46, + case ineg : // 0x4c, + case ior : // 0x56, + case irem : // 0x4a, + case ireturn : // 0x79, + case ishl : // 0x4e, + case ishr : // 0x50, + case istore_0 : // 0x33, + case istore_1 : // 0x34, + case istore_2 : // 0x35, + case istore_3 : // 0x36, + case isub : // 0x44, + case iushr : // 0x52, + case ixor : // 0x58, + case nop : // 0, + case pop : // 0x3b, + case pop2 : // 0x3c, + case Return : // 0x7a, + case s2b : // 0x5b, + case s2i : // 0x5c, + case sadd : // 0x41, + case saload : // 0x46, + case sand : // 0x53, + case sastore : // 0x39, + case sconst_m1 : // 0x02, + case sconst_0 : // 0x03, + case sconst_1 : // 0x04, + case sconst_2 : // 0x05, + case sconst_3 : // 0x06, + case sconst_4 : // 0x07, + case sconst_5 : // 0x08, + case sdiv : // 0x47, + case sload_0 : // 0x1c, + case sload_1 : // 0x1d, + case sload_2 : // 0x1e, + case sload_3 : // 0x1f, + case smul : // 0x45, + case sneg : // 0x4b, + case sor : // 0x55, + case srem : // 0x49, + case sreturn : // 0x78, + case sshl : // 0x4d, + case sshr : // 0x4f, + case sstore_0 : // 0x2f, + case sstore_1 : // 0x30, + case sstore_2 : // 0x31, + case sstore_3 : // 0x32, + case ssub : // 0x43, + case sushr : // 0x51, + case sxor : // 0x57 + + break; + case aload : // 0x15, //singl byte operand + case astore : // 0x28, + case bipush : // 0x12, + case bspush : // 0x10, + case dup_x : // 0x3f, + case getfield_a : // 0x83, + case getfield_b : // 0x84, + case getfield_s : // 0x85, + case getfield_i : // 0x86, + case getfield_a_this : // 0xad, + case getfield_b_this : // 0xae, + case getfield_s_this : // 0xaf, + case getfield_i_this : // 0xb0, + case goto : // 0x70, + case if_acmpeq : // 0x68, + case if_acmpne : // 0x69, + case if_scmpeq : // 0x6a, + case if_scmpne : // 0x6b, + case if_scmplt : // 0x6c, + case if_scmpge : // 0x6d, + case if_scmpgt : // 0x6e, + case if_scmple : // 0x6f, + case ifeq : // 0x60, + case ifne : // 0x61, + case iflt : // 0x62, + case ifge : // 0x63, + case ifgt : // 0x64, + case ifle : // 0x65, + case ifnonnull : // 0x67, + case ifnull : // 0x66, + case iload : // 0x17, + case istore : // 0x2a, + case newarray : // 0x90, + case putfield_a : // 0x87, + case putfield_b : // 0x88, + case putfield_s : // 0x89, + case putfield_i : // 0x8a, + case putfield_a_this : // 0xb5, + case putfield_b_this : // 0xb6, + case putfield_s_this : // 0xb7, + case putfield_i_this : // 0xb8, + case ret : // 0x72, + case sload : // 0x16, + case sstore : // 0x29, + case swap_x : // 0x40, + uchar operand1; + break; + case anewarray : // 0x91, //single short operand + case getfield_a_w : // 0xa9, + case getfield_b_w : // 0xaa, + case getfield_s_w : // 0xab, + case getfield_i_w : // 0xac, + case getstatic_a : // 0x7b, + case getstatic_b : // 0x7c, + case getstatic_s : // 0x7d, + case getstatic_i : // 0x7e, + case goto_w : // 0xa8, + case if_acmpeq_w : // 0xa0, + case if_acmpne_w : // 0xa1, + case if_scmpeq_w : // 0xa2, + case if_scmpne_w : // 0xa3, + case if_scmplt_w : // 0xa4, + case if_scmpge_w : // 0xa5, + case if_scmpgt_w : // 0xa6, + case if_scmple_w : // 0xa7, + case ifeq_w : // 0x98, + case ifne_w : // 0x99, + case iflt_w : // 0x9a, + case ifge_w : // 0x9b, + case ifgt_w : // 0x9c, + case ifle_w : // 0x9d, + case ifnonnull_w : // 0x9f, + case ifnull_w : // 0x9e, + case invokespecial : // 0x8c, + case invokestatic : // 0x8d, + case invokevirtual : // 0x8b, + case jsr : // 0x71, + case new : // 0x8f, + case putfield_a_w : // 0xb1, + case putfield_b_w : // 0xb2, + case putfield_s_w : // 0xb3, + case putfield_i_w : // 0xb4, + case putstatic_a : // 0x7f, + case putstatic_b : // 0x80, + case putstatic_s : // 0x81, + case putstatic_i : // 0x82, + case sipush : // 0x13, + case sspush : // 0x11, + ushort operand1; + break; + case checkcast : // 0x94, //type 1 + 2byte index + case iinc_w : // 0x97, + case instanceof : // 0x95, + case sinc_w : // 0x96, + uchar operand1; + ushort operand2; + break; + case iinc : // 0x5a, //index 1 + const 1 + case sinc : // 0x59, + uchar operand1; + uchar operand2; + break; + case iipush : // 0x14, //4byte word + uint operand1; + break; + case invokeinterface : // 0x8e, //args1,2index,1method + uchar args; + ushort index; + uchar method; + break; + case ilookupswitch : // 0x76, //table + ushort default_offset; + ushort pairs; + local ushort index = 0; + if(pairs > 0) { + while(index < pairs) { + struct { + uint match; + ushort offset; + } imo_pairs; + index ++; + } + } + break; + case itableswitch : // 0x74, //2default, 4 low, 4 high, 1 offset + ushort default_offset; + uint low; + uint high; + if((high - low) > 0) + ushort offsets[high - low]; + break; + case slookupswitch : // 0x75, 2 deafult, 2 pair, 1 byte + ushort default_offset; + ushort pairs; + local ushort index = 0; + if(pairs > 0) { + while(index < pairs) { + struct { + ushort match; + ushort offset; + } imo_pairs; + index ++; + } + } + break; + case stableswitch : // 0x73, 2 deafult, 2 low, 2 high, 1 offset + ushort default_offset; + ushort low; + ushort high; + if((high - low) > 0) + ushort offsets[high - low]; + break; + default: break; + } +} JAVA_OPCODE ; + +local uint64 start_bytecode = 0; +string ReadJavaOpcode(JAVA_OPCODE &code) { + + return EnumToString(code.opcode); +} + +typedef struct { + uchar tag; + ushort size; + local uint64 start_index = FTell(); + local uint64 handler_size = FTell() - start_index; + //uchar methods[size - handler_size]; + local uint64 start_method = FTell(); + start_bytecode = start_method; + uchar handler_count; + if(handler_count > 0) + EXCEPTION_HANDLER_INFO exception_handlers[handler_count] ; + //METHOD_INFO + //IntToBinaryStr(queue_peek_method()); + + //Printf("Tail : %Lu\n", tail_index); + while(head_index != tail_index) { + FSeek(start_method + method_offsets[head_index]); + struct { + if((ReadByte( FTell() ) & 0x80)) { + EXTENDED_METHOD_HEADER_INFO method_header; + } else { + METHOD_HEADER_INFO method_header; + } + start_index = FTell(); + local uint16 codesize = method_codesize[head_index]; + //uchar bytecode[codesize]; + if(codesize != 0) { + struct { + while(FTell() < (start_index + codesize)) { + JAVA_OPCODE code; + } + } bytecodes; + } + } methods; + head_index ++; + //queue_pop_method(); + } + FSeek(start_index + size); +} METHOD_COMPONENT; + +typedef struct { + uchar tag; + uchar info[3]; +} CP_INFO; + +typedef struct { + uchar tag; + ushort size; + ushort count; + CP_INFO constant_pool[count]; +} CONSTANT_POOL_COMPONENT; + +typedef struct { + uchar token; //must be 0xFF + uchar access_flags; + if(access_flags & 0x08) { //static field + STATIC_FIELD_REF field_ref; + } else { + INSTANCE_FIELD_REF field_ref; //instance field; + } + union { + ushort primitive_type; + ushort reference_type; + } type; +} FIELD_DESCRIPTOR_INFO; + +typedef struct { + uchar token; + uchar access_flags; + ushort method_offset; + ushort type_offset; + ushort bytecode_count; + ushort exception_handler_count; + ushort exception_handler_index; + //printf("%d\n", method_offset); + if(bytecode_count > 0) { + method_offsets[tail_index] = method_offset; + method_codesize[tail_index] = bytecode_count; + tail_index ++; + } +} METHOD_DESCRIPTOR_INFO; + +typedef struct { + uchar token; + uchar access_flags; + CLASS_REF this_class_ref; + uchar interface_count; + ushort field_count; + ushort method_count; + if(interface_count > 0) + CLASS_REF interfaces[interface_count] ; + if(field_count > 0) + FIELD_DESCRIPTOR_INFO fields[field_count] ; + if(method_count > 0) { + METHOD_DESCRIPTOR_INFO methods[method_count] ; + } +} CLASS_DESCRIPTOR_INFO; + +typedef struct { + uchar tag; + ushort size; + local uint64 start_index = FTell(); + uchar class_count; + if(class_count > 0) + CLASS_DESCRIPTOR_INFO classes[class_count] ; + + local uint64 desc_start_index = FTell(); + struct { + ushort constant_pool_count; + if(constant_pool_count > 0) + ushort constant_pool_types[constant_pool_count]; + while(FTell() < (start_index+size)) { + TYPE_DESCRIPTOR type_desc; + //uchar bytes[size - (desc_start_index - start_index)]; + } + } types; + // +} DESCRIPTOR_COMPONENT; + +typedef struct { + ushort length; + if(length > 0) + uchar bytes[length]; +} UTF8_INFO; + +typedef struct { + ushort name_index; + ushort descriptor_index; + ushort access_flags; + uint contents; +} FIELD_DEBUG_INFO; + +typedef struct { + uchar index; + ushort name_index; + ushort descriptor_index; + ushort start_pc; + ushort length; +} VARIABLE_INFO; + +typedef struct { + ushort start_pc; + ushort end_pc; + ushort source_line; +} LINE_INFO; + +typedef struct { + ushort name_index; + ushort descriptor_index; + ushort access_flags; + ushort location; + uchar header_size; + ushort body_size; + ushort variable_count; + ushort line_count; + if(variable_count > 0) + VARIABLE_INFO variable_table[variable_count] ; + if(line_count > 0) + LINE_INFO line_table[line_count] ; +} METHOD_DEBUG_INFO; + +typedef struct { + ushort name_index; + ushort access_flags; + ushort location; + ushort superclass_name_index; + ushort source_file_index; + uchar interface_count; + ushort field_count; + ushort method_count; + if(interface_count > 0) + ushort interface_names_indexes[interface_count] ; + if(field_count > 0) + FIELD_DEBUG_INFO fields[field_count] ; + if(method_count > 0) + METHOD_DEBUG_INFO methods[method_count] ; +} CLASS_DEBUG_INFO; + +typedef struct { + uchar tag; + ushort size; + ushort string_count; + UTF8_INFO strings_table[string_count] ; + ushort package_name_index; + ushort class_count; + CLASS_DEBUG_INFO classes[class_count] ; +} DEBUG_COMPONENT; + +// Defines a file record +local uint64 method_comp_offset = 0; +local uchar descriptor_comp_decoded = false; +local uchar method_comp_decoded = false; +local uint64 current_file_rec_offset = 0; +local uint64 next_file_rec_offset = 0; +typedef struct { + char signature[4]; //0x04034b50 + ushort version; + ushort flags; + COMPTYPE mode; + if(mode != COMP_STORED) return "Not a valid CAP file"; + DOSTIME filetime; + DOSDATE filedate; + uint crc ; + uint comp_size; + uint uncomp_size; + ushort filename_length; + ushort extrafield_length; + if( filename_length > 0 ) + char filename[ filename_length ]; + if( extrafield_length > 0 ) + uchar extrafield[ extrafield_length ]; +} CAPFILEHEADER; + +typedef struct { + // Header for the file + CAPFILEHEADER header; + + // Compressed data + SetBackColor( cNone ); + //if( frCompressedSize > 0 ) + //uchar frData[ frCompressedSize ]; + BigEndian(); + if(Stricmp( FileNameGetBase( header.filename ), "header.cap" ) == 0) { + HEADER_COMPONENT header_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "directory.cap" ) == 0) { + DIRECTORY_COMPONENT directory_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "applet.cap" ) == 0) { + APPLET_COMPONENT applet_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "class.cap" ) == 0) { + CLASS_COMPONENT class_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "import.cap" ) == 0) { + IMPORT_COMPONENT import_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "constantpool.cap" ) == 0) { + CONSTANT_POOL_COMPONENT constantpool_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "method.cap" ) == 0) { + METHOD_COMPONENT method_component; + method_comp_decoded = true; + } else if(Stricmp( FileNameGetBase( header.filename ), "staticfield.cap" ) == 0) { + STATICFIELD_COMPONENT staticfield_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "reflocation.cap" ) == 0) { + REFERENCELOC_COMPONENT refloc_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "export.cap" ) == 0) { + EXPORT_COMPONENT export_component; + } else if(Stricmp( FileNameGetBase( header.filename ), "descriptor.cap" ) == 0) { + //uchar frData[ frCompressedSize ]; + DESCRIPTOR_COMPONENT descriptor_component; + descriptor_comp_decoded = true; + //local uint64 next_offset + //if( + } else if(Stricmp( FileNameGetBase( header.filename ), "debug.cap" ) == 0) { + DEBUG_COMPONENT debug_component; + } + LittleEndian(); +} CAPFILERECORD ; + +int SizeCAPFILERECORD( CAPFILERECORD &r ) +{ + return 30 + // base size of the struct + ReadUInt(startof(r)+18) + // size of the compressed data + ReadUShort(startof(r)+26) + // size of the file name + ReadUShort(startof(r)+28); // size of the extra field +}; + +// Defines an entry in the directory table +typedef struct { + char signature[4]; //0x02014b50 + ushort version_src; + ushort version_trgt; + ushort flags; + COMPTYPE mode; + DOSTIME filetime; + DOSDATE filedate; + uint crc ; + uint comp_size; + uint uncomp_size; + ushort filename_length; + ushort extrafield_length; + ushort comment_length; + ushort disknum_start; + ushort internal_attr; + uint external_attr; + uint offset_hdr; + if( filename_length > 0 ) + char filename[ filename_length ]; + if( extrafield_length > 0 ) + uchar extrafield[ extrafield_length ]; + if( comment_length > 0 ) + uchar comment[ comment_length ]; +} CAPDIRENTRY ; + +// Defines the digital signature +typedef struct { + char signature[4]; //0x05054b50 + ushort data_length; + if( data_length > 0 ) + uchar data[ data_length ]; +} CAPDIGITALSIG; + +// Defintes the Data descriptor +typedef struct { + char signature[4]; //0x08074b50 + uint crc ; + uint comp_size; + uint uncomp_size; +} CAPDATADESCR; + +// Defines the end of central directory locator +typedef struct { + char signature[4]; //0x06054b50 + ushort disknum; + ushort disknum_start; + ushort disk_entries; + ushort directory_entries; + uint directory_size; + uint directory_offset; + ushort comment_length; + if( comment_length > 0 ) + char comment[ comment_length ]; +} CAPENDLOCATOR; + +//-------------------------------------------- + +string ReadCAPFILERECORD( CAPFILERECORD &file ) +{ + if( exists( file.header.filename ) ) + { + if(Stricmp( FileNameGetBase( file.header.filename ), "header.cap" ) == 0) { + return "Header"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "directory.cap" ) == 0) { + return "Directory"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "applet.cap" ) == 0) { + return "Applet"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "class.cap" ) == 0) { + return "Class"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "import.cap" ) == 0) { + return "Import"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "constantpool.cap" ) == 0) { + return "ConstantPool"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "method.cap" ) == 0) { + return "Method"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "staticfield.cap" ) == 0) { + return "StaticField"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "reflocation.cap" ) == 0) { + return "ReferenceLocation"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "export.cap" ) == 0) { + return "Export"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "descriptor.cap" ) == 0) { + return "Descriptor"; + } else if(Stricmp( FileNameGetBase( file.header.filename ), "debug.cap" ) == 0) { + return "Debug"; + } + } + return ""; +} + +string ReadCAPDIRENTRY( CAPDIRENTRY &entry ) +{ + if( exists( entry.filename ) ) + { + if(Stricmp( FileNameGetBase( entry.filename ), "header.cap" ) == 0) { + return "Header Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "directory.cap" ) == 0) { + return "Directory Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "applet.cap" ) == 0) { + return "Applet Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "class.cap" ) == 0) { + return "Class Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "import.cap" ) == 0) { + return "Import Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "constantpool.cap" ) == 0) { + return "ConstantPool Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "method.cap" ) == 0) { + return "Method Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "staticfield.cap" ) == 0) { + return "StaticField Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "reflocation.cap" ) == 0) { + return "ReferenceLocation Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "export.cap" ) == 0) { + return "Export Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "descriptor.cap" ) == 0) { + return "Descriptor Entry"; + } else if(Stricmp( FileNameGetBase( entry.filename ), "debug.cap" ) == 0) { + return "Debug Entry"; + } + } + return "Unknown Entry"; +} + +void WriteCAPFILERECORD( CAPFILERECORD &file, string s ) +{ + local int len = Strlen( s ); + if( exists( file.frFileName ) ) + { + Strncpy( file.frFileName, s, file.frFileNameLength ); + if( len < file.frFileNameLength ) + file.frFileName[len] = 0; //null terminate + } +} + +//-------------------------------------------- + +local uint tag; +local ushort filename_len = 0; +local char filename[]; +LittleEndian(); +while( !FEof() ) +{ + // Read a tag + tag = ReadUInt( FTell() ); + + if( tag == 0x04034b50 ) + { + SetBackColor( cLtGray ); + current_file_rec_offset = FTell(); + filename_len = ReadUShort(FTell() + 26); // size of the file name + filename = ReadString( FTell() + 0x1E, filename_len ); + //return filename; + if(Stricmp( FileNameGetBase( filename ), "header.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "directory.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "applet.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "class.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "import.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "constantpool.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "method.cap" ) == 0) { + //uchar frData[ frCompressedSize ]; + method_comp_offset = current_file_rec_offset; + if(descriptor_comp_decoded == true) { + CAPFILERECORD record; + } else { + method_comp_decoded = false; + local uint64 pk_header_size = 30 + ReadUInt(FTell()+18) + ReadUShort(FTell()+26) + ReadUShort(FTell()+28); // size of the extra field + //local uint64 next_offset = ReadUShort(FTell() + pk_header_size); + //return next_offset; + //return FTell() + pk_header_size; + FSeek(FTell() + pk_header_size); + } + } else if(Stricmp( FileNameGetBase( filename ), "staticfield.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "reflocation.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "export.cap" ) == 0) { + CAPFILERECORD record; + } else if(Stricmp( FileNameGetBase( filename ), "descriptor.cap" ) == 0) { + head_index = 0; + tail_index = 0; + CAPFILERECORD record; + next_file_rec_offset = FTell(); + if(method_comp_decoded == false) { + FSeek(method_comp_offset); + CAPFILERECORD record; + FSeek(next_file_rec_offset); + } + } else if(Stricmp( FileNameGetBase( filename ), "debug.cap" ) == 0) { + CAPFILERECORD record; + } else { + CAPFILERECORD record; + } + } + else if( tag == 0x08074b50 ) + { + SetBackColor( cLtGreen ); + CAPDATADESCR dataDescr; + } + else if( tag == 0x02014b50 ) + { + SetBackColor( cLtPurple ); + CAPDIRENTRY dirEntry; + } + else if( tag == 0x05054b50 ) + { + SetBackColor( cLtBlue ); + CAPDIGITALSIG digitalSig; + } + else if( tag == 0x06054b50 ) + { + SetBackColor( cLtYellow ); + CAPENDLOCATOR endLocator; + } + else + { + Warning( "Unknown CAP tag encountered. Template stopped." ); + return -1; + } +} \ No newline at end of file diff --git a/cparser/CDATemplate.bt b/cparser/CDATemplate.bt new file mode 100644 index 0000000..7b82219 --- /dev/null +++ b/cparser/CDATemplate.bt @@ -0,0 +1,31 @@ +//------------------------------------ +//--- 010 Editor v1.0 Binary Template +// +// Name: CDATemplate.bt +// Author: Szabolcs Dávid +// Purpose: CDA template for Audio CD +// header Information +//------------------------------------ +typedef struct +{ + char szHeader[8]; + char szFormat[8]; + DWORD dwEOLn; +} CDAFILEHEADER; + +typedef struct +{ + WORD wTrackFirst; + WORD wTrackCount; + DWORD dwVolumeSerialNumber; + DWORD dwStartFrame; + DWORD dwLengthFrame; + DWORD dwStartMS; + DWORD dwLengthMS; +} CDAINFORMATION; + +LittleEndian(); +CDAFILEHEADER Header; +CDAINFORMATION Information; + + diff --git a/cparser/CLASSTemplate.bt b/cparser/CLASSTemplate.bt new file mode 100644 index 0000000..5c29926 --- /dev/null +++ b/cparser/CLASSTemplate.bt @@ -0,0 +1,253 @@ +//------------------------------------------------------------------------- +//--- 010 Editor v2.1 Binary Template +// +// File: CLASSTemplate.bt +// Author: Kevin O. Grover +// Purpose: A template for parsing Java Class (JVM) Files +// Version: 1.1 2014-08-13 +// History: +// 2007-02-26 kog Original Version +// 2014-08-13 kog Updated for Java 7/8 Version number (and future) +// +// This template was written to the "The Java Virtual Machine +// Specification", Second Edition, by Tim Lindholm, Frank Yellin. +// It was later updated to include the provisio in that spec (and future +// specs). +// +// The details used to write this Template came mainly from Chapter 4: +// "The class File Format". +// +// You can get the document from the Oracle Java Pages or Wikipedia: +// http://docs.oracle.com/javase/specs/ +// http://docs.oracle.com/javase/specs/jvms/se7/jvms7.pdf +// http://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf +// http://en.wikipedia.org/wiki/Class_file +//------------------------------------------------------------------------- + +BigEndian(); + +// Types used in the JVM Spec. +// (To make this code as close to the text in the spec as possible.) +typedef uint32 u4; +typedef uint16 u2; +typedef ubyte u1; + +typedef enum eACCESS_FLAGS { + ACC_PUBLIC = 0x0001, // Declared public; may be accessed from outside its package. + ACC_PRIVATE = 0x0002, // Declared private; usable only within the defining class. + ACC_PROTECTED = 0x0004, // Declared protected; may be accessed within subclasses. + ACC_STATIC = 0x0008, // Declared static. + ACC_FINAL = 0x0010, // Declared final; no subclasses allowed. + ACC_SUPER = 0x0020, // Treat superclass methods specially when invoked by the invokespecial instruction. + ACC_VOLATILE = 0x0040, // Declared volatile; cannot be cached. + ACC_TRANSIENT = 0x0080, // Declared transient; not written or read by a persistent object manager. + ACC_NATIVE = 0x0100, // Declared native; implemented in a language other than Java. + ACC_INTERFACE = 0x0200, // Is an interface, not a class. + ACC_ABSTRACT = 0x0400, // Declared abstract; may not be instantiated. + ACC_STRICT = 0x0800 // Declared strictfp; floating-point mode is FP-strict +} AF ; + +string read_AF (local AF &af) { + local string s = ""; + local int commaNeeded = 0; + local AF i = 1; + + SPrintf (s, "%d: ", af); + + // Iterate over all possible values the flags + // if the given bit is set, add it's text representation to the + // return string. + // NOTE: There's probably a better way to do this. (More portable?) + while (i < ACC_STRICT) { + if (af && i) { + if (commaNeeded) { + s += ", "; + } + s += EnumToString(i); + commaNeeded = 1; + } + i = i << 1; + } + return s; +} + +// Constants for cp_info.tag ... +typedef enum eCP_CONST { + CONSTANT_Utf8 = 1, + CONSTANT_Integer = 3, + CONSTANT_Float = 4, + CONSTANT_Long = 5, + CONSTANT_Double = 6, + CONSTANT_Class = 7, + CONSTANT_String = 8, + CONSTANT_Fieldref = 9, + CONSTANT_Methodref = 10, + CONSTANT_InterfaceMethodref = 11, + CONSTANT_NameAndType = 12, +} CP_CONST; + +// Constant Pool Table Structure +// NOTE: These are NOT constant sized items. Although referenced +// like an array in the main structure, you can not use position +// to directly infer a byte offset because you do not know the +// sizes of the items preceeding it. +typedef struct { + CP_CONST tag; + switch(tag) + { + case CONSTANT_Class: + u2 name_index; + break; + case CONSTANT_Methodref: + case CONSTANT_Fieldref: + case CONSTANT_InterfaceMethodref: + u2 class_index; + u2 name_and_type_index; + break; + case CONSTANT_Utf8: + u2 length; + char bytes[length]; + break; + case CONSTANT_Integer: + case CONSTANT_Float: + u4 bytes; + break; + case CONSTANT_Long: + case CONSTANT_Double: + u4 high_bytes; + u4 low_bytes; + break; + case CONSTANT_String: + u2 string_index; + break; + case CONSTANT_NameAndType: + u2 name_index; + u2 descriptor_index; + break; + default: + local string s; + SPrintf(s, "Unknown 'constant_pool' tag: %d", tag); + Warning(s); + return -3; + } +} cp_info ; + +/** + * Reader for 'cp_info' + * @param cp_info Constant Pool info structure + */ +string read_cp_info (local cp_info &i) +{ + local string s = ""; + s = EnumToString(i.tag); + if (i.tag == CONSTANT_Utf8) { + s += ": " + i.bytes; + } + return s; +} + +typedef struct { + u2 attribute_name_index; + u4 attribute_length; + u1 info[attribute_length]; +} attribute_info ; + +typedef struct { + AF access_flags; + u2 name_index; + u2 descriptor_index; + u2 attributes_count; + attribute_info attributes[attributes_count]; +} field_info ; + +typedef struct { + AF access_flags; + u2 name_index; + u2 descriptor_index; + u2 attributes_count; + attribute_info attributes[attributes_count]; +} method_info ; + +// MAIN Structure + +typedef struct { + u4 magic ; + if (magic != 0xCAFEBABE) { // Check that 'magic' is correct + Warning("Incorrect Magic Number. This is not a JVM Class. Template Terminated."); + return -1; + } + u2 minor_version; + u2 major_version; + u2 constant_pool_count; + cp_info constant_pool[constant_pool_count-1]; + AF access_flags; + u2 this_class; // Reference into constant_pool table + if (this_class < 1 || this_class > constant_pool_count-1) { + local string s; + SPrintf(s,"Bad 'this_class' reference (%d). It should be in the range [1..%d]", this_class, constant_pool_count-1); + Warning(s); + return -2; + } + u2 super_class; // Reference into constant_pool table + if (super_class < 1 || super_class > constant_pool_count-1) { + local string s; + SPrintf(s,"Bad 'super_class' reference (%d). It should be in the range [1..%d]", super_class, constant_pool_count-1); + Warning(s); + return -2; + } + u2 interfaces_count; + u2 interfaces[interfaces_count]; + u2 fields_count; + field_info fields[fields_count]; + u2 methods_count; + method_info methods[methods_count]; + u2 attributes_count; + attribute_info attributes[attributes_count]; +} JVMClass ; + +/** + * Reader for 'JVMClass' + * Returns the JVM Version: major.minor and the Java version (if it can + * calculate it from the JVM Version. + * @param j JVMClass The JVM Class Structure + * @return string The version information + */ +string read_JVMClass (local JVMClass &j) +{ + // JVM Version (as stored in the class file) + local string s; + SPrintf (s, "JVM class v%d.%d", j.major_version, j.minor_version); + + // Java Runtime Version. From the JVM Spec for class files + local int major = 1; + local int minor = 0; + + if (j.major_version == 45) { + if (j.minor_version >= 3) minor = 1; + } else { + if (j.major_version >= 46) { + minor = j.major_version - 44; + } else { + // Unknown: it's either newer or older than expected + major = 0; + minor = 0; + Warning("Unexpected JVM major version number."); + } + } + + if (major || minor) { + local string jre_v; + SPrintf(jre_v, " (Java %d.%d)", major, minor); + s += jre_v; + } else { + s += " (Unknown Java Version)"; + } + + return s; +} + +// ***************************************** +// MAIN - Allocate data here... +// ***************************************** + +struct JVMClass jc; diff --git a/cparser/CLASSTemplate2.bt b/cparser/CLASSTemplate2.bt new file mode 100644 index 0000000..8cf9446 --- /dev/null +++ b/cparser/CLASSTemplate2.bt @@ -0,0 +1,121 @@ +BigEndian(); + +typedef struct { + enum { + CONSTANT_Class = 7, + CONSTANT_Fieldref = 9, + CONSTANT_Methodref = 10, + CONSTANT_InterfaceMethodref = 11, + CONSTANT_String = 8, + CONSTANT_Integer = 3, + CONSTANT_Float = 4, + CONSTANT_Long = 5, + CONSTANT_Double = 6, + CONSTANT_NameAndType = 12, + CONSTANT_Utf8 = 1 + } tag; + switch (tag) { + case 7: + uint16 name_index; + break; + case 9: + uint16 class_index; + uint16 name_and_type_index; + break; + case 10: + uint16 class_index; + uint16 name_and_type_index; + break; + case 11: + uint16 class_index; + uint16 name_and_type_index; + break; + case 8: + uint16 string_index; + break; + case 3: + int32 int_value; + break; + case 4: + float float_value; + break; + case 5: + int64 long_value; + break; + case 6: + double double_value; + break; + case 12: + uint16 name_index; + uint16 descriptor_index; + break; + case 1: + uint16 length; + char utf8_value[length]; + break; + } +} cp_info; + +typedef struct { + uint16 attribute_name_index; + uint32 attribute_length; + char info[attribute_length]; +} attribute_info; + +typedef struct { + uint16 access_flags ; + uint16 name_index; + uint16 descriptor_index; + uint16 attributes_count; + local int i_att2 = 0; + for ( i_att2 = 0; i_att2 < attributes_count; i_att2++) { + attribute_info attributes; + }; +} field_info, method_info; + +typedef struct { + uint32 magic ; + if (magic != 0xCAFEBABE) { + Warning ("Invalid Class File."); + return -1; + } + uint16 minor_version; + uint16 major_version; + uint16 constant_pool_count; + local int i_cp = 0; + for ( i_cp = 1; i_cp < constant_pool_count; i_cp++) { + cp_info constant_pool; + if ( constant_pool.tag == 5 || constant_pool.tag == 6 ){ + i_cp++; + } + }; + uint16 access_flags ; + uint16 this_class; + uint16 super_class; + uint16 interfaces_count; + local int i_if = 0; + for ( i_if = 0; i_if < interfaces_count; i_if++) { + uint16 interfaces; + }; + uint16 fields_count; + local int i_fld = 0; + for ( i_fld = 0; i_fld < fields_count; i_fld++) { + field_info fields; + }; + uint16 methods_count; + local int i_m = 0; + for ( i_m = 0; i_m < methods_count; i_m++) { + method_info methods; + }; + uint16 attributes_count; + local int i_att = 0; + for ( i_att = 0; i_att < attributes_count; i_att++) { + attribute_info attributes; + }; +} class_file; + +class_file file; + +if (!FEof()) { + Warning("File is not properly ended."); +}; diff --git a/cparser/CLASSTemplate3.bt b/cparser/CLASSTemplate3.bt new file mode 100644 index 0000000..0247358 --- /dev/null +++ b/cparser/CLASSTemplate3.bt @@ -0,0 +1,1477 @@ +//-------------------------------------- +//--- 010 Editor v5.0 Binary Template +// Author: Pishchik Ilya L. (RUS) +// Purpose: A template for parsing Java Class (JVM) Files full +// +// You can get the document from the Java +// Pages http://docs.oracle.com/javase/specs/jvms/se7/html/ +//-------------------------------------- + +BigEndian(); + +typedef ubyte u1; +typedef uint16 u2; +typedef uint32 u4; +typedef uint64 u8; +typedef byte i1; +typedef int16 i2; +typedef int32 i4; + +enum Constant_pool +{ + CONSTANT_Class=7, + CONSTANT_Fieldref=9, + CONSTANT_Methodref=10, + CONSTANT_InterfaceMethodref=11, + CONSTANT_String=8, + CONSTANT_Integer=3, + CONSTANT_Float=4, + CONSTANT_Long=5, + CONSTANT_Double=6, + CONSTANT_NameAndType=12, + CONSTANT_Utf8=1, + CONSTANT_MethodHandle=15, + CONSTANT_MethodType=16, + CONSTANT_InvokeDynamic=18 +}; + +enum access_property_flags +{ + ACC_PUBLIC=0x0001, + ACC_PRIVATE=0x0002, + ACC_PROTECTED=0x0004, + ACC_STATIC=0x0008, + ACC_FINAL=0x0010, + ACC_SUPER_ACC_SYNCHRONIZED=0x0020, + ACC_BRIDGE_ACC_VOLATILE=0x0040, + ACC_VARARGS_ACC_TRANSIENT=0x0080, + ACC_NATIVE=0x0100, + ACC_INTERFACE=0x0200, + ACC_ABSTRACT=0x0400, + ACC_STRICT=0x0800, + ACC_SYNTHETIC=0x1000, + ACC_ANNOTATION=0x2000, + ACC_ENUM=0x4000 +}; + +enum enum_type +{ + Class, + Method, + Field, + Nested_Class +}; + + +enum enum_opcodes +{ +nop=0x00, +aconst_null=0x01, +iconst_m1=0x02, +iconst_0=0x03, +iconst_1=0x04, +iconst_2=0x05, +iconst_3=0x06, +iconst_4=0x07, +iconst_5=0x08, +lconst_0=0x09, +lconst_1=0x0a, +fconst_0=0x0b, +fconst_1=0x0c, +fconst_2=0x0d, +dconst_0=0x0e, +dconst_1=0x0f, +bipush=0x10, +sipush=0x11, +ldc=0x12, +ldc_w=0x13, +ldc2_w=0x14, +iload=0x15, +lload=0x16, +fload=0x17, +dload=0x18, +aload=0x19, +iload_0=0x1a, +iload_1=0x1b, +iload_2=0x1c, +iload_3=0x1d, +lload_0=0x1e, +lload_1=0x1f, +lload_2=0x20, +lload_3=0x21, +fload_0=0x22, +fload_1=0x23, +fload_2=0x24, +fload_3=0x25, +dload_0=0x26, +dload_1=0x27, +dload_2=0x28, +dload_3=0x29, +aload_0=0x2a, +aload_1=0x2b, +aload_2=0x2c, +aload_3=0x2d, +iaload=0x2e, +laload=0x2f, +faload=0x30, +daload=0x31, +aaload=0x32, +baload=0x33, +caload=0x34, +saload=0x35, +istore=0x36, +lstore=0x37, +fstore=0x38, +dstore=0x39, +astore=0x3a, +istore_0=0x3b, +istore_1=0x3c, +istore_2=0x3d, +istore_3=0x3e, +lstore_0=0x3f, +lstore_1=0x40, +lstore_2=0x41, +lstore_3=0x42, +fstore_0=0x43, +fstore_1=0x44, +fstore_2=0x45, +fstore_3=0x46, +dstore_0=0x47, +dstore_1=0x48, +dstore_2=0x49, +dstore_3=0x4a, +astore_0=0x4b, +astore_1=0x4c, +astore_2=0x4d, +astore_3=0x4e, +iastore=0x4f, +lastore=0x50, +fastore=0x51, +dastore=0x52, +aastore=0x53, +bastore=0x54, +castore=0x55, +sastore=0x56, +pop=0x57, +pop2=0x58, +dup=0x59, +dup_x1=0x5a, +dup_x2=0x5b, +dup2=0x5c, +dup2_x1=0x5d, +dup2_x2=0x5e, +swap=0x5f, +iadd=0x60, +ladd=0x61, +fadd=0x62, +dadd=0x63, +isub=0x64, +lsub=0x65, +fsub=0x66, +dsub=0x67, +imul=0x68, +lmul=0x69, +fmul=0x6a, +dmul=0x6b, +idiv=0x6c, +ldiv=0x6d, +fdiv=0x6e, +ddiv=0x6f, +irem=0x70, +lrem=0x71, +frem=0x72, +drem=0x73, +ineg=0x74, +lneg=0x75, +fneg=0x76, +dneg=0x77, +ishl=0x78, +lshl=0x79, +ishr=0x7a, +lshr=0x7b, +iushr=0x7c, +lushr=0x7d, +iand=0x7e, +land=0x7f, +ior=0x80, +lor=0x81, +ixor=0x82, +lxor=0x83, +iinc=0x84, +i2l=0x85, +i2f=0x86, +i2d=0x87, +l2i=0x88, +l2f=0x89, +l2d=0x8a, +f2i=0x8b, +f2l=0x8c, +f2d=0x8d, +d2i=0x8e, +d2l=0x8f, +d2f=0x90, +i2b=0x91, +i2c=0x92, +i2s=0x93, +lcmp=0x94, +fcmpl=0x95, +fcmpg=0x96, +dcmpl=0x97, +dcmpg=0x98, +ifeq=0x99, +ifne=0x9a, +iflt=0x9b, +ifge=0x9c, +ifgt=0x9d, +ifle=0x9e, +if_icmpeq=0x9f, +if_icmpne=0xa0, +if_icmplt=0xa1, +if_icmpge=0xa2, +if_icmpgt=0xa3, +if_icmple=0xa4, +if_acmpeq=0xa5, +if_acmpne=0xa6, +goto=0xa7, +jsr=0xa8, +ret=0xa9, +tableswitch=0xaa, +lookupswitch=0xab, +ireturn=0xac, +lreturn=0xad, +freturn=0xae, +dreturn=0xaf, +areturn=0xb0, +Return=0xb1, +getstatic=0xb2, +putstatic=0xb3, +getfield=0xb4, +putfield=0xb5, +invokevirtual=0xb6, +invokespecial=0xb7, +invokestatic=0xb8, +invokeinterface=0xb9, +invokedynamic=0xba, +new=0xbb, +newarray=0xbc, +anewarray=0xbd, +arraylength=0xbe, +athrow=0xbf, +checkcast=0xc0, +instanceof=0xc1, +monitorenter=0xc2, +monitorexit=0xc3, +wide=0xc4, +multianewarray=0xc5, +ifnull=0xc6, +ifnonnull=0xc7, +goto_w=0xc8, +jsr_w=0xc9, +breakpoint=0xca, +impdep1=0xfe, +impdep2=0xff +}; + +enum enum_array_type +{ + no_body=0, + index_body=1, + index_const_body=2, + sipush_body=3, + bipush_body=4, + newarray_body=5, + indexbyte_1_2_body=6, + branchbyte1_2_body=7, + branchbyte1_4_body=8, + invokeinterface_body=9, + invokedynamic_body=10, + multianewarray_body=11, + wide_body=12, + tableswitch_body=13, + lookupswitch_body=14, + index_v2_body=15 +}; + + +enum enum_opcodes_body_type +{ + T_BOOLEAN=4, + T_CHAR=5, + T_FLOAT=6, + T_DOUBLE=7, + T_BYTE=8, + T_SHORT=9, + T_INT=10, + T_LONG=11 +}; + + +const u4 address_constant_pool=0xA; +const u4 address_constant_pool_count=0x8; +const u2 constant_pool_count=ReadUShort(address_constant_pool_count)-1; + +local u8 map_address_constant_pool[constant_pool_count]; +local u1 array_opcodes_body_type[256]; + + +array_opcodes_body_type[tableswitch]=tableswitch_body;//170 +array_opcodes_body_type[lookupswitch]=lookupswitch_body;//171 + + +array_opcodes_body_type[bipush]=bipush_body; //16 +byte + +array_opcodes_body_type[iload]=index_body; //21 +index +array_opcodes_body_type[lload]=index_body; //22 +index +array_opcodes_body_type[fload]=index_body; //23 +index +array_opcodes_body_type[dload]=index_body; //24 +index +array_opcodes_body_type[aload]=index_body; //25 +index + +array_opcodes_body_type[istore]=index_body; //54 +index +array_opcodes_body_type[lstore]=index_body; //55 +index +array_opcodes_body_type[fstore]=index_body; //56 +index +array_opcodes_body_type[dstore]=index_body; //57 +index +array_opcodes_body_type[astore]=index_body; //58 +index + +array_opcodes_body_type[sipush]=sipush_body; //17 +byte1,byte2 +array_opcodes_body_type[ldc]=index_v2_body; //18 +index +array_opcodes_body_type[ldc_w]=indexbyte_1_2_body; //19 +indexbyte1,indexbyte2 +array_opcodes_body_type[ldc2_w]=indexbyte_1_2_body;//20 +indexbyte1,indexbyte2 + +array_opcodes_body_type[iinc]=index_const_body; //132 +index,const + +array_opcodes_body_type[ifeq]=branchbyte1_2_body; //153 +branchbyte1,branchbyte2 +array_opcodes_body_type[ifne]=branchbyte1_2_body; //154 +branchbyte1,branchbyte2 +array_opcodes_body_type[iflt]=branchbyte1_2_body; //155 +branchbyte1,branchbyte2 +array_opcodes_body_type[ifge]=branchbyte1_2_body; //156 +branchbyte1,branchbyte2 +array_opcodes_body_type[ifgt]=branchbyte1_2_body; //157 +branchbyte1,branchbyte2 +array_opcodes_body_type[ifle]=branchbyte1_2_body; //158 +branchbyte1,branchbyte2 + +array_opcodes_body_type[if_icmpeq]=branchbyte1_2_body; //159 +branchbyte1,branchbyte2 +array_opcodes_body_type[if_icmpne]=branchbyte1_2_body; //160 +branchbyte1,branchbyte2 +array_opcodes_body_type[if_icmplt]=branchbyte1_2_body; //161 +branchbyte1,branchbyte2 +array_opcodes_body_type[if_icmpge]=branchbyte1_2_body; //162 +branchbyte1,branchbyte2 +array_opcodes_body_type[if_icmpgt]=branchbyte1_2_body; //163 +branchbyte1,branchbyte2 +array_opcodes_body_type[if_icmple]=branchbyte1_2_body; //164 +branchbyte1,branchbyte2 + +array_opcodes_body_type[if_acmpeq]=branchbyte1_2_body; //165 +branchbyte1,branchbyte2 +array_opcodes_body_type[if_acmpne]=branchbyte1_2_body; //166 +branchbyte1,branchbyte2 + +array_opcodes_body_type[goto]=branchbyte1_2_body; //167 +branchbyte1,branchbyte2 +array_opcodes_body_type[jsr]=branchbyte1_2_body; //168 +branchbyte1,branchbyte2 + +array_opcodes_body_type[ret]=index_body;//169 +index + +array_opcodes_body_type[getstatic]=indexbyte_1_2_body; //178 +indexbyte1,indexbyte2 +array_opcodes_body_type[putstatic]=indexbyte_1_2_body; //179 +indexbyte1,indexbyte2 + +array_opcodes_body_type[getfield]=indexbyte_1_2_body; //180 +indexbyte1,indexbyte2 +array_opcodes_body_type[putfield]=indexbyte_1_2_body; //181 +indexbyte1,indexbyte2 + +array_opcodes_body_type[new]=indexbyte_1_2_body; //187 +indexbyte1,indexbyte2 +array_opcodes_body_type[newarray]=newarray_body; //188 +atype + +array_opcodes_body_type[invokevirtual]=indexbyte_1_2_body; //182 +indexbyte1,indexbyte2 +array_opcodes_body_type[invokespecial]=indexbyte_1_2_body; //183 +indexbyte1,indexbyte2 +array_opcodes_body_type[invokestatic]=indexbyte_1_2_body; //184 +indexbyte1,indexbyte2 + +array_opcodes_body_type[anewarray]=indexbyte_1_2_body; //189 +indexbyte1,indexbyte2 +array_opcodes_body_type[checkcast]=indexbyte_1_2_body; //192 +indexbyte1,indexbyte2 +array_opcodes_body_type[instanceof]=indexbyte_1_2_body; //193 +indexbyte1,indexbyte2 + +array_opcodes_body_type[wide]=wide_body; //196 (iload,fload,aload,lload,dload,istore,fstore,astore,lstore,dstore,ret),indexbyte1,indexbyte2 or iinc,indexbyte1,indexbyte2,constbyte1,constbyte2 +array_opcodes_body_type[multianewarray]=multianewarray_body; //197 indexbyte1,indexbyte2,dimensions + +array_opcodes_body_type[ifnull]=branchbyte1_2_body; //198 +branchbyte1,branchbyte2 +array_opcodes_body_type[ifnonnull]=branchbyte1_2_body; //199 +branchbyte1,branchbyte2 + +array_opcodes_body_type[invokeinterface]=invokeinterface_body; //185 +indexbyte1,indexbyte2,count,0 +array_opcodes_body_type[invokedynamic]=invokedynamic_body; //186 +indexbyte1,indexbyte2,0,0 +array_opcodes_body_type[goto_w]=branchbyte1_4_body;//200 +branchbyte1,branchbyte2,branchbyte3,branchbyte4 +array_opcodes_body_type[jsr_w]=branchbyte1_4_body; //201 +branchbyte1,branchbyte2,branchbyte3,branchbyte4 + +/* ++ConstantValue OK ++Code OK ++StackMapTable OK! ++Exceptions OK ++InnerClasses OK ++EnclosingMethod OK ++Synthetic OK ++Signature OK ++SourceFile OK ++SourceDebugExtension ++LineNumberTable OK ++LocalVariableTable OK ++LocalVariableTypeTable ? ++Deprecated OK ++RuntimeVisibleAnnotations OK ++RuntimeInvisibleAnnotations OK ++RuntimeVisibleParameterAnnotations OK ++RuntimeInvisibleParameterAnnotations OK ++AnnotationDefault OK ++BootstrapMethods*/ + +struct element_value; + +typedef struct{ + u2 type_index; + u2 num_element_value_pairs; + if(0; + element_value value; + }element_value_pairs[num_element_value_pairs]; + + + + } +}annotation; + +typedef struct{ + u1 tag; + if(tag=='e') + { + struct{ + u2 type_name_index; + u2 const_name_index; + }enum_const_value; + } + else if(tag=='c') + { + u2 class_info_index; + } + else if(tag=='@') + { + annotation annotation_value; + } + else if(tag=='[') + { + struct{ + u2 num_values; + element_value values[num_values]; + }array_value; + } + else + { + //B,C,D,F,I,J,S Z,or s. + u2 const_value_index; + } +}element_value; + +typedef struct{ + u1 tag; + /*Top_variable_info 0 + Integer_variable_info 1 + Float_variable_info 2 + Double_variable_info 3 + Long_variable_info 4 + Null_variable_info 5 + UninitializedThis_variable_info 6*/ + if(tag==7) + { + //Object_variable_info 7 + u2 cpool_index; + } + else if(tag==8) + { + //Uninitialized_variable_info//Object_variable_info 7 8 + u2 offset; + } +}verification_type_info; + +typedef struct{ + u1 frame_type;//same_frame + if(frame_type>=64&&frame_type<=127) + { + //same_locals_1_stack_item_frame + verification_type_info stack[1]; + } + else if(frame_type==247) + { + //same_locals_1_stack_item_frame_extended + u2 offset_delta; + verification_type_info stack[1]; + } + else if(frame_type>=248&&frame_type<=251) + { + //chop_frame or same_frame_extended + u2 offset_delta; + } + else if(frame_type>=252&&frame_type<=254) + { + //append_frame + u2 offset_delta; + verification_type_info locals[frame_type - 251]; + } + else if(frame_type==255) + { + //full_frame + u2 offset_delta; + u2 number_of_locals; + if(0; + u2 number_of_stack_items; + if(0; + } +}stack_map_frame; + +typedef struct(int hidden,u8 offsets){ + + if(exists(hidden)) + { + u1 operation; + switch(array_opcodes_body_type[operation]) + { + case index_body: + case index_v2_body: + u1 index; + break; + case index_const_body: + u1 index; + i1 _const; + break; + case sipush_body: + u2 _byte; //byte1,byte2; + break; + case bipush_body: + u1 _byte; + break; + case newarray_body: + u1 atype; + break; + case multianewarray_body: + u2 indexbyte; //indexbyte1,indexbyte2; + u1 dimensions; + break; + case wide_body: + u1 operation2; + u2 indexbyte; //indexbyte1,indexbyte2; + if(operation2==iinc) + { + u2 constbyte; //constbyte1,constbyte2; + } + break; + case tableswitch_body: + local u4 len=4-(offsets+1)%4; + if(len<4) u1 byte_pad[len]; + i4 defaultbyte; //defaultbyte1,defaultbyte2,defaultbyte3,defaultbyte4 + i4 lowbyte; //lowbyte1,lowbyte2,lowbyte3,lowbyte4 + i4 highbyte; //highbyte1,highbyte2,highbyte3,highbyte4 + u4 jump[highbyte-lowbyte+1]; + break; + case lookupswitch_body: + local u4 len=4-(offsets+1)%4; + if(len<4)u1 byte_pad[len]; + i4 defaultbyte; //defaultbyte1,defaultbyte2,defaultbyte3,defaultbyte4 + i4 npairs; //npairs1,npairs2,npairs3,npairs4 + struct + { + i4 match; + i4 offset; + }match_offset[npairs]; + break; + case indexbyte_1_2_body: + u2 indexbyte; //indexbyte1,indexbyte2; + break; + case branchbyte1_2_body: + i2 branchbyte; //indexbyte1,indexbyte2; + break; + case branchbyte1_4_body: + i4 branchbyte; //branchbyte1,branchbyte2,branchbyte3,branchbyte4 + break; + case invokeinterface_body: + u2 indexbyte; //indexbyte1,indexbyte2; + u1 _count; + u1 zero; + break; + case invokedynamic_body: + u2 indexbyte; //indexbyte1,indexbyte2; + u1 zero; + u1 zero; + break; + default: + break; + } + } +}opcodes_operation; + + +struct attribute_info; + +typedef struct{ + u2 attribute_name_index; + u4 attribute_length; + + local string attribute_name=get_constant_pool_Utf8(attribute_name_index); + + if(attribute_name=="ConstantValue") + { + u2 constantvalue_index ; + } + else if(attribute_name=="Code") + { + u2 max_stack; + u2 max_locals; + u4 code_length; + //u1 code[code_length]; + struct + { + local u8 begin_address=FTell(); + local u8 current_address=FTell(); + local u8 end_address=begin_address+code_length; + local u4 i; + local u8 Len; + while( FTell() < end_address) + { + opcodes_operation operation(0,current_address-begin_address); + Len=FTell()-current_address-1; + FSkip(-Len); + for(i=0;i; + } + current_address=FTell(); + } + }code; + + u2 exception_table_length; + if(exception_table_length>0) + { + struct + { + u2 start_pc; + u2 end_pc; + u2 handler_pc; + u2 catch_type; + }exception_table[exception_table_length]; + } + u2 attributes_count; + if(attributes_count>0)attribute_info attributes[attributes_count]; + } + else if(attribute_name=="Exceptions") + { + u2 number_of_exceptions; + u2 exception_index_table[number_of_exceptions]; + } + else if(attribute_name=="LineNumberTable") + { + u2 line_number_table_length; + struct{ + u2 start_pc; + u2 line_number; + }line_number_table[line_number_table_length] ; + } + else if(attribute_name=="LocalVariableTable") + { + u2 local_variable_table_length; + struct LocalVariableTable_struct{ + u2 start_pc; + u2 length; + u2 name_index; + u2 descriptor_index; + u2 index; + }local_variable_table[local_variable_table_length] ; + } + else if(attribute_name=="LocalVariableTypeTable") + { + u2 local_variable_type_table_length; + struct{ + u2 start_pc; + u2 length; + u2 name_index; + u2 signature_index; + u2 index; + }local_variable_type_table[local_variable_type_table_length]; + } + else if(attribute_name=="SourceFile") + { + u2 sourcefile_index; + } + else if(attribute_name=="InnerClasses") + { + u2 number_of_classes; + struct InnerClasses_struct{ + u2 inner_class_info_index; + u2 outer_class_info_index; + u2 inner_name_index; + u2 inner_class_access_flags; + }classes[number_of_classes] ; + } + else if(attribute_name=="EnclosingMethod") + { + u2 class_index; + u2 method_index; + } + else if(attribute_name=="Signature") + { + u2 signature_index; + } + else if(attribute_name=="SourceDebugExtension") + { + u1 debug_extension[attribute_length] ; + } + else if(attribute_name=="RuntimeVisibleAnnotations"||attribute_name=="RuntimeInvisibleAnnotations") + { + u2 num_annotations; + annotation annotations[num_annotations]; + } + else if(attribute_name=="RuntimeVisibleParameterAnnotations"||attribute_name=="RuntimeInvisibleParameterAnnotations") + { + u1 num_parameters; + struct{ + u2 num_annotations; + annotation annotations[num_annotations]; + }parameter_annotations[num_parameters]; + } + else if(attribute_name=="AnnotationDefault") + { + element_value default_value; + } + else if(attribute_name=="BootstrapMethods") + { + u2 num_bootstrap_methods; + struct{ + u2 bootstrap_method_ref; + u2 num_bootstrap_arguments; + u2 bootstrap_arguments[num_bootstrap_arguments]; + }bootstrap_methods[num_bootstrap_methods]; + } + else if(attribute_name=="StackMapTable") + { + u2 number_of_entries; + stack_map_frame entries[number_of_entries]; + } + else + { + if(attribute_length>0) u1 info[attribute_length] ; + } +}attribute_info ; + +typedef struct +{ + u2 access_flags; + u2 name_index; + u2 descriptor_index; + u2 attributes_count; + if(0; + } +}field_info ; + +typedef struct{ + u2 access_flags; + u2 name_index; + u2 descriptor_index; + u2 attributes_count; + if(0; + } +}method_info ; + + + + +typedef struct{ + if(sizeof(this)>1) + { + u1 tag; + switch(tag) + { + case CONSTANT_Class: + u2 name_index; + break; + case CONSTANT_Fieldref: + case CONSTANT_Methodref: + case CONSTANT_InterfaceMethodref: + u2 class_index; + u2 name_and_type_index; + break; + case CONSTANT_String: + u2 string_index; + break; + case CONSTANT_Integer: + case CONSTANT_Float: + u4 bytes; + break; + case CONSTANT_Long: + case CONSTANT_Double: + u4 high_bytes; + u4 low_bytes; + break; + case CONSTANT_NameAndType: + u2 name_index; + u2 descriptor_index; + break; + case CONSTANT_Utf8: + u2 length; + if(length>0) + { + u1 bytes[length]; + } + break; + case CONSTANT_MethodHandle: + u1 reference_kind; + u2 reference_index; + break; + case CONSTANT_MethodType: + u2 descriptor_index; + break; + case CONSTANT_InvokeDynamic: + u2 bootstrap_method_attr_index; + u2 name_and_type_index; + break; + default: + Warning("fix cp_info"); + break; + } + } +}cp_info; + + +typedef struct +{ + u4 magic ; + u2 minor_version; + u2 major_version; + u2 constant_pool_count; + cp_info constant_pool[constant_pool_count-1]; + u2 access_flags ; + u2 this_class ; + u2 super_class ; + + u2 interfaces_count; + if(0; + } + + u2 fields_count; + if(0; + } + + u2 methods_count; + if(0; + } + + u2 attributes_count; + if(0; + } + +}ClassFile; + +//main + + +void generator_map_address_constant_pool() +{ + local u8 address=address_constant_pool; + local u1 tag; + + + local int i; + for(i = 0; i =0&&obj.frame_type<=63) + { + return "same_frame"; + } + else if(obj.frame_type>=64&&obj.frame_type<=127) + { + return "same_locals_1_stack_item_frame"; + } + else if(obj.frame_type==247) + { + return "same_locals_1_stack_item_frame_extended"; + } + else if(obj.frame_type>=248&&obj.frame_type<=251) + { + return "chop_frame or same_frame_extended"; + } + else if(obj.frame_type>=252&&obj.frame_type<=254) + { + return "append_frame"; + } + else if(obj.frame_type==255) + { + return "full_frame"; + } +} + + +string annotation_OnComment(annotation &obj) +{ + return get_constant_pool_Utf8(obj.type_index); +} + +string Name_OnComment(u2 n) +{ + return get_constant_pool_Utf8(n); +} + +string Name_Exception_OnComment(u2 n) +{ + if(n==0)return "any"; + return get_constant_pool_Utf8(n); +} + +string element_value_OnComment(element_value &obj) +{ + switch(obj.tag) + { + case 's': + return "String"; + break; + case 'e': + return "enum"; + break; + case 'c': + return "class"; + break; + case '@': + return "annotation type"; + break; + case '[': + return "array"; + break; + default: + return ""; + break; + } +} + + +string opcodes_operation_OnComment(opcodes_operation &obj) +{ + if(!exists(obj.operation))return ""; + + string str; + string str2; + enum_opcodes obj_operation=obj.operation; + + switch(array_opcodes_body_type[obj.operation]) + { + case index_body: + SPrintf(str," %d",obj.index); + break; + case index_v2_body: + str=" "+get_constant_pool_Utf8(obj.index); + break; + case index_const_body: + SPrintf(str," %d",obj.index); + SPrintf(str2," %d",obj._const); + str=str+" by"+str2; + break; + case sipush_body: + SPrintf(str," %d",obj._byte); + break; + case bipush_body: + SPrintf(str," %d",obj._byte); + break; + case newarray_body: + switch(obj.atype) + { + case T_BOOLEAN: + str=" boolean"; + break; + case T_CHAR: + str=" char"; + break; + case T_FLOAT: + str=" float"; + break; + case T_DOUBLE: + str=" double"; + break; + case T_BYTE: + str=" byte"; + break; + case T_SHORT: + str=" short"; + break; + case T_INT: + str=" int"; + break; + case T_LONG: + str=" long"; + break; + default: + Warning("fix opcodes_operation_OnComment"); + break; + } + break; + case multianewarray_body: + SPrintf(str,"%d",obj.dimensions); + str=" "+get_constant_pool_Utf8(obj.indexbyte)+" dimensions "+str; + break; + case wide_body: + enum_opcodes obj_operation2=obj.operation2; + str=" "+EnumToString(obj_operation2)+get_constant_pool_Utf8(obj.indexbyte); + if(obj_operation2==iinc) + { + SPrintf(str2,"%d",obj.constbyte); + str=str+" by "+str2; + } + break; + case tableswitch_body: + SPrintf(str,"%d",obj.lowbyte); + SPrintf(str2,"%d",obj.highbyte); + str=" "+str+" to "+str2; + break; + case lookupswitch_body: + SPrintf(str,"%d",obj.npairs); + str=" "+str; + break; + case invokedynamic_body: + case indexbyte_1_2_body: + str=" "+get_constant_pool_Utf8(obj.indexbyte); + break; + case branchbyte1_2_body: + case branchbyte1_4_body: + SPrintf(str," %d",obj.branchbyte); + break; + case invokeinterface_body: + SPrintf(str," %d",obj._count); + str=" "+get_constant_pool_Utf8(obj.indexbyte)+" count "+str; + break; + default: + break; + } + + return EnumToString(obj_operation)+str; +} + +generator_map_address_constant_pool(); + +ClassFile classFile; \ No newline at end of file diff --git a/cparser/CRXTemplate.bt b/cparser/CRXTemplate.bt new file mode 100644 index 0000000..2a5590e --- /dev/null +++ b/cparser/CRXTemplate.bt @@ -0,0 +1,209 @@ +//----------------------------------- +//--- 010 Editor v2.0 Binary Template +// +// File: CRXTemplate.bt +// Author: SweetScape Software +// Revision: 1.0 +// Purpose: Copy of ZIPTemplate.bt +// with extra bits for Google Chrome +// extensions. +//----------------------------------- + +// Define structures used in ZIP files + +//enum used for compression format +typedef enum { + COMP_STORED = 0, + COMP_SHRUNK = 1, + COMP_REDUCED1 = 2, + COMP_REDUCED2 = 3, + COMP_REDUCED3 = 4, + COMP_REDUCED4 = 5, + COMP_IMPLODED = 6, + COMP_TOKEN = 7, + COMP_DEFLATE = 8, + COMP_DEFLATE64 = 9 +} COMPTYPE; + +// Defines a file record +typedef struct { + // Header for the file + char frSignature[4]; //0x04034b50 + ushort frVersion; + ushort frFlags; + COMPTYPE frCompression; + DOSTIME frFileTime; + DOSDATE frFileDate; + uint frCrc ; + uint frCompressedSize; + uint frUncompressedSize; + ushort frFileNameLength; + ushort frExtraFieldLength; + if( frFileNameLength > 0 ) + char frFileName[ frFileNameLength ]; + if( frExtraFieldLength > 0 ) + uchar frExtraField[ frExtraFieldLength ]; + + // Compressed data + SetBackColor( cNone ); + if( frCompressedSize > 0 ) + uchar frData[ frCompressedSize ]; + +} ZIPFILERECORD ; + +// Defines an entry in the directory table +typedef struct { + char deSignature[4]; //0x02014b50 + ushort deVersionMadeBy; + ushort deVersionToExtract; + ushort deFlags; + COMPTYPE deCompression; + DOSTIME deFileTime; + DOSDATE deFileDate; + uint deCrc ; + uint deCompressedSize; + uint deUncompressedSize; + ushort deFileNameLength; + ushort deExtraFieldLength; + ushort deFileCommentLength; + ushort deDiskNumberStart; + ushort deInternalAttributes; + uint deExternalAttributes; + uint deHeaderOffset; + if( deFileNameLength > 0 ) + char deFileName[ deFileNameLength ]; + if( deExtraFieldLength > 0 ) + uchar deExtraField[ deExtraFieldLength ]; + if( deFileCommentLength > 0 ) + uchar deFileComment[ deFileCommentLength ]; +} ZIPDIRENTRY ; + +// Defines the digital signature +typedef struct { + char dsSignature[4]; //0x05054b50 + ushort dsDataLength; + if( dsDataLength > 0 ) + uchar dsData[ dsDataLength ]; +} ZIPDIGITALSIG; + +// Defintes the Data descriptor +typedef struct { + char ddSignature[4]; //0x08074b50 + uint ddCRC ; + uint ddCompressedSize; + uint ddUncompressedSize; +} ZIPDATADESCR; + +// Defines the end of central directory locator +typedef struct { + char elSignature[4]; //0x06054b50 + ushort elDiskNumber; + ushort elStartDiskNumber; + ushort elEntriesOnDisk; + ushort elEntriesInDirectory; + uint elDirectorySize; + uint elDirectoryOffset; + ushort elCommentLength; + if( elCommentLength > 0 ) + char elComment[ elCommentLength ]; +} ZIPENDLOCATOR; + +//-------------------------------------------- + +// Custom read functions that allows the name of the +// of the file to appear in the Template Results. + +string ReadZIPFILERECORD( ZIPFILERECORD &file ) +{ + if( exists( file.frFileName ) ) + return file.frFileName; + else + return ""; +} + +string ReadZIPDIRENTRY( ZIPDIRENTRY &entry ) +{ + if( exists( entry.deFileName ) ) + return entry.deFileName; + else + return ""; +} + +// Custom write function that allows changing +// the name of the file - note that the file +// name size cannot be increased + +void WriteZIPFILERECORD( ZIPFILERECORD &file, string s ) +{ + local int len = Strlen( s ); + if( exists( file.frFileName ) ) + { + Strncpy( file.frFileName, s, file.frFileNameLength ); + if( len < file.frFileNameLength ) + file.frFileName[len] = 0; //null terminate + } +} + +typedef struct { + SetBackColor(0xd8e5ed); + char magicNumber[4]; + SetBackColor(0xd8edd8); + uint32 version; + SetBackColor(0xd8e5ed); + uint32 pkLength; + SetBackColor(0xd8edd8); + uint32 sigLength; + SetBackColor(0xf7d6c3); + byte pubKey[pkLength]; + SetBackColor(0xd8edd8); + byte sig[sigLength]; +} CRXHEADER; + +//-------------------------------------------- + +// Define the file +SetBackColor(0xe8e8e8); +CRXHEADER crxHeader; +SetBackColor(cNone); +local uint tag; +LittleEndian(); +while( !FEof() ) +{ + // Read a tag + tag = ReadUInt( FTell() ); + + // Read data depending upon tag - should start with 'PK'. + // Note that when duplicate variables are defined, they + // are made into an array (see 'Using Templates and Structs' + // in the help file). + if( tag == 0x04034b50 ) + { + SetBackColor( cLtGray ); + ZIPFILERECORD record; + } + else if( tag == 0x08074b50 ) + { + SetBackColor( cLtGreen ); + ZIPDATADESCR dataDescr; + } + else if( tag == 0x02014b50 ) + { + SetBackColor( cLtPurple ); + ZIPDIRENTRY dirEntry; + } + else if( tag == 0x05054b50 ) + { + SetBackColor( cLtBlue ); + ZIPDIGITALSIG digitalSig; + } + else if( tag == 0x06054b50 ) + { + SetBackColor( cLtYellow ); + ZIPENDLOCATOR endLocator; + } + else + { + Warning( "Unknown ZIP tag encountered. Template stopped." ); + return -1; + } +} \ No newline at end of file diff --git a/cparser/DBFTemplate.bt b/cparser/DBFTemplate.bt new file mode 100644 index 0000000..aeda4a9 --- /dev/null +++ b/cparser/DBFTemplate.bt @@ -0,0 +1,59 @@ +//-------------------------------------- +//--- 010 Editor v2.1.3 Binary Template +// +// File: +// Author: +// Revision: +// Purpose: +//-------------------------------------- + +string yearFrom1900 (char yy) +{ +string s; +SPrintf(s, "%d", 1900 + yy); +return s; +} + +struct DBF { + struct HEADER { + char version; + struct DATE_OF_LAST_UPDATE { + char yy ; + char mm ; + char dd ; + } DateOfLastUpdate; + int numberOfRecords; + short lengthOfHeaderStructure; + short lengthOfEachRecord; + char reserved[2]; + char incompleteTrasaction ; + char encryptionFlag ; + int freeRecordThread; + int reserved1[2]; + char mdxFlag ; + char languageDriver ; + short reserved2; + } header; + struct FIELD { + char fieldName[11]; + char fieldType; + int fieldDataAddress; + char fieldLength ; + char decimalCount ; + short reserved; + char workAreaId ; + short reserved1; + char flags ; + char reserved2[7]; + char indexFieldFlag ; + } field[(header.lengthOfHeaderStructure-33)/sizeof(struct FIELD)]; + char Terminator ; + struct RECORD { + char deletedFlag; + char fields[header.lengthOfEachRecord-1]; + } record [ header.numberOfRecords ] ; +} dbf ; + + + + \ No newline at end of file diff --git a/cparser/DEXTemplate.bt b/cparser/DEXTemplate.bt new file mode 100644 index 0000000..65c4b4d --- /dev/null +++ b/cparser/DEXTemplate.bt @@ -0,0 +1,1665 @@ +//-------------------------------------- +//--- 010 Editor v3.1.3 Binary Template +// +// File: DEXTemplate.bt +// Author: Jon Larimer +// Revision: 1.0 +// Purpose: A template for analyzing Dalvik VM (Android) DEX files +// +// License: This file is released into the public domain. People may +// use it for any purpose, commercial or otherwise. +//-------------------------------------- + +// Version 1.0 (2011-05-10) +// +// KNOWN ISSUES: +// - display of floats and doubles in encoded_value is incorrect +// - display of MUTF-8 strings may be incorrect +// - doesn't handle big endian (byte swapped) files +// - doesn't disassemble DEX instructions +// - only decodes partial information from optimized (ODEX/DexOpt) files +// - could use a bit of refactoring and removing duplicate code +// - not decoding items in the map_list structure - they're already +// referenced through other items in the header so adding them +// in the map_list would be reduntant +// - colors? + +LittleEndian(); + +#define NO_INDEX (0xFFFFFFFF) +#define ENDIAN_CONSTANT (0x12345678) +#define REVERSE_ENDIAN_CONSTANT (0x78563412); + +// offset used when seeking within a dex file inside of an odex wrapper +local int odexpad = 0; + +// utility type to show the SHA1 hash in the value column +typedef ubyte SHA1[20] ; + +string SHA1Read(SHA1 sig) { + string ret; + string tmp; + int i; + + for(i = 0; i<20; i++) { + SPrintf(tmp, "%.2X", sig[i]); + ret += tmp; + } + + return ret; +} + +// utility for reading/checking the magic value +typedef struct { + char dex[3]; + char newline; + char ver[3]; + char zero; + + // XXX not checking the version, but it should be 035 + if((Strcmp(dex, "dex") && Strcmp(dex, "dey")) || + newline != '\n' || + zero != 0) { + + Warning("Invalid DEX file"); + return -1; + } +} dex_magic ; + +string DexMagicRead(dex_magic &m) { + string s; + SPrintf(s, "%s %s", m.dex, m.ver); + return s; +} + +////////////////////////////////////////////////// +// LEB128 stuff +////////////////////////////////////////////////// + +// struct to read a uleb128 value. uleb128's are a variable-length encoding for +// a 32 bit value. some of the uleb128/sleb128 code was adapted from dalvik's +// libdex/Leb128.h + +typedef struct { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if (val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + } + } + } + } +} uleb128 ; + +// get the actual uint value of the uleb128 +uint uleb128_value(uleb128 &u) { + local uint result; + local ubyte cur; + + result = u.val[0]; + if(result > 0x7f) { + cur = u.val[1]; + result = (result & 0x7f) | (uint)((cur & 0x7f) << 7); + if(cur > 0x7f) { + cur = u.val[2]; + result |= (uint)(cur & 0x7f) << 14; + if(cur > 0x7f) { + cur = u.val[3]; + result |= (uint)(cur & 0x7f) << 21; + if(cur > 0x7f) { + cur = u.val[4]; + result |= (uint)cur << 28; + } + } + } + } + + return result; +} + +typedef struct uleb128 uleb128p1; + +int uleb128p1_value(uleb128 &u) { + return (int)uleb128_value(u) - 1; +} + +string ULeb128Read(uleb128 &u) { + local string s; + s = SPrintf(s, "0x%X", uleb128_value(u)); + return s; +} + +// sleb128 +typedef struct { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if (val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + } + } + } + } +} sleb128 ; + +// get the actual uint value of the uleb128 +int sleb128_value(sleb128 &u) { + local int result; + local ubyte cur; + + result = u.val[0]; + if(result <= 0x7f) { + result = (result << 25) >> 25; + } else { + cur = u.val[1]; + result = (result & 0x7f) | ((uint)(cur & 0x7f) << 7); + if(cur <= 0x7f) { + result = (result << 18) >> 18; + } else { + cur = u.val[2]; + result |= (uint)(cur & 0x7f) << 14; + if(cur <= 0x7f) { + result = (result << 11) >> 11; + } else { + cur = u.val[3]; + result |= (uint)(cur & 0x7f) << 21; + if(cur <= 0x7f) { + result = (result << 4) >> 4; + } else { + cur = u.val[4]; + result |= (uint)cur << 28; + } + } + } + } + + return result; +} + +string SLeb128Read(sleb128 &u) { + local string s; + s = SPrintf(s, "%i", sleb128_value(u)); + return s; +} + +////////////////////////////////////////////////// +// encoded_value type +////////////////////////////////////////////////// + +typedef enum { + VALUE_BYTE = 0x00, + VALUE_SHORT = 0x02, + VALUE_CHAR = 0x03, + VALUE_INT = 0x04, + VALUE_LONG = 0x06, + VALUE_FLOAT = 0x10, + VALUE_DOUBLE = 0x11, + VALUE_STRING = 0x17, + VALUE_TYPE = 0x18, + VALUE_FIELD = 0x19, + VALUE_METHOD = 0x1a, + VALUE_ENUM = 0x1b, + VALUE_ARRAY = 0x1c, + VALUE_ANNOTATION = 0x1d, + VALUE_NULL = 0x1e, + VALUE_BOOLEAN = 0x1f +} VALUE; + +// variable-width integer used by encoded_value types +typedef struct (int size, VALUE type) { + local int s = size + 1; + local VALUE t = type; + local int i; + + for(i=0; i; + } +} EncodedValue ; + +string EncodedValueRead(EncodedValue &v) { + local string s = ""; + + switch(v.t) { + case VALUE_BYTE: + case VALUE_SHORT: + case VALUE_INT: + case VALUE_LONG: + case VALUE_FLOAT: + case VALUE_DOUBLE: + SPrintf(s, "0x%X", EncodedValueValue(v)); + break; + case VALUE_STRING: + s = StringIdRead(EncodedValueValue(v)); + break; + case VALUE_TYPE: + s = LongTypeIdRead(EncodedValueValue(v)); + break; + case VALUE_FIELD: + s = FieldIdRead(EncodedValueValue(v)); + break; + case VALUE_ENUM: + s = FieldIdRead(EncodedValueValue(v)); + break; + case VALUE_ARRAY: + case VALUE_ANNOTATION: + case VALUE_BOOLEAN: + case VALUE_NULL: + s = "NULL"; + break; + } + return s; +} + +int64 EncodedValueValue(EncodedValue &v) { + local int shift = 0; + local int i; + local int64 ret; + + if(v.s == 1) { + return v.val; + } + + for(i=0; i; + ubyte value_arg:3 ; + local string valstr = ""; + local string typestr = ""; + + switch (value_type) { + case VALUE_BYTE: + ubyte value ; + SPrintf(valstr, "0x%.2X", value); + typestr = "byte"; + break; + case VALUE_SHORT: + // value_arg has size-1, either 0 or 1 + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%i", EncodedValueValue(value)); + typestr = "short"; + break; + case VALUE_CHAR: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "'%c'", EncodedValueValue(value)); + typestr = "char"; + break; + case VALUE_INT: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%i", EncodedValueValue(value)); + typestr = "int"; + break; + case VALUE_LONG: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%li", EncodedValueValue(value)); + typestr = "long"; + break; + case VALUE_FLOAT: // XXX this doesn't work + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%f", EncodedValueValue(value)); + typestr = "float"; + break; + case VALUE_DOUBLE: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%li", EncodedValueValue(value)); + typestr = "double"; + break; + case VALUE_STRING: + EncodedValue value(value_arg, value_type) ; + valstr = "\"" + GetStringById(EncodedValueValue(value)) + "\""; + typestr = "string"; + break; + case VALUE_TYPE: + EncodedValue value(value_arg, value_type) ; + valstr = GetLongTypeById(EncodedValueValue(value)); + typestr = "type"; + break; + case VALUE_FIELD: + EncodedValue value(value_arg, value_type) ; + valstr = GetFieldById(EncodedValueValue(value)); + typestr = "field"; + break; + case VALUE_METHOD: + EncodedValue value(value_arg, value_type) ; + valstr = GetMethodById(EncodedValueValue(value)); + typestr = "method"; + break; + case VALUE_ENUM: + EncodedValue value(value_arg, value_type) ; + valstr = GetFieldById(EncodedValueValue(value)); + typestr = "enum"; + break; + case VALUE_ARRAY: + struct encoded_array array ; + break; + case VALUE_ANNOTATION: + struct encoded_annotation annotation ; + break; + case VALUE_NULL: + // no additional bytes used by null + typestr = valstr = "NULL"; + break; + case VALUE_BOOLEAN: + // no additional bytes used by boolean + typestr = "boolean"; + if(value_arg == 0) { + valstr = "false"; + } else { + valstr = "true"; + } + break; + default: + Warning("Unknown type for encoded value 0x%X", value_type); + break; + } +} encoded_value ; + +string EncodedValueStructRead(encoded_value &v) { + return v.typestr + ": " + v.valstr; +} + +typedef struct { + uleb128 size ; + encoded_value values[uleb128_value(size)] ; +} encoded_array ; + +// show first 5 elements of the array +string EncodedArrayRead(encoded_array &a) { + local int count = 5; + local int dots = 1; + local int i; + + if(uleb128_value(a.size) < 5) { + count = uleb128_value(a.size); + dots = 0; + } + + string val = "["; + + for(i=0; i; + encoded_value value ; +} annotation_element ; + +string AnnotationElementRead(annotation_element &e) { + string name = GetStringById(uleb128_value(e.name_idx)); + return name + " = " + e.value.valstr; +} + +typedef struct { + uleb128 type_idx ; + uleb128 size ; + + if(uleb128_value(size) > 0) { + annotation_element elements[uleb128_value(size)] ; + } +} encoded_annotation ; + +string EncodedAnnotationRead(encoded_annotation &a) { + string s; + SPrintf(s, "%i annotations for %s", uleb128_value(a.size), GetLongTypeById(uleb128_value(a.type_idx))); + return s; +} + +////////////////////////////////////////////////// +// dex file header +////////////////////////////////////////////////// + +typedef struct { + dex_magic magic ; + uint checksum ; + SHA1 signature ; + uint file_size ; + uint header_size ; + uint endian_tag ; + + if(endian_tag != ENDIAN_CONSTANT) { + // XXX we don't handle big endian files + Warning("Invalid endian_tag %.8X, should be %.8X", endian_tag, ENDIAN_CONSTANT); + } + + uint link_size ; + uint link_off ; + uint map_off ; + uint string_ids_size ; + uint string_ids_off ; + uint type_ids_size ; + uint type_ids_off ; + uint proto_ids_size ; + uint proto_ids_off ; + uint field_ids_size ; + uint field_ids_off ; + uint method_ids_size ; + uint method_ids_off ; + uint class_defs_size ; + uint class_defs_off ; + uint data_size ; + uint data_off ; +} header_item; + +////////////////////////////////////////////////// +// odex file header +////////////////////////////////////////////////// + +typedef enum { + DEX_FLAG_VERIFIED = 0x1, + DEX_OPT_FLAG_BIG = 0x2, + DEX_OPT_FLAG_FIELDS = 0x4, + DEX_OPT_FLAG_INVOCATIONS = 0x8 +} DEX_OPT_FLAGS; + +typedef struct { + dex_magic magic ; + uint dex_offset ; + uint dex_length ; + uint deps_offset ; + uint deps_length ; + uint opt_offset ; + uint opt_length ; + DEX_OPT_FLAGS flags ; + uint checksum ; +} dexopt_header_item; + +string DexOptFlagsRead(DEX_OPT_FLAGS f) { + string ret = ""; + string flags = ""; + DEX_OPT_FLAGS i = 1; + + while(i <= DEX_OPT_FLAG_INVOCATIONS) { + if (f & i) { + flags += EnumToString(i) + " "; + } + i = i << 1; + } + + SPrintf(ret, "(0x%X) %s", f, flags); + return ret; +} + +////////////////////////////////////////////////// +// strings +////////////////////////////////////////////////// + +typedef struct { + uleb128 utf16_size ; + string data ; +} string_item; + +typedef struct { + uint string_data_off ; + + local int64 pos = FTell(); + FSeek(odexpad + string_data_off); + + string_item string_data ; + + FSeek(pos); +} string_id_item ; + +string StringDataReader(string_id_item &i) { + return i.string_data.data; +} + +typedef struct (int size) { + local int s = size; + string_id_item string_id[size] ; +} string_id_list ; + +string StringIDListRead(string_id_list &l) { + string s; + s = SPrintf(s, "%d strings", l.s); + return s; +} + +////////////////////////////////////////////////// +// type IDs +////////////////////////////////////////////////// + +typedef struct { + uint descriptor_idx ; +} type_id_item ; + +string TypeIDRead(type_id_item &i) { + return GetLongTypeDescriptor(GetStringById(i.descriptor_idx)); +} + +typedef struct (int size) { + local int s = size; + type_id_item type_id[size] ; +} type_id_list ; + +string TypeIDListRead(type_id_list &l) { + string s; + s = SPrintf(s, "%d types", l.s); + return s; +} + +////////////////////////////////////////////////// +// type list +////////////////////////////////////////////////// +typedef struct { + ushort type_idx ; +} type_item; + +typedef struct { + uint size ; + type_item list[size] ; +} type_item_list ; + +string TypeItemRead(type_item &t) { + return GetTypeById(t.type_idx); +} + +string TypeItemListRead(type_item_list &l) { + string s = ""; + string tmp; + int i; + + for(i = 0; i < l.size; i++) { + s += GetTypeById(l.list[i].type_idx); + if(i+1 < l.size) { + s += ", "; + } + } + return s; +} + +string GetLongTypeDescriptor(string descriptor) { + local string desc = ""; + local string post = ""; + local int i = 0; + local int len = Strlen(descriptor); + + // array descriptors + while(descriptor[i] == '[') { + post += "[]"; + i++; + + if(i >= len) return "ERROR"; + } + + if(descriptor[i] == 'L') { + // fully qualified class descriptors + i++; + while(i < len) { + if(descriptor[i] == '/') desc += "."; + else if(descriptor[i] == ';') break; + else desc += descriptor[i]; + i++; + } + } else { + // simple type descriptors + switch(descriptor[i]) { + case 'V': desc = "void"; break; + case 'Z': desc = "boolean"; break; + case 'B': desc = "byte"; break; + case 'S': desc = "short"; break; + case 'C': desc = "char"; break; + case 'I': desc = "int"; break; + case 'J': desc = "long"; break; + case 'F': desc = "float"; break; + case 'D': desc = "double"; break; + } + } + + return desc + post; +} + +////////////////////////////////////////////////// +// protoypes +////////////////////////////////////////////////// + +typedef struct { + uint shorty_idx ; + uint return_type_idx ; + uint parameters_off ; + + if(parameters_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + parameters_off); + + type_item_list parameters ; + + FSeek(pos); + } + +} proto_id_item ; + +string ProtoIDItemRead(proto_id_item &i) { + return GetPrototypeSignature(i); +} + +typedef struct (int size) { + local int s = size; + proto_id_item proto_id[size] ; +} proto_id_list ; + +string ProtoIDListRead(proto_id_list &l) { + string s; + s = SPrintf(s, "%d prototypes", l.s); + return s; +} + +string GetParameterListString(type_item_list &l) { + local string s = "("; + local string tmp; + local int i; + + for(i = 0; i < l.size; i++) { + s += GetLongTypeDescriptor(GetTypeById(l.list[i].type_idx)); + if(i+1 < l.size) { + s += ", "; + } + } + return s + ")"; +} + +string GetPrototypeSignature(proto_id_item &item) { + string ret = GetLongTypeDescriptor(GetTypeById(item.return_type_idx)); + string params = "()"; + if(exists(item.parameters)) { + params = GetParameterListString(item.parameters); + } + + return ret + " " + params; +} + +////////////////////////////////////////////////// +// fields +////////////////////////////////////////////////// + +typedef struct { + ushort class_idx ; + ushort type_idx ; + uint name_idx ; +} field_id_item ; + +string FieldIdItemRead(field_id_item &i) { + string type = GetLongTypeDescriptor(GetTypeById(i.type_idx)); + string class = GetLongTypeDescriptor(GetTypeById(i.class_idx)); + string name = GetStringById(i.name_idx); + + return type + " " + class + "." + name; +} + +typedef struct (int size) { + local int s = size; + field_id_item field_id[size] ; +} field_id_list ; + +string FieldIDListRead(field_id_list &l) { + string s; + s = SPrintf(s, "%d fields", l.s); + return s; +} + +////////////////////////////////////////////////// +// methods +////////////////////////////////////////////////// + +typedef struct { + ushort class_idx ; + ushort proto_idx ; + uint name_idx ; +} method_id_item ; + +string ProtoIdxRead(ushort p) { + string s; + SPrintf(s, "(0x%X) %s", p, GetPrototypeSignature(dex_proto_ids.proto_id[p])); + return s; +} + +string MethodIdItemRead(method_id_item &m) { + local string retval = GetLongTypeDescriptor(GetTypeById(dex_proto_ids.proto_id[m.proto_idx].return_type_idx)); + local string classname = GetLongTypeDescriptor(GetStringById(dex_type_ids.type_id[m.class_idx].descriptor_idx)); + local string methodname = GetStringById(m.name_idx); + local string params = "()"; + if(exists(dex_proto_ids.proto_id[m.proto_idx].parameters)) { + params = GetParameterListString(dex_proto_ids.proto_id[m.proto_idx].parameters); + } + return retval + " " + classname + "." + methodname + params; +} + +typedef struct (int size) { + local int s = size; + method_id_item method_id[size] ; +} method_id_list ; + +string MethodIDListRead(method_id_list &l) { + string s; + s = SPrintf(s, "%d methods", l.s); + return s; +} + +////////////////////////////////////////////////// +// annotations +////////////////////////////////////////////////// + +typedef struct { + uint field_idx ; + uint annotations_off; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_item field_annotations; + + FSeek(pos); + } +} field_annotation ; + +string FieldAnnotationRead(field_annotation &f) { + return GetFieldById(f.field_idx); +} + +typedef struct { + uint method_idx ; + uint annotations_off; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_item method_annotations; + + FSeek(pos); + } +} method_annotation ; + +string MethodAnnotationRead(method_annotation &m) { + return GetMethodById(m.method_idx); +} + +typedef struct { + uint method_idx ; + uint annotations_off; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_ref_list annotations_list; + + FSeek(pos); + } +} parameter_annotation ; + +string ParameterAnnotationRead(parameter_annotation &p) { + return GetParameterListString(dex_proto_ids.proto_id[dex_method_ids.method_id[p.method_idx].proto_idx].parameters); +} + +typedef enum { + VISIBILITY_BUILD = 0x0, + VISIBILITY_RUNTIME = 0x1, + VISIBILITY_SYSTEM = 0x2 +} VISIBILITY; + +typedef struct { + VISIBILITY visibility ; + encoded_annotation annotation ; +} annotation_item ; + +string AnnotationItemRead(annotation_item &i) { + return EncodedAnnotationRead(i.annotation); +} + +typedef struct { + uint annotation_off ; + + if(annotation_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotation_off); + + annotation_item item ; + + FSeek(pos); + } + +} annotation_off_item ; + +string AnnotationOffItemRead(annotation_off_item &i) { + if(exists(i.item)) { + return AnnotationItemRead(i.item); + } +} + +typedef struct { + uint size ; + + if(size > 0) { + annotation_off_item entries[size] ; + } +} annotation_set_item ; + +string AnnotationSetItemRead(annotation_set_item &i) { + local string s; + SPrintf(s, "%i annotation entries", i.size); + return s; +} + +typedef struct { + uint class_annotations_off ; + + if(class_annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + class_annotations_off); + + annotation_set_item class_annotations ; + + FSeek(pos); + } + uint fields_size ; + uint methods_size ; + uint parameters_size ; + + if(fields_size > 0) { + field_annotation field_annotations[fields_size] ; + } + + if(methods_size > 0) { + method_annotation method_annotations[methods_size] ; + } + + if(parameters_size > 0) { + parameter_annotation parameter_annotations[parameters_size] ; + } +} annotations_directory_item ; + +string AnnotationsDirectoryItemRead(annotations_directory_item &i) { + local string s; + local int classes = 0; + if(exists(i.class_annotations)) { + classes = i.class_annotations.size; + } + + SPrintf(s, "%i class annotations, %i field annotations, %i method annotations, %i parameter annotations", + classes, i.fields_size, i.methods_size, i.parameters_size); + return s; +} + +typedef struct { + uint annotations_off ; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_item item ; + + FSeek(pos); + } +} annotation_set_ref_item ; + +typedef struct { + uint size ; + + if(size > 0) { + annotation_set_ref_item list[size] ; + } +} annotation_set_ref_list; + +////////////////////////////////////////////////// +// classes +////////////////////////////////////////////////// + +// access flags. some of these mean different things for different items (class/field/method) +typedef enum { + ACC_PUBLIC = 0x1, + ACC_PRIVATE = 0x2, + ACC_PROTECTED = 0x4, + ACC_STATIC = 0x8, + ACC_FINAL = 0x10, + ACC_SYNCHRONIZED = 0x20, + ACC_VOLATILE = 0x40, // field + //ACC_BRIDGE = 0x40, // method + ACC_TRANSIENT = 0x80, // field + //ACC_VARARGS = 0x80, // method + ACC_NATIVE = 0x100, + ACC_INTERFACE = 0x200, + ACC_ABSTRACT = 0x400, + ACC_STRICT = 0x800, + ACC_SYNTHETIC = 0x1000, + ACC_ANNOTATION = 0x2000, + ACC_ENUM = 0x4000, + ACC_CONSTRUCTOR = 0x10000, + ACC_DECLARED_SYNCHRONIZED = 0x20000 +} ACCESS_FLAGS ; + +string AccessFlagsRead(ACCESS_FLAGS f) { + string ret = ""; + string flags = ""; + ACCESS_FLAGS i = 1; + + while(i <= ACC_DECLARED_SYNCHRONIZED) { + if (f & i) { + flags += EnumToString(i) + " "; + } + i = i << 1; + } + + SPrintf(ret, "(0x%X) %s", f, flags); + return ret; +} + +string AccessFlagsReadUleb(uleb128 &f) { + return AccessFlagsRead(uleb128_value(f)); +} + +typedef enum { + AF_CLASS, AF_FIELD, AF_METHOD +} AF_TYPE; + +string GetFriendlyAccessFlag(int flag, AF_TYPE type) { + switch (flag) { + case ACC_PUBLIC: return "public"; + case ACC_PRIVATE: return "private"; + case ACC_PROTECTED: return "protected"; + case ACC_STATIC: return "static"; + case ACC_FINAL: return "final"; + case ACC_SYNCHRONIZED: return "synchronized"; + case ACC_VOLATILE: + if(type == AF_FIELD) return "volatile"; + else return "bridge"; // 0x40 is 'bridge' for methods + case ACC_TRANSIENT: + if(type == AF_FIELD) return "transient"; + else return "varargs"; // 0x80 is 'varargs' for methods + case ACC_NATIVE: return "native"; + case ACC_INTERFACE: return "interface"; + case ACC_ABSTRACT: return "abstract"; + case ACC_STRICT: return "strict"; + case ACC_SYNTHETIC: return "synthetic"; + case ACC_ANNOTATION: return "annotation"; + case ACC_ENUM: return "enum"; + case ACC_CONSTRUCTOR: return "constructor"; + case ACC_DECLARED_SYNCHRONIZED: return "declared-synchronized"; + } + return "ERROR"; +} + +string GetFriendlyAccessFlags(ACCESS_FLAGS f, AF_TYPE type) { + string flags = ""; + ACCESS_FLAGS i = 1; + + while(i <= ACC_DECLARED_SYNCHRONIZED) { + if (f & i) { + flags += GetFriendlyAccessFlag(i, type) + " "; + } + i = i << 1; + } + + return flags; +} + +// encoded fields +typedef struct (int previd) { + local int p = previd; + + uleb128 field_idx_diff ; + uleb128 access_flags ; +} encoded_field ; + +string EncodedFieldRead(encoded_field &f) { + local int realid = f.p + uleb128_value(f.field_idx_diff); + return GetFriendlyAccessFlags(uleb128_value(f.access_flags), AF_FIELD) + GetFieldById(realid); +} + +typedef struct (int size) { + local int s = size; + local int i; + local int fieldid = 0; + + for(i=0; i; + fieldid = fieldid + uleb128_value(field.field_idx_diff); + } +} encoded_field_list ; + +string EncodedFieldListRead(encoded_field_list &l) { + local string s; + SPrintf(s, "%i fields", l.s); + return s; +} + +// encoded methods +typedef struct (int previd) { + local int p = previd; + + uleb128 method_idx_diff ; + uleb128 access_flags ; + uleb128 code_off ; + + if(uleb128_value(code_off) != 0) { + local int64 pos = FTell(); + FSeek(odexpad + uleb128_value(code_off)); + struct code_item code ; + FSeek(pos); + } +} encoded_method ; + +string EncodedMethodRead(encoded_method &m) { + local int realid = m.p + uleb128_value(m.method_idx_diff); + return GetFriendlyAccessFlags(uleb128_value(m.access_flags), AF_METHOD) + GetMethodById(realid); +} + +typedef struct (int size) { + local int s = size; + local int i; + local int methodid = 0; + + for(i=0; i; + methodid = methodid + uleb128_value(method.method_idx_diff); + } +} encoded_method_list ; + +string EncodedMethodListRead(encoded_method_list &l) { + local string s; + SPrintf(s, "%i methods", l.s); + return s; +} + +typedef struct { + uleb128 static_fields_size ; + uleb128 instance_fields_size ; + uleb128 direct_methods_size ; + uleb128 virtual_methods_size ; + + if(uleb128_value(static_fields_size) > 0) { + encoded_field_list static_fields(uleb128_value(static_fields_size)) ; + } + + if(uleb128_value(instance_fields_size) > 0) { + encoded_field_list instance_fields(uleb128_value(instance_fields_size)) ; + } + + if(uleb128_value(direct_methods_size) > 0) { + encoded_method_list direct_methods(uleb128_value(direct_methods_size)) ; + } + + if(uleb128_value(virtual_methods_size) > 0) { + encoded_method_list virtual_methods(uleb128_value(virtual_methods_size)) ; + } +} class_data_item ; + +string ClassDataItemRead(class_data_item &i) { + local string s; + SPrintf(s, "%i static fields, %i instance fields, %i direct methods, %i virtual methods", + uleb128_value(i.static_fields_size), uleb128_value(i.instance_fields_size), + uleb128_value(i.direct_methods_size), uleb128_value(i.virtual_methods_size)); + return s; +} + +typedef struct { + local int64 pos; + + uint class_idx ; + ACCESS_FLAGS access_flags ; + uint superclass_idx ; + + uint interfaces_off ; + if(interfaces_off != 0) { + pos = FTell(); + FSeek(odexpad + interfaces_off); + type_item_list interfaces ; + FSeek(pos); + } + + uint source_file_idx ; + + uint annotations_off ; + if(annotations_off != 0) { + pos = FTell(); + FSeek(odexpad + annotations_off); + annotations_directory_item annotations ; + FSeek(pos); + } + + uint class_data_off ; + if(class_data_off != 0) { + pos = FTell(); + FSeek(odexpad + class_data_off); + class_data_item class_data ; + FSeek(pos); + } + + uint static_values_off ; + if(static_values_off != 0) { + pos = FTell(); + FSeek(odexpad + static_values_off); + struct encoded_array_item static_values ; + FSeek(pos); + } +} class_def_item ; + +string ClassDefItemRead(class_def_item &i) { + local string classname = GetLongTypeById(i.class_idx); + local string flags = GetFriendlyAccessFlags(i.access_flags, AF_CLASS); + return flags + classname; +} + +string InterfacesRead(type_item_list &l) { + string s = ""; + int i; + + for(i = 0; i < l.size; i++) { + s += GetLongTypeDescriptor(GetTypeById(l.list[i].type_idx)); + if(i+1 < l.size) { + s += ", "; + } + } + return s; +} + +typedef struct (int size) { + local int s = size; + class_def_item class_def[size] ; +} class_def_item_list ; + +string ClassDefItemListRead(class_def_item_list &l) { + string s; + s = SPrintf(s, "%d classes", l.s); + return s; +} + +typedef struct { + uint start_addr ; + ushort insn_count ; + ushort handler_off ; +} try_item ; + +typedef struct { + sleb128 size ; + + local int s = sleb128_value(size); + local int numhandlers = 0; + + if(s != 0) { + numhandlers = Abs(s); + struct encoded_type_addr_pair handlers[numhandlers] ; + } + + if(s <= 0) { + uleb128 catch_all_addr ; + numhandlers++; + } +} encoded_catch_handler ; + +string EncodedCatchHandlerRead(encoded_catch_handler &h) { + local string s; + SPrintf(s, "%i handlers", h.numhandlers); + return s; +} + +typedef struct { + uleb128 size ; + encoded_catch_handler list[uleb128_value(size)] ; +} encoded_catch_handler_list ; + +string EncodedCatchHandlerListRead(encoded_catch_handler_list &l) { + local string s; + SPrintf(s, "%i handler lists", uleb128_value(l.size)); + return s; +} + +typedef struct { + ushort registers_size ; + ushort ins_size ; + ushort outs_size ; + ushort tries_size ; + uint debug_info_off ; + + if(debug_info_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + debug_info_off); + + struct debug_info_item debug_info ; + FSeek(pos); + } + + uint insns_size ; + if(insns_size != 0) { + ushort insns[insns_size] ; + } + + if(tries_size != 0) { + if (insns_size & 1 == 1) { + ushort padding ; + } + + try_item tries[tries_size] ; + encoded_catch_handler_list handlers ; + } +} code_item ; + +string CodeItemRead(code_item &i) { + local string s; + SPrintf(s, "%i registers, %i in arguments, %i out arguments, %i tries, %i instructions", + i.registers_size, i.ins_size, i.outs_size, i.tries_size, i.insns_size); + return s; +} + +typedef struct { + uleb128 type_idx ; + uleb128 addr ; +} encoded_type_addr_pair ; + +string EncodedTypeAddrPairRead(encoded_type_addr_pair &p) { + string s; + SPrintf(s, "%s at 0x%X", GetLongTypeById(uleb128_value(p.type_idx)), uleb128_value(p.addr)); + return s; +} + +typedef struct { + encoded_array value ; +} encoded_array_item ; + +string EncodedArrayItemRead(encoded_array_item &i) { + local string s; + SPrintf(s, "%i items: %s", uleb128_value(i.value.size), EncodedArrayRead(i.value)); + return s; +} + +enum TYPE_CODES { + TYPE_HEADER_ITEM = 0x0000, + TYPE_STRING_ID_ITEM = 0x0001, + TYPE_TYPE_ID_ITEM = 0x0002, + TYPE_PROTO_ID_ITEM = 0x0003, + TYPE_FIELD_ID_ITEM = 0x0004, + TYPE_METHOD_ID_ITEM = 0x0005, + TYPE_CLASS_DEF_ITEM = 0x0006, + + TYPE_MAP_LIST = 0x1000, + TYPE_TYPE_LIST = 0x1001, + TYPE_ANNOTATION_SET_REF_LIST = 0x1002, + TYPE_ANNOTATION_SET_ITEM = 0x1003, + + TYPE_CLASS_DATA_ITEM = 0x2000, + TYPE_CODE_ITEM = 0x2001, + TYPE_STRING_DATA_ITEM = 0x2002, + TYPE_DEBUG_INFO_ITEM = 0x2003, + TYPE_ANNOTATION_ITEM = 0x2004, + TYPE_ENCODED_ARRAY_ITEM = 0x2005, + TYPE_ANNOTATIONS_DIRECTORY_ITEM = 0x2006 +}; + +////////////////////////////////////////////////// +// debug info +////////////////////////////////////////////////// + +typedef enum { + DBG_END_SEQUENCE = 0x00, + DBG_ADVANCE_PC = 0x01, + DBG_ADVANCE_LINE = 0x02, + DBG_START_LOCAL = 0x03, + DBG_START_LOCAL_EXTENDED = 0x04, + DBG_END_LOCAL = 0x05, + DBG_RESTART_LOCAL = 0x06, + DBG_SET_PROLOGUE_END = 0x07, + DBG_SET_EPILOGUE_BEGIN = 0x08, + DBG_SET_FILE = 0x09 +} DBG_OPCODE; + +typedef struct { + DBG_OPCODE opcode ; + local string args = ""; + + switch (opcode) { + case DBG_END_SEQUENCE: + break; + case DBG_ADVANCE_PC: + uleb128 addr_diff ; + SPrintf(args, "%i", uleb128_value(addr_diff)); + break; + case DBG_ADVANCE_LINE: + sleb128 line_diff ; + SPrintf(args, "%i", sleb128_value(line_diff)); + break; + case DBG_START_LOCAL: + uleb128 register_num ; + uleb128p1 name_idx ; + uleb128p1 type_idx ; + SPrintf(args, "%i, %s, %s", uleb128_value(register_num), StringIdReadUlebp1(name_idx), + LongTypeIdReadUlebp1(type_idx)); + break; + case DBG_START_LOCAL_EXTENDED: + uleb128 register_num ; + uleb128p1 name_idx ; + uleb128p1 type_idx ; + uleb128p1 sig_idx ; + SPrintf(args, "%i, %s, %s, %s", uleb128_value(register_num), StringIdReadUlebp1(name_idx), + LongTypeIdReadUlebp1(type_idx), StringIdReadUlebp1(sig_idx)); + break; + case DBG_END_LOCAL: + uleb128 register_num ; + SPrintf(args, "%i", uleb128_value(register_num)); + break; + case DBG_RESTART_LOCAL: + uleb128 register_num ; + SPrintf(args, "%i", uleb128_value(register_num)); + break; + case DBG_SET_PROLOGUE_END: + case DBG_SET_EPILOGUE_BEGIN: + break; + case DBG_SET_FILE: + uleb128p1 name_idx ; + SPrintf(args, "%s", StringIdReadUlebp1(name_idx)); + } +} debug_opcode ; + +#define DBG_FIRST_SPECIAL 0x0a +#define DBG_LINE_BASE -4 +#define DBG_LINE_RANGE 15 + +string DebugOpcodeRead(debug_opcode &opcode) { + local string s; + if(opcode.opcode >= DBG_FIRST_SPECIAL) { + local ubyte adjusted = opcode.opcode - DBG_FIRST_SPECIAL; + SPrintf(s, "Special opcode: line + %i, address + %i", DBG_LINE_BASE + (adjusted % DBG_LINE_RANGE), (adjusted / DBG_LINE_RANGE)); + } else { + s = EnumToString(opcode.opcode); + } + + if(opcode.args != "") { + s += " (" + opcode.args + ")"; + } + + return s; +} + +typedef struct { + uleb128 line_start ; + uleb128 parameters_size ; + if(uleb128_value(parameters_size) > 0) { + uleb128p1 parameter_names[uleb128_value(parameters_size)] ; // actually uleb128p1 + } + + do { + debug_opcode opcode ; + } while (opcode.opcode != DBG_END_SEQUENCE); +} debug_info_item; + +////////////////////////////////////////////////// +// map list +////////////////////////////////////////////////// +typedef struct { + TYPE_CODES type; + ushort unused; + uint size; + uint offset; +} map_item ; + +string MapItemRead(map_item &m) { + string s; + SPrintf(s, "%s", EnumToString(m.type)); + return s; +} + +typedef struct { + uint size; + map_item list[size]; +} map_list_type ; + +string MapListTypeRead(map_list_type &t) { + local string s; + SPrintf(s, "%i items", t.size); + return s; +} + +////////////////////////////////////////////////// +// utility functions for reading various strings +// note: strings are stored in a format called MUTF-8, and its +// possible they won't always display correctly in the 010 UI +////////////////////////////////////////////////// + +// read a value from the string table +string StringIdRead(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + local string s; + SPrintf(s, "(0x%.X) \"%s\"", id, GetStringById(id)); + return s; +} + +string StringIdReadUleb(uleb128 &id) { + return StringIdRead(uleb128_value(id)); +} + +string StringIdReadUlebp1(uleb128p1 &id) { + return StringIdRead(uleb128p1_value(id)); +} + +// read a value from the type table, return short form +string TypeIdRead(int id) { + return GetIdAndNameString(id, GetTypeById(id)); +} + +// read a value from the type table, return the long form +string LongTypeIdRead(int id) { + return GetIdAndNameString(id, GetLongTypeById(id)); +} + +string LongTypeIdReadUleb(uleb128 &id) { + return LongTypeIdRead(uleb128_value(id)); +} + +string LongTypeIdReadUlebp1(uleb128p1 &id) { + return LongTypeIdRead(uleb128p1_value(id)); +} + +string FieldIdRead(int id) { + return GetIdAndNameString(id, GetFieldById(id)); +} + +string MethodIdRead(int id) { + return GetIdAndNameString(id, GetMethodById(id)); +} + +string GetIdAndNameString(int id, string name) { + local string s; + SPrintf(s, "(0x%X) %s", id, name); + return s; +} + +// read a string from the string table +string GetStringById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_string_ids.string_id[id])) { + return dex_string_ids.string_id[id].string_data.data; + } else { + return "*** NO STRING"; + } +} + +string GetTypeById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_type_ids.type_id[id])) { + return GetStringById(dex_type_ids.type_id[id].descriptor_idx); + } else { + return "*** NO TYPE"; + } +} + +string GetLongTypeById(int id) { + return GetLongTypeDescriptor(GetTypeById(id)); +} + +string GetMethodById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_method_ids.method_id[id])) { + return MethodIdItemRead(dex_method_ids.method_id[id]); + } else { + return "*** NO METHOD"; + } +} + +string GetFieldById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_field_ids.field_id[id])) { + return FieldIdItemRead(dex_field_ids.field_id[id]); + } else { + return "*** NO FIELD"; + } +} + +////////////////////////////////////////////////// +// dexopt stuff +////////////////////////////////////////////////// + +typedef enum { + DEX_CHUNK_CLASS_LOOKUP = 0x434c4b50, + DEX_CHUNK_REGISTER_MAPS = 0x524d4150, + DEX_CHUNK_END = 0x41454e44 +} DEX_CHUNK_TYPE; + +typedef struct { + DEX_CHUNK_TYPE type ; + uint size ; + local int realsize = (size + 7) & ~7; + + + if(type == DEX_CHUNK_CLASS_LOOKUP) { + struct dex_class_lookup class_lookup_table ; + } else if (type == DEX_CHUNK_REGISTER_MAPS) { + ubyte chunkbytes[realsize]; + } else if (type == DEX_CHUNK_END) { + //ubyte chunkbytes[realsize]; + } else { + Warning("Unknown chunk type 0x%X", type); + return; + } +} dexopt_opt_chunk ; + +typedef struct { + local int count = 0; + do { + dexopt_opt_chunk chunk; + count++; + } while(chunk.type != DEX_CHUNK_END); +} dexopt_opt_table ; + +string DexoptOptTableRead(dexopt_opt_table &t) { + local string s; + SPrintf(s, "%i items", t.count); + return s; +} + +string DexOptChunkRead(dexopt_opt_chunk &c) { + local string s; + SPrintf(s, "%s chunk: %i bytes", EnumToString(c.type), c.size); + return s; +} + +typedef struct { + uint class_descriptor_hash ; + int class_descriptor_offset ; + int class_definition_offset ; +} dex_class_lookup_entry ; + +string DexClassLookupEntryRead(dex_class_lookup_entry &e) { + local string s; + SPrintf(s, "0x%X: (descriptor 0x%X, definition 0x%X)", e.class_descriptor_hash, e.class_descriptor_offset, e.class_definition_offset); + return s; +} + +typedef struct { + int size ; + int num_entries ; + + if(num_entries > 0) { + dex_class_lookup_entry table[num_entries] ; + } +} dex_class_lookup; + +////////////////////////////////////////////////// +// main stuff +////////////////////////////////////////////////// + +// first check file type - dex files start with 'dex', odex files start with 'dey' +local int odex = 0; +local char tmp[3]; +ReadBytes(tmp, 0, 3); +FSeek(0); + +if(!Strcmp(tmp, "dey")) { + odex = 1; +} + +// dexopt files start with a dexopt header +if(odex) { + dexopt_header_item dexopt_header ; + odexpad = dexopt_header.dex_offset; + FSeek(odexpad); +} + +// main dex header and structs +header_item dex_header ; +string_id_list dex_string_ids(dex_header.string_ids_size) ; +type_id_list dex_type_ids(dex_header.type_ids_size) ; +proto_id_list dex_proto_ids(dex_header.proto_ids_size) ; +field_id_list dex_field_ids(dex_header.field_ids_size) ; +method_id_list dex_method_ids(dex_header.method_ids_size) ; +class_def_item_list dex_class_defs(dex_header.class_defs_size) ; + +// map list, we don't really do anything with it though +if(dex_header.map_off != 0) { + FSeek(odexpad + dex_header.map_off); + map_list_type dex_map_list ; +} + +if(odex) { + if(dexopt_header.deps_offset != 0) { + FSeek(dexopt_header.deps_offset); + ubyte dexopt_deps[dexopt_header.deps_length] ; + } + + if(dexopt_header.opt_offset != 0) { + FSeek(dexopt_header.opt_offset); + dexopt_opt_table opt_table ; + } +} \ No newline at end of file diff --git a/cparser/DEXTemplate.new.bt b/cparser/DEXTemplate.new.bt new file mode 100644 index 0000000..65c4b4d --- /dev/null +++ b/cparser/DEXTemplate.new.bt @@ -0,0 +1,1665 @@ +//-------------------------------------- +//--- 010 Editor v3.1.3 Binary Template +// +// File: DEXTemplate.bt +// Author: Jon Larimer +// Revision: 1.0 +// Purpose: A template for analyzing Dalvik VM (Android) DEX files +// +// License: This file is released into the public domain. People may +// use it for any purpose, commercial or otherwise. +//-------------------------------------- + +// Version 1.0 (2011-05-10) +// +// KNOWN ISSUES: +// - display of floats and doubles in encoded_value is incorrect +// - display of MUTF-8 strings may be incorrect +// - doesn't handle big endian (byte swapped) files +// - doesn't disassemble DEX instructions +// - only decodes partial information from optimized (ODEX/DexOpt) files +// - could use a bit of refactoring and removing duplicate code +// - not decoding items in the map_list structure - they're already +// referenced through other items in the header so adding them +// in the map_list would be reduntant +// - colors? + +LittleEndian(); + +#define NO_INDEX (0xFFFFFFFF) +#define ENDIAN_CONSTANT (0x12345678) +#define REVERSE_ENDIAN_CONSTANT (0x78563412); + +// offset used when seeking within a dex file inside of an odex wrapper +local int odexpad = 0; + +// utility type to show the SHA1 hash in the value column +typedef ubyte SHA1[20] ; + +string SHA1Read(SHA1 sig) { + string ret; + string tmp; + int i; + + for(i = 0; i<20; i++) { + SPrintf(tmp, "%.2X", sig[i]); + ret += tmp; + } + + return ret; +} + +// utility for reading/checking the magic value +typedef struct { + char dex[3]; + char newline; + char ver[3]; + char zero; + + // XXX not checking the version, but it should be 035 + if((Strcmp(dex, "dex") && Strcmp(dex, "dey")) || + newline != '\n' || + zero != 0) { + + Warning("Invalid DEX file"); + return -1; + } +} dex_magic ; + +string DexMagicRead(dex_magic &m) { + string s; + SPrintf(s, "%s %s", m.dex, m.ver); + return s; +} + +////////////////////////////////////////////////// +// LEB128 stuff +////////////////////////////////////////////////// + +// struct to read a uleb128 value. uleb128's are a variable-length encoding for +// a 32 bit value. some of the uleb128/sleb128 code was adapted from dalvik's +// libdex/Leb128.h + +typedef struct { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if (val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + } + } + } + } +} uleb128 ; + +// get the actual uint value of the uleb128 +uint uleb128_value(uleb128 &u) { + local uint result; + local ubyte cur; + + result = u.val[0]; + if(result > 0x7f) { + cur = u.val[1]; + result = (result & 0x7f) | (uint)((cur & 0x7f) << 7); + if(cur > 0x7f) { + cur = u.val[2]; + result |= (uint)(cur & 0x7f) << 14; + if(cur > 0x7f) { + cur = u.val[3]; + result |= (uint)(cur & 0x7f) << 21; + if(cur > 0x7f) { + cur = u.val[4]; + result |= (uint)cur << 28; + } + } + } + } + + return result; +} + +typedef struct uleb128 uleb128p1; + +int uleb128p1_value(uleb128 &u) { + return (int)uleb128_value(u) - 1; +} + +string ULeb128Read(uleb128 &u) { + local string s; + s = SPrintf(s, "0x%X", uleb128_value(u)); + return s; +} + +// sleb128 +typedef struct { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if (val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + if(val > 0x7f) { + ubyte val ; + } + } + } + } +} sleb128 ; + +// get the actual uint value of the uleb128 +int sleb128_value(sleb128 &u) { + local int result; + local ubyte cur; + + result = u.val[0]; + if(result <= 0x7f) { + result = (result << 25) >> 25; + } else { + cur = u.val[1]; + result = (result & 0x7f) | ((uint)(cur & 0x7f) << 7); + if(cur <= 0x7f) { + result = (result << 18) >> 18; + } else { + cur = u.val[2]; + result |= (uint)(cur & 0x7f) << 14; + if(cur <= 0x7f) { + result = (result << 11) >> 11; + } else { + cur = u.val[3]; + result |= (uint)(cur & 0x7f) << 21; + if(cur <= 0x7f) { + result = (result << 4) >> 4; + } else { + cur = u.val[4]; + result |= (uint)cur << 28; + } + } + } + } + + return result; +} + +string SLeb128Read(sleb128 &u) { + local string s; + s = SPrintf(s, "%i", sleb128_value(u)); + return s; +} + +////////////////////////////////////////////////// +// encoded_value type +////////////////////////////////////////////////// + +typedef enum { + VALUE_BYTE = 0x00, + VALUE_SHORT = 0x02, + VALUE_CHAR = 0x03, + VALUE_INT = 0x04, + VALUE_LONG = 0x06, + VALUE_FLOAT = 0x10, + VALUE_DOUBLE = 0x11, + VALUE_STRING = 0x17, + VALUE_TYPE = 0x18, + VALUE_FIELD = 0x19, + VALUE_METHOD = 0x1a, + VALUE_ENUM = 0x1b, + VALUE_ARRAY = 0x1c, + VALUE_ANNOTATION = 0x1d, + VALUE_NULL = 0x1e, + VALUE_BOOLEAN = 0x1f +} VALUE; + +// variable-width integer used by encoded_value types +typedef struct (int size, VALUE type) { + local int s = size + 1; + local VALUE t = type; + local int i; + + for(i=0; i; + } +} EncodedValue ; + +string EncodedValueRead(EncodedValue &v) { + local string s = ""; + + switch(v.t) { + case VALUE_BYTE: + case VALUE_SHORT: + case VALUE_INT: + case VALUE_LONG: + case VALUE_FLOAT: + case VALUE_DOUBLE: + SPrintf(s, "0x%X", EncodedValueValue(v)); + break; + case VALUE_STRING: + s = StringIdRead(EncodedValueValue(v)); + break; + case VALUE_TYPE: + s = LongTypeIdRead(EncodedValueValue(v)); + break; + case VALUE_FIELD: + s = FieldIdRead(EncodedValueValue(v)); + break; + case VALUE_ENUM: + s = FieldIdRead(EncodedValueValue(v)); + break; + case VALUE_ARRAY: + case VALUE_ANNOTATION: + case VALUE_BOOLEAN: + case VALUE_NULL: + s = "NULL"; + break; + } + return s; +} + +int64 EncodedValueValue(EncodedValue &v) { + local int shift = 0; + local int i; + local int64 ret; + + if(v.s == 1) { + return v.val; + } + + for(i=0; i; + ubyte value_arg:3 ; + local string valstr = ""; + local string typestr = ""; + + switch (value_type) { + case VALUE_BYTE: + ubyte value ; + SPrintf(valstr, "0x%.2X", value); + typestr = "byte"; + break; + case VALUE_SHORT: + // value_arg has size-1, either 0 or 1 + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%i", EncodedValueValue(value)); + typestr = "short"; + break; + case VALUE_CHAR: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "'%c'", EncodedValueValue(value)); + typestr = "char"; + break; + case VALUE_INT: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%i", EncodedValueValue(value)); + typestr = "int"; + break; + case VALUE_LONG: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%li", EncodedValueValue(value)); + typestr = "long"; + break; + case VALUE_FLOAT: // XXX this doesn't work + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%f", EncodedValueValue(value)); + typestr = "float"; + break; + case VALUE_DOUBLE: + EncodedValue value(value_arg, value_type) ; + SPrintf(valstr, "%li", EncodedValueValue(value)); + typestr = "double"; + break; + case VALUE_STRING: + EncodedValue value(value_arg, value_type) ; + valstr = "\"" + GetStringById(EncodedValueValue(value)) + "\""; + typestr = "string"; + break; + case VALUE_TYPE: + EncodedValue value(value_arg, value_type) ; + valstr = GetLongTypeById(EncodedValueValue(value)); + typestr = "type"; + break; + case VALUE_FIELD: + EncodedValue value(value_arg, value_type) ; + valstr = GetFieldById(EncodedValueValue(value)); + typestr = "field"; + break; + case VALUE_METHOD: + EncodedValue value(value_arg, value_type) ; + valstr = GetMethodById(EncodedValueValue(value)); + typestr = "method"; + break; + case VALUE_ENUM: + EncodedValue value(value_arg, value_type) ; + valstr = GetFieldById(EncodedValueValue(value)); + typestr = "enum"; + break; + case VALUE_ARRAY: + struct encoded_array array ; + break; + case VALUE_ANNOTATION: + struct encoded_annotation annotation ; + break; + case VALUE_NULL: + // no additional bytes used by null + typestr = valstr = "NULL"; + break; + case VALUE_BOOLEAN: + // no additional bytes used by boolean + typestr = "boolean"; + if(value_arg == 0) { + valstr = "false"; + } else { + valstr = "true"; + } + break; + default: + Warning("Unknown type for encoded value 0x%X", value_type); + break; + } +} encoded_value ; + +string EncodedValueStructRead(encoded_value &v) { + return v.typestr + ": " + v.valstr; +} + +typedef struct { + uleb128 size ; + encoded_value values[uleb128_value(size)] ; +} encoded_array ; + +// show first 5 elements of the array +string EncodedArrayRead(encoded_array &a) { + local int count = 5; + local int dots = 1; + local int i; + + if(uleb128_value(a.size) < 5) { + count = uleb128_value(a.size); + dots = 0; + } + + string val = "["; + + for(i=0; i; + encoded_value value ; +} annotation_element ; + +string AnnotationElementRead(annotation_element &e) { + string name = GetStringById(uleb128_value(e.name_idx)); + return name + " = " + e.value.valstr; +} + +typedef struct { + uleb128 type_idx ; + uleb128 size ; + + if(uleb128_value(size) > 0) { + annotation_element elements[uleb128_value(size)] ; + } +} encoded_annotation ; + +string EncodedAnnotationRead(encoded_annotation &a) { + string s; + SPrintf(s, "%i annotations for %s", uleb128_value(a.size), GetLongTypeById(uleb128_value(a.type_idx))); + return s; +} + +////////////////////////////////////////////////// +// dex file header +////////////////////////////////////////////////// + +typedef struct { + dex_magic magic ; + uint checksum ; + SHA1 signature ; + uint file_size ; + uint header_size ; + uint endian_tag ; + + if(endian_tag != ENDIAN_CONSTANT) { + // XXX we don't handle big endian files + Warning("Invalid endian_tag %.8X, should be %.8X", endian_tag, ENDIAN_CONSTANT); + } + + uint link_size ; + uint link_off ; + uint map_off ; + uint string_ids_size ; + uint string_ids_off ; + uint type_ids_size ; + uint type_ids_off ; + uint proto_ids_size ; + uint proto_ids_off ; + uint field_ids_size ; + uint field_ids_off ; + uint method_ids_size ; + uint method_ids_off ; + uint class_defs_size ; + uint class_defs_off ; + uint data_size ; + uint data_off ; +} header_item; + +////////////////////////////////////////////////// +// odex file header +////////////////////////////////////////////////// + +typedef enum { + DEX_FLAG_VERIFIED = 0x1, + DEX_OPT_FLAG_BIG = 0x2, + DEX_OPT_FLAG_FIELDS = 0x4, + DEX_OPT_FLAG_INVOCATIONS = 0x8 +} DEX_OPT_FLAGS; + +typedef struct { + dex_magic magic ; + uint dex_offset ; + uint dex_length ; + uint deps_offset ; + uint deps_length ; + uint opt_offset ; + uint opt_length ; + DEX_OPT_FLAGS flags ; + uint checksum ; +} dexopt_header_item; + +string DexOptFlagsRead(DEX_OPT_FLAGS f) { + string ret = ""; + string flags = ""; + DEX_OPT_FLAGS i = 1; + + while(i <= DEX_OPT_FLAG_INVOCATIONS) { + if (f & i) { + flags += EnumToString(i) + " "; + } + i = i << 1; + } + + SPrintf(ret, "(0x%X) %s", f, flags); + return ret; +} + +////////////////////////////////////////////////// +// strings +////////////////////////////////////////////////// + +typedef struct { + uleb128 utf16_size ; + string data ; +} string_item; + +typedef struct { + uint string_data_off ; + + local int64 pos = FTell(); + FSeek(odexpad + string_data_off); + + string_item string_data ; + + FSeek(pos); +} string_id_item ; + +string StringDataReader(string_id_item &i) { + return i.string_data.data; +} + +typedef struct (int size) { + local int s = size; + string_id_item string_id[size] ; +} string_id_list ; + +string StringIDListRead(string_id_list &l) { + string s; + s = SPrintf(s, "%d strings", l.s); + return s; +} + +////////////////////////////////////////////////// +// type IDs +////////////////////////////////////////////////// + +typedef struct { + uint descriptor_idx ; +} type_id_item ; + +string TypeIDRead(type_id_item &i) { + return GetLongTypeDescriptor(GetStringById(i.descriptor_idx)); +} + +typedef struct (int size) { + local int s = size; + type_id_item type_id[size] ; +} type_id_list ; + +string TypeIDListRead(type_id_list &l) { + string s; + s = SPrintf(s, "%d types", l.s); + return s; +} + +////////////////////////////////////////////////// +// type list +////////////////////////////////////////////////// +typedef struct { + ushort type_idx ; +} type_item; + +typedef struct { + uint size ; + type_item list[size] ; +} type_item_list ; + +string TypeItemRead(type_item &t) { + return GetTypeById(t.type_idx); +} + +string TypeItemListRead(type_item_list &l) { + string s = ""; + string tmp; + int i; + + for(i = 0; i < l.size; i++) { + s += GetTypeById(l.list[i].type_idx); + if(i+1 < l.size) { + s += ", "; + } + } + return s; +} + +string GetLongTypeDescriptor(string descriptor) { + local string desc = ""; + local string post = ""; + local int i = 0; + local int len = Strlen(descriptor); + + // array descriptors + while(descriptor[i] == '[') { + post += "[]"; + i++; + + if(i >= len) return "ERROR"; + } + + if(descriptor[i] == 'L') { + // fully qualified class descriptors + i++; + while(i < len) { + if(descriptor[i] == '/') desc += "."; + else if(descriptor[i] == ';') break; + else desc += descriptor[i]; + i++; + } + } else { + // simple type descriptors + switch(descriptor[i]) { + case 'V': desc = "void"; break; + case 'Z': desc = "boolean"; break; + case 'B': desc = "byte"; break; + case 'S': desc = "short"; break; + case 'C': desc = "char"; break; + case 'I': desc = "int"; break; + case 'J': desc = "long"; break; + case 'F': desc = "float"; break; + case 'D': desc = "double"; break; + } + } + + return desc + post; +} + +////////////////////////////////////////////////// +// protoypes +////////////////////////////////////////////////// + +typedef struct { + uint shorty_idx ; + uint return_type_idx ; + uint parameters_off ; + + if(parameters_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + parameters_off); + + type_item_list parameters ; + + FSeek(pos); + } + +} proto_id_item ; + +string ProtoIDItemRead(proto_id_item &i) { + return GetPrototypeSignature(i); +} + +typedef struct (int size) { + local int s = size; + proto_id_item proto_id[size] ; +} proto_id_list ; + +string ProtoIDListRead(proto_id_list &l) { + string s; + s = SPrintf(s, "%d prototypes", l.s); + return s; +} + +string GetParameterListString(type_item_list &l) { + local string s = "("; + local string tmp; + local int i; + + for(i = 0; i < l.size; i++) { + s += GetLongTypeDescriptor(GetTypeById(l.list[i].type_idx)); + if(i+1 < l.size) { + s += ", "; + } + } + return s + ")"; +} + +string GetPrototypeSignature(proto_id_item &item) { + string ret = GetLongTypeDescriptor(GetTypeById(item.return_type_idx)); + string params = "()"; + if(exists(item.parameters)) { + params = GetParameterListString(item.parameters); + } + + return ret + " " + params; +} + +////////////////////////////////////////////////// +// fields +////////////////////////////////////////////////// + +typedef struct { + ushort class_idx ; + ushort type_idx ; + uint name_idx ; +} field_id_item ; + +string FieldIdItemRead(field_id_item &i) { + string type = GetLongTypeDescriptor(GetTypeById(i.type_idx)); + string class = GetLongTypeDescriptor(GetTypeById(i.class_idx)); + string name = GetStringById(i.name_idx); + + return type + " " + class + "." + name; +} + +typedef struct (int size) { + local int s = size; + field_id_item field_id[size] ; +} field_id_list ; + +string FieldIDListRead(field_id_list &l) { + string s; + s = SPrintf(s, "%d fields", l.s); + return s; +} + +////////////////////////////////////////////////// +// methods +////////////////////////////////////////////////// + +typedef struct { + ushort class_idx ; + ushort proto_idx ; + uint name_idx ; +} method_id_item ; + +string ProtoIdxRead(ushort p) { + string s; + SPrintf(s, "(0x%X) %s", p, GetPrototypeSignature(dex_proto_ids.proto_id[p])); + return s; +} + +string MethodIdItemRead(method_id_item &m) { + local string retval = GetLongTypeDescriptor(GetTypeById(dex_proto_ids.proto_id[m.proto_idx].return_type_idx)); + local string classname = GetLongTypeDescriptor(GetStringById(dex_type_ids.type_id[m.class_idx].descriptor_idx)); + local string methodname = GetStringById(m.name_idx); + local string params = "()"; + if(exists(dex_proto_ids.proto_id[m.proto_idx].parameters)) { + params = GetParameterListString(dex_proto_ids.proto_id[m.proto_idx].parameters); + } + return retval + " " + classname + "." + methodname + params; +} + +typedef struct (int size) { + local int s = size; + method_id_item method_id[size] ; +} method_id_list ; + +string MethodIDListRead(method_id_list &l) { + string s; + s = SPrintf(s, "%d methods", l.s); + return s; +} + +////////////////////////////////////////////////// +// annotations +////////////////////////////////////////////////// + +typedef struct { + uint field_idx ; + uint annotations_off; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_item field_annotations; + + FSeek(pos); + } +} field_annotation ; + +string FieldAnnotationRead(field_annotation &f) { + return GetFieldById(f.field_idx); +} + +typedef struct { + uint method_idx ; + uint annotations_off; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_item method_annotations; + + FSeek(pos); + } +} method_annotation ; + +string MethodAnnotationRead(method_annotation &m) { + return GetMethodById(m.method_idx); +} + +typedef struct { + uint method_idx ; + uint annotations_off; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_ref_list annotations_list; + + FSeek(pos); + } +} parameter_annotation ; + +string ParameterAnnotationRead(parameter_annotation &p) { + return GetParameterListString(dex_proto_ids.proto_id[dex_method_ids.method_id[p.method_idx].proto_idx].parameters); +} + +typedef enum { + VISIBILITY_BUILD = 0x0, + VISIBILITY_RUNTIME = 0x1, + VISIBILITY_SYSTEM = 0x2 +} VISIBILITY; + +typedef struct { + VISIBILITY visibility ; + encoded_annotation annotation ; +} annotation_item ; + +string AnnotationItemRead(annotation_item &i) { + return EncodedAnnotationRead(i.annotation); +} + +typedef struct { + uint annotation_off ; + + if(annotation_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotation_off); + + annotation_item item ; + + FSeek(pos); + } + +} annotation_off_item ; + +string AnnotationOffItemRead(annotation_off_item &i) { + if(exists(i.item)) { + return AnnotationItemRead(i.item); + } +} + +typedef struct { + uint size ; + + if(size > 0) { + annotation_off_item entries[size] ; + } +} annotation_set_item ; + +string AnnotationSetItemRead(annotation_set_item &i) { + local string s; + SPrintf(s, "%i annotation entries", i.size); + return s; +} + +typedef struct { + uint class_annotations_off ; + + if(class_annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + class_annotations_off); + + annotation_set_item class_annotations ; + + FSeek(pos); + } + uint fields_size ; + uint methods_size ; + uint parameters_size ; + + if(fields_size > 0) { + field_annotation field_annotations[fields_size] ; + } + + if(methods_size > 0) { + method_annotation method_annotations[methods_size] ; + } + + if(parameters_size > 0) { + parameter_annotation parameter_annotations[parameters_size] ; + } +} annotations_directory_item ; + +string AnnotationsDirectoryItemRead(annotations_directory_item &i) { + local string s; + local int classes = 0; + if(exists(i.class_annotations)) { + classes = i.class_annotations.size; + } + + SPrintf(s, "%i class annotations, %i field annotations, %i method annotations, %i parameter annotations", + classes, i.fields_size, i.methods_size, i.parameters_size); + return s; +} + +typedef struct { + uint annotations_off ; + + if(annotations_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + annotations_off); + + struct annotation_set_item item ; + + FSeek(pos); + } +} annotation_set_ref_item ; + +typedef struct { + uint size ; + + if(size > 0) { + annotation_set_ref_item list[size] ; + } +} annotation_set_ref_list; + +////////////////////////////////////////////////// +// classes +////////////////////////////////////////////////// + +// access flags. some of these mean different things for different items (class/field/method) +typedef enum { + ACC_PUBLIC = 0x1, + ACC_PRIVATE = 0x2, + ACC_PROTECTED = 0x4, + ACC_STATIC = 0x8, + ACC_FINAL = 0x10, + ACC_SYNCHRONIZED = 0x20, + ACC_VOLATILE = 0x40, // field + //ACC_BRIDGE = 0x40, // method + ACC_TRANSIENT = 0x80, // field + //ACC_VARARGS = 0x80, // method + ACC_NATIVE = 0x100, + ACC_INTERFACE = 0x200, + ACC_ABSTRACT = 0x400, + ACC_STRICT = 0x800, + ACC_SYNTHETIC = 0x1000, + ACC_ANNOTATION = 0x2000, + ACC_ENUM = 0x4000, + ACC_CONSTRUCTOR = 0x10000, + ACC_DECLARED_SYNCHRONIZED = 0x20000 +} ACCESS_FLAGS ; + +string AccessFlagsRead(ACCESS_FLAGS f) { + string ret = ""; + string flags = ""; + ACCESS_FLAGS i = 1; + + while(i <= ACC_DECLARED_SYNCHRONIZED) { + if (f & i) { + flags += EnumToString(i) + " "; + } + i = i << 1; + } + + SPrintf(ret, "(0x%X) %s", f, flags); + return ret; +} + +string AccessFlagsReadUleb(uleb128 &f) { + return AccessFlagsRead(uleb128_value(f)); +} + +typedef enum { + AF_CLASS, AF_FIELD, AF_METHOD +} AF_TYPE; + +string GetFriendlyAccessFlag(int flag, AF_TYPE type) { + switch (flag) { + case ACC_PUBLIC: return "public"; + case ACC_PRIVATE: return "private"; + case ACC_PROTECTED: return "protected"; + case ACC_STATIC: return "static"; + case ACC_FINAL: return "final"; + case ACC_SYNCHRONIZED: return "synchronized"; + case ACC_VOLATILE: + if(type == AF_FIELD) return "volatile"; + else return "bridge"; // 0x40 is 'bridge' for methods + case ACC_TRANSIENT: + if(type == AF_FIELD) return "transient"; + else return "varargs"; // 0x80 is 'varargs' for methods + case ACC_NATIVE: return "native"; + case ACC_INTERFACE: return "interface"; + case ACC_ABSTRACT: return "abstract"; + case ACC_STRICT: return "strict"; + case ACC_SYNTHETIC: return "synthetic"; + case ACC_ANNOTATION: return "annotation"; + case ACC_ENUM: return "enum"; + case ACC_CONSTRUCTOR: return "constructor"; + case ACC_DECLARED_SYNCHRONIZED: return "declared-synchronized"; + } + return "ERROR"; +} + +string GetFriendlyAccessFlags(ACCESS_FLAGS f, AF_TYPE type) { + string flags = ""; + ACCESS_FLAGS i = 1; + + while(i <= ACC_DECLARED_SYNCHRONIZED) { + if (f & i) { + flags += GetFriendlyAccessFlag(i, type) + " "; + } + i = i << 1; + } + + return flags; +} + +// encoded fields +typedef struct (int previd) { + local int p = previd; + + uleb128 field_idx_diff ; + uleb128 access_flags ; +} encoded_field ; + +string EncodedFieldRead(encoded_field &f) { + local int realid = f.p + uleb128_value(f.field_idx_diff); + return GetFriendlyAccessFlags(uleb128_value(f.access_flags), AF_FIELD) + GetFieldById(realid); +} + +typedef struct (int size) { + local int s = size; + local int i; + local int fieldid = 0; + + for(i=0; i; + fieldid = fieldid + uleb128_value(field.field_idx_diff); + } +} encoded_field_list ; + +string EncodedFieldListRead(encoded_field_list &l) { + local string s; + SPrintf(s, "%i fields", l.s); + return s; +} + +// encoded methods +typedef struct (int previd) { + local int p = previd; + + uleb128 method_idx_diff ; + uleb128 access_flags ; + uleb128 code_off ; + + if(uleb128_value(code_off) != 0) { + local int64 pos = FTell(); + FSeek(odexpad + uleb128_value(code_off)); + struct code_item code ; + FSeek(pos); + } +} encoded_method ; + +string EncodedMethodRead(encoded_method &m) { + local int realid = m.p + uleb128_value(m.method_idx_diff); + return GetFriendlyAccessFlags(uleb128_value(m.access_flags), AF_METHOD) + GetMethodById(realid); +} + +typedef struct (int size) { + local int s = size; + local int i; + local int methodid = 0; + + for(i=0; i; + methodid = methodid + uleb128_value(method.method_idx_diff); + } +} encoded_method_list ; + +string EncodedMethodListRead(encoded_method_list &l) { + local string s; + SPrintf(s, "%i methods", l.s); + return s; +} + +typedef struct { + uleb128 static_fields_size ; + uleb128 instance_fields_size ; + uleb128 direct_methods_size ; + uleb128 virtual_methods_size ; + + if(uleb128_value(static_fields_size) > 0) { + encoded_field_list static_fields(uleb128_value(static_fields_size)) ; + } + + if(uleb128_value(instance_fields_size) > 0) { + encoded_field_list instance_fields(uleb128_value(instance_fields_size)) ; + } + + if(uleb128_value(direct_methods_size) > 0) { + encoded_method_list direct_methods(uleb128_value(direct_methods_size)) ; + } + + if(uleb128_value(virtual_methods_size) > 0) { + encoded_method_list virtual_methods(uleb128_value(virtual_methods_size)) ; + } +} class_data_item ; + +string ClassDataItemRead(class_data_item &i) { + local string s; + SPrintf(s, "%i static fields, %i instance fields, %i direct methods, %i virtual methods", + uleb128_value(i.static_fields_size), uleb128_value(i.instance_fields_size), + uleb128_value(i.direct_methods_size), uleb128_value(i.virtual_methods_size)); + return s; +} + +typedef struct { + local int64 pos; + + uint class_idx ; + ACCESS_FLAGS access_flags ; + uint superclass_idx ; + + uint interfaces_off ; + if(interfaces_off != 0) { + pos = FTell(); + FSeek(odexpad + interfaces_off); + type_item_list interfaces ; + FSeek(pos); + } + + uint source_file_idx ; + + uint annotations_off ; + if(annotations_off != 0) { + pos = FTell(); + FSeek(odexpad + annotations_off); + annotations_directory_item annotations ; + FSeek(pos); + } + + uint class_data_off ; + if(class_data_off != 0) { + pos = FTell(); + FSeek(odexpad + class_data_off); + class_data_item class_data ; + FSeek(pos); + } + + uint static_values_off ; + if(static_values_off != 0) { + pos = FTell(); + FSeek(odexpad + static_values_off); + struct encoded_array_item static_values ; + FSeek(pos); + } +} class_def_item ; + +string ClassDefItemRead(class_def_item &i) { + local string classname = GetLongTypeById(i.class_idx); + local string flags = GetFriendlyAccessFlags(i.access_flags, AF_CLASS); + return flags + classname; +} + +string InterfacesRead(type_item_list &l) { + string s = ""; + int i; + + for(i = 0; i < l.size; i++) { + s += GetLongTypeDescriptor(GetTypeById(l.list[i].type_idx)); + if(i+1 < l.size) { + s += ", "; + } + } + return s; +} + +typedef struct (int size) { + local int s = size; + class_def_item class_def[size] ; +} class_def_item_list ; + +string ClassDefItemListRead(class_def_item_list &l) { + string s; + s = SPrintf(s, "%d classes", l.s); + return s; +} + +typedef struct { + uint start_addr ; + ushort insn_count ; + ushort handler_off ; +} try_item ; + +typedef struct { + sleb128 size ; + + local int s = sleb128_value(size); + local int numhandlers = 0; + + if(s != 0) { + numhandlers = Abs(s); + struct encoded_type_addr_pair handlers[numhandlers] ; + } + + if(s <= 0) { + uleb128 catch_all_addr ; + numhandlers++; + } +} encoded_catch_handler ; + +string EncodedCatchHandlerRead(encoded_catch_handler &h) { + local string s; + SPrintf(s, "%i handlers", h.numhandlers); + return s; +} + +typedef struct { + uleb128 size ; + encoded_catch_handler list[uleb128_value(size)] ; +} encoded_catch_handler_list ; + +string EncodedCatchHandlerListRead(encoded_catch_handler_list &l) { + local string s; + SPrintf(s, "%i handler lists", uleb128_value(l.size)); + return s; +} + +typedef struct { + ushort registers_size ; + ushort ins_size ; + ushort outs_size ; + ushort tries_size ; + uint debug_info_off ; + + if(debug_info_off != 0) { + local int64 pos = FTell(); + FSeek(odexpad + debug_info_off); + + struct debug_info_item debug_info ; + FSeek(pos); + } + + uint insns_size ; + if(insns_size != 0) { + ushort insns[insns_size] ; + } + + if(tries_size != 0) { + if (insns_size & 1 == 1) { + ushort padding ; + } + + try_item tries[tries_size] ; + encoded_catch_handler_list handlers ; + } +} code_item ; + +string CodeItemRead(code_item &i) { + local string s; + SPrintf(s, "%i registers, %i in arguments, %i out arguments, %i tries, %i instructions", + i.registers_size, i.ins_size, i.outs_size, i.tries_size, i.insns_size); + return s; +} + +typedef struct { + uleb128 type_idx ; + uleb128 addr ; +} encoded_type_addr_pair ; + +string EncodedTypeAddrPairRead(encoded_type_addr_pair &p) { + string s; + SPrintf(s, "%s at 0x%X", GetLongTypeById(uleb128_value(p.type_idx)), uleb128_value(p.addr)); + return s; +} + +typedef struct { + encoded_array value ; +} encoded_array_item ; + +string EncodedArrayItemRead(encoded_array_item &i) { + local string s; + SPrintf(s, "%i items: %s", uleb128_value(i.value.size), EncodedArrayRead(i.value)); + return s; +} + +enum TYPE_CODES { + TYPE_HEADER_ITEM = 0x0000, + TYPE_STRING_ID_ITEM = 0x0001, + TYPE_TYPE_ID_ITEM = 0x0002, + TYPE_PROTO_ID_ITEM = 0x0003, + TYPE_FIELD_ID_ITEM = 0x0004, + TYPE_METHOD_ID_ITEM = 0x0005, + TYPE_CLASS_DEF_ITEM = 0x0006, + + TYPE_MAP_LIST = 0x1000, + TYPE_TYPE_LIST = 0x1001, + TYPE_ANNOTATION_SET_REF_LIST = 0x1002, + TYPE_ANNOTATION_SET_ITEM = 0x1003, + + TYPE_CLASS_DATA_ITEM = 0x2000, + TYPE_CODE_ITEM = 0x2001, + TYPE_STRING_DATA_ITEM = 0x2002, + TYPE_DEBUG_INFO_ITEM = 0x2003, + TYPE_ANNOTATION_ITEM = 0x2004, + TYPE_ENCODED_ARRAY_ITEM = 0x2005, + TYPE_ANNOTATIONS_DIRECTORY_ITEM = 0x2006 +}; + +////////////////////////////////////////////////// +// debug info +////////////////////////////////////////////////// + +typedef enum { + DBG_END_SEQUENCE = 0x00, + DBG_ADVANCE_PC = 0x01, + DBG_ADVANCE_LINE = 0x02, + DBG_START_LOCAL = 0x03, + DBG_START_LOCAL_EXTENDED = 0x04, + DBG_END_LOCAL = 0x05, + DBG_RESTART_LOCAL = 0x06, + DBG_SET_PROLOGUE_END = 0x07, + DBG_SET_EPILOGUE_BEGIN = 0x08, + DBG_SET_FILE = 0x09 +} DBG_OPCODE; + +typedef struct { + DBG_OPCODE opcode ; + local string args = ""; + + switch (opcode) { + case DBG_END_SEQUENCE: + break; + case DBG_ADVANCE_PC: + uleb128 addr_diff ; + SPrintf(args, "%i", uleb128_value(addr_diff)); + break; + case DBG_ADVANCE_LINE: + sleb128 line_diff ; + SPrintf(args, "%i", sleb128_value(line_diff)); + break; + case DBG_START_LOCAL: + uleb128 register_num ; + uleb128p1 name_idx ; + uleb128p1 type_idx ; + SPrintf(args, "%i, %s, %s", uleb128_value(register_num), StringIdReadUlebp1(name_idx), + LongTypeIdReadUlebp1(type_idx)); + break; + case DBG_START_LOCAL_EXTENDED: + uleb128 register_num ; + uleb128p1 name_idx ; + uleb128p1 type_idx ; + uleb128p1 sig_idx ; + SPrintf(args, "%i, %s, %s, %s", uleb128_value(register_num), StringIdReadUlebp1(name_idx), + LongTypeIdReadUlebp1(type_idx), StringIdReadUlebp1(sig_idx)); + break; + case DBG_END_LOCAL: + uleb128 register_num ; + SPrintf(args, "%i", uleb128_value(register_num)); + break; + case DBG_RESTART_LOCAL: + uleb128 register_num ; + SPrintf(args, "%i", uleb128_value(register_num)); + break; + case DBG_SET_PROLOGUE_END: + case DBG_SET_EPILOGUE_BEGIN: + break; + case DBG_SET_FILE: + uleb128p1 name_idx ; + SPrintf(args, "%s", StringIdReadUlebp1(name_idx)); + } +} debug_opcode ; + +#define DBG_FIRST_SPECIAL 0x0a +#define DBG_LINE_BASE -4 +#define DBG_LINE_RANGE 15 + +string DebugOpcodeRead(debug_opcode &opcode) { + local string s; + if(opcode.opcode >= DBG_FIRST_SPECIAL) { + local ubyte adjusted = opcode.opcode - DBG_FIRST_SPECIAL; + SPrintf(s, "Special opcode: line + %i, address + %i", DBG_LINE_BASE + (adjusted % DBG_LINE_RANGE), (adjusted / DBG_LINE_RANGE)); + } else { + s = EnumToString(opcode.opcode); + } + + if(opcode.args != "") { + s += " (" + opcode.args + ")"; + } + + return s; +} + +typedef struct { + uleb128 line_start ; + uleb128 parameters_size ; + if(uleb128_value(parameters_size) > 0) { + uleb128p1 parameter_names[uleb128_value(parameters_size)] ; // actually uleb128p1 + } + + do { + debug_opcode opcode ; + } while (opcode.opcode != DBG_END_SEQUENCE); +} debug_info_item; + +////////////////////////////////////////////////// +// map list +////////////////////////////////////////////////// +typedef struct { + TYPE_CODES type; + ushort unused; + uint size; + uint offset; +} map_item ; + +string MapItemRead(map_item &m) { + string s; + SPrintf(s, "%s", EnumToString(m.type)); + return s; +} + +typedef struct { + uint size; + map_item list[size]; +} map_list_type ; + +string MapListTypeRead(map_list_type &t) { + local string s; + SPrintf(s, "%i items", t.size); + return s; +} + +////////////////////////////////////////////////// +// utility functions for reading various strings +// note: strings are stored in a format called MUTF-8, and its +// possible they won't always display correctly in the 010 UI +////////////////////////////////////////////////// + +// read a value from the string table +string StringIdRead(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + local string s; + SPrintf(s, "(0x%.X) \"%s\"", id, GetStringById(id)); + return s; +} + +string StringIdReadUleb(uleb128 &id) { + return StringIdRead(uleb128_value(id)); +} + +string StringIdReadUlebp1(uleb128p1 &id) { + return StringIdRead(uleb128p1_value(id)); +} + +// read a value from the type table, return short form +string TypeIdRead(int id) { + return GetIdAndNameString(id, GetTypeById(id)); +} + +// read a value from the type table, return the long form +string LongTypeIdRead(int id) { + return GetIdAndNameString(id, GetLongTypeById(id)); +} + +string LongTypeIdReadUleb(uleb128 &id) { + return LongTypeIdRead(uleb128_value(id)); +} + +string LongTypeIdReadUlebp1(uleb128p1 &id) { + return LongTypeIdRead(uleb128p1_value(id)); +} + +string FieldIdRead(int id) { + return GetIdAndNameString(id, GetFieldById(id)); +} + +string MethodIdRead(int id) { + return GetIdAndNameString(id, GetMethodById(id)); +} + +string GetIdAndNameString(int id, string name) { + local string s; + SPrintf(s, "(0x%X) %s", id, name); + return s; +} + +// read a string from the string table +string GetStringById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_string_ids.string_id[id])) { + return dex_string_ids.string_id[id].string_data.data; + } else { + return "*** NO STRING"; + } +} + +string GetTypeById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_type_ids.type_id[id])) { + return GetStringById(dex_type_ids.type_id[id].descriptor_idx); + } else { + return "*** NO TYPE"; + } +} + +string GetLongTypeById(int id) { + return GetLongTypeDescriptor(GetTypeById(id)); +} + +string GetMethodById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_method_ids.method_id[id])) { + return MethodIdItemRead(dex_method_ids.method_id[id]); + } else { + return "*** NO METHOD"; + } +} + +string GetFieldById(int id) { + if(id == NO_INDEX) { + return "NO_INDEX"; + } + + if(exists(dex_field_ids.field_id[id])) { + return FieldIdItemRead(dex_field_ids.field_id[id]); + } else { + return "*** NO FIELD"; + } +} + +////////////////////////////////////////////////// +// dexopt stuff +////////////////////////////////////////////////// + +typedef enum { + DEX_CHUNK_CLASS_LOOKUP = 0x434c4b50, + DEX_CHUNK_REGISTER_MAPS = 0x524d4150, + DEX_CHUNK_END = 0x41454e44 +} DEX_CHUNK_TYPE; + +typedef struct { + DEX_CHUNK_TYPE type ; + uint size ; + local int realsize = (size + 7) & ~7; + + + if(type == DEX_CHUNK_CLASS_LOOKUP) { + struct dex_class_lookup class_lookup_table ; + } else if (type == DEX_CHUNK_REGISTER_MAPS) { + ubyte chunkbytes[realsize]; + } else if (type == DEX_CHUNK_END) { + //ubyte chunkbytes[realsize]; + } else { + Warning("Unknown chunk type 0x%X", type); + return; + } +} dexopt_opt_chunk ; + +typedef struct { + local int count = 0; + do { + dexopt_opt_chunk chunk; + count++; + } while(chunk.type != DEX_CHUNK_END); +} dexopt_opt_table ; + +string DexoptOptTableRead(dexopt_opt_table &t) { + local string s; + SPrintf(s, "%i items", t.count); + return s; +} + +string DexOptChunkRead(dexopt_opt_chunk &c) { + local string s; + SPrintf(s, "%s chunk: %i bytes", EnumToString(c.type), c.size); + return s; +} + +typedef struct { + uint class_descriptor_hash ; + int class_descriptor_offset ; + int class_definition_offset ; +} dex_class_lookup_entry ; + +string DexClassLookupEntryRead(dex_class_lookup_entry &e) { + local string s; + SPrintf(s, "0x%X: (descriptor 0x%X, definition 0x%X)", e.class_descriptor_hash, e.class_descriptor_offset, e.class_definition_offset); + return s; +} + +typedef struct { + int size ; + int num_entries ; + + if(num_entries > 0) { + dex_class_lookup_entry table[num_entries] ; + } +} dex_class_lookup; + +////////////////////////////////////////////////// +// main stuff +////////////////////////////////////////////////// + +// first check file type - dex files start with 'dex', odex files start with 'dey' +local int odex = 0; +local char tmp[3]; +ReadBytes(tmp, 0, 3); +FSeek(0); + +if(!Strcmp(tmp, "dey")) { + odex = 1; +} + +// dexopt files start with a dexopt header +if(odex) { + dexopt_header_item dexopt_header ; + odexpad = dexopt_header.dex_offset; + FSeek(odexpad); +} + +// main dex header and structs +header_item dex_header ; +string_id_list dex_string_ids(dex_header.string_ids_size) ; +type_id_list dex_type_ids(dex_header.type_ids_size) ; +proto_id_list dex_proto_ids(dex_header.proto_ids_size) ; +field_id_list dex_field_ids(dex_header.field_ids_size) ; +method_id_list dex_method_ids(dex_header.method_ids_size) ; +class_def_item_list dex_class_defs(dex_header.class_defs_size) ; + +// map list, we don't really do anything with it though +if(dex_header.map_off != 0) { + FSeek(odexpad + dex_header.map_off); + map_list_type dex_map_list ; +} + +if(odex) { + if(dexopt_header.deps_offset != 0) { + FSeek(dexopt_header.deps_offset); + ubyte dexopt_deps[dexopt_header.deps_length] ; + } + + if(dexopt_header.opt_offset != 0) { + FSeek(dexopt_header.opt_offset); + dexopt_opt_table opt_table ; + } +} \ No newline at end of file diff --git a/cparser/DMPTemplate.bt b/cparser/DMPTemplate.bt new file mode 100644 index 0000000..9ed65bb --- /dev/null +++ b/cparser/DMPTemplate.bt @@ -0,0 +1,82 @@ +//-------------------------------------- +//--- 010 Editor v2.0.2 Binary Template +// +// File: DMPTemplate.bt +// Author: +// Revision: 1.0 - 20060320 +// Purpose: This template merely serves as documentation of the +// memory dump format used by Microsoft's debuggers and +// the NT kernel crashdump facility. Detailed and +// authorative information about a DMP file can be +// obtained by processing the file with the "dumpchk" +// utility which ships whith Microsoft's free debugging +// tools package. +//-------------------------------------- + + +typedef enum { + FULL = 1, + KERNEL, + SMALL +} e_DumpType; + + +typedef struct { + uint32 BasePage ; + uint32 PageCount ; +} _PHYSICAL_MEMORY_RUN32; + + +typedef struct { + uint32 NumberOfRuns; + uint32 NumberOfPages ; + _PHYSICAL_MEMORY_RUN32 Run[NumberOfRuns]; +} _PHYSICAL_MEMORY_DESCRIPTOR32; + + +typedef struct { + int32 ExceptionCode ; + uint32 ExceptionFlags; + uint32 ExceptionRecord; + uint32 ExceptionAddress ; + uint32 NumberParameters; + uint32 ExceptionInformation[15] ; +} _EXCEPTION_RECORD32; + + +FSeek(0); + +char Signature[4]; +char ValidDump[4]; +uint32 MajorVersion; +uint32 MinorVersion; +uint32 DirectoryTableBase ; +uint32 PfnDataBase ; +uint32 PsLoadedModuleList ; +uint32 PsActiveProcessHead ; +uint32 MachineImageType ; +uint32 NumberProcessors; +uint32 BugCheckCode ; +uint32 BugCheckParameter[4] ; +char VersionUser[32]; +uchar PaeEnabled; +uchar KdSecondaryVersion; +uchar Spare3[2]; +uint32 KdDebuggerDataBlock ; +_PHYSICAL_MEMORY_DESCRIPTOR32 PhysicalMemoryBlock; +FSeek(800); +uchar ContextRecord[1200]; +_EXCEPTION_RECORD32 Exception; +char Comment[128]; +uchar _reserved0[1768]; +e_DumpType DumpType; +uint32 MiniDumpFields; +uint32 SecondaryDataState; +uint32 ProductType; +uint32 SuiteMask; +uint32 WriterStatus; +int64 RequiredDumpSpace; +uchar _reserved2[16]; +FILETIME SystemUpTime; +FILETIME SystemTime; +uchar _reserved3[56]; diff --git a/cparser/EDIDTemplate.bt b/cparser/EDIDTemplate.bt new file mode 100644 index 0000000..59c44fb --- /dev/null +++ b/cparser/EDIDTemplate.bt @@ -0,0 +1,730 @@ +//-------------------------------------- +//--- 010 Editor v3.2.2 Binary Template +// +// File: EDIDTemplate.bt +// Author: Rafael Vuijk +// Revision: 2012-03-02 +// Purpose: EDID structure parser +//-------------------------------------- +// +// NOTE: This template uses variable-size/unoptimized structure arrays. +// Information source: https://en.wikipedia.org/wiki/Extended_display_identification_data +// Modeline calculator: http://www.epanorama.net/faq/vga2rgb/calc.html +// +//-------------------------------------- + +typedef uint16 EISAId ; + +string EISAIdToString(EISAId x) +{ + uint16 sw = SwapBytes(x); + string s; + SPrintf(s, "%c%c%c", '@' + (sw>>10 & 0x1F), '@' + (sw>>5 & 0x1F), '@' + (sw>>0 & 0x1F)); + return s; +} + +void StringToEISAId(EISAId &x, string s) +{ + char c[3]; + SScan(s, "%c%c%c", c[0], c[1], c2[2]); + x = (c[0] - '@')<<10 | (c[1] - '@')<<5 | (c[2] - '@')<<0; + x = SwapBytes(x); +} + +//-------------------------------------- + +typedef struct +{ + ubyte x_resolution; + ubyte vFrequency : 6; + ubyte pixelRatio : 2; +} Timing ; + +string TimingToString(Timing &t) +{ + if (t.x_resolution == 1 && t.vFrequency == 1 && t.pixelRatio == 0) return "-"; + int x = (t.x_resolution + 31) * 8; + int y; + switch (t.pixelRatio) + { + case 0: y = x*10/16; break; + case 1: y = x*3/4; break; + case 2: y = x*4/5; break; + case 3: y = x*9/16; break; + } + string s; + SPrintf(s, "%ux%u, %uHz", x, y, t.vFrequency + 60); + return s; +} + +//-------------------------------------- + +enum DescriptorType +{ + TIMINGS = 0xFA, // Additional standard timing identifiers. 6- 2-byte descriptors, padded with 0A. + WHITE_POINT = 0xFB, // Additional white point data. 2- 5-byte descriptors, padded with 0A 20 20. + MONITOR_NAME = 0xFC, // Monitor name (text) + RANGE_LIMITS = 0xFD, // Monitor range limits. 6- or 13-byte binary descriptor. + UNSPECIFIED_TEXT = 0xFE, // Unspecified text (text) + SERIAL_NUMBER = 0xFF, // Monitor serial number (text) +}; + +//-------------------------------------- + +enum FormatCode +{ + RESERVED = 0, + LPCM = 1, + AC_3 = 2, + MPEG1 = 3, + MP3 = 4, + MPEG2 = 5, + AAC = 6, + DTS = 7, + ATRAC = 8, + SACD = 9, + DD_PLUS = 10, + DTS_HD = 11, + MLP_TRUEHD = 12, + DST = 13, + WMA_PRO = 14, + RESERVED2 = 15, +}; + +//-------------------------------------- + +enum BlockType +{ + AUDIO = 1, + VIDEO = 2, + VENDOR_SPECIFIC = 3, + SPEAKER = 4, +}; + +//-------------------------------------- + +enum SVDIndex +{ + _DMT0659 = 1, // 4:3 640x480p @ 59.94/60Hz + _480p = 2, // 4:3 720x480p @ 59.94/60Hz + _480pH = 3, // 16:9 720x480p @ 59.94/60Hz + _720p = 4, // 16:9 1280x720p @ 59.94/60Hz + _1080i = 5, // 16:9 1920x1080i @ 59.94/60Hz + _480i = 6, // 4:3 720(1440)x480i @ 59.94/60Hz + _480iH = 7, // 16:9 720(1440)x480i @ 59.94/60Hz + _240p = 8, // 4:3 720(1440)x240p @ 59.94/60Hz + _240pH = 9, // 16:9 720(1440)x240p @ 59.94/60Hz + _480i4x = 10, // 4:3 (2880)x480i @ 59.94/60Hz + _480i4xH = 11, // 16:9 (2880)x480i @ 59.94/60Hz + _240p4x = 12, // 4:3 (2880)x240p @ 59.94/60Hz + _240p4xH = 13, // 16:9 (2880)x240p @ 59.94/60Hz + _480p2x = 14, // 4:3 1440x480p @ 59.94/60Hz + _480p2xH = 15, // 16:9 1440x480p @ 59.94/60Hz + _1080p = 16, // 16:9 1920x1080p @ 59.94/60Hz + _576p = 17, // 4:3 720x576p @ 50Hz + _576pH = 18, // 16:9 720x576p @ 50Hz + _720p50 = 19, // 16:9 1280x720p @ 50Hz + _1080i25 = 20, // 16:9 1920x1080i @ 50Hz* + _576i = 21, // 4:3 720(1440)x576i @ 50Hz + _576iH = 22, // 16:9 720(1440)x576i @ 50Hz + _288p = 23, // 4:3 720(1440)x288p @ 50Hz + _288pH = 24, // 16:9 720(1440)x288p @ 50Hz + _576i4x = 25, // 4:3 (2880)x576i @ 50Hz + _576i4xH = 26, // 16:9 (2880)x576i @ 50Hz + _288p4x = 27, // 4:3 (2880)x288p @ 50Hz + _288p4xH = 28, // 16:9 (2880)x288p @ 50Hz + _576p2x = 29, // 4:3 1440x576p @ 50Hz + _576p2xH = 30, // 16:9 1440x576p @ 50Hz + _1080p50 = 31, // 16:9 1920x1080p @ 50Hz + _1080p24 = 32, // 16:9 1920x1080p @ 23.98/24Hz + _1080p25 = 33, // 16:9 1920x1080p @ 25Hz + _1080p30 = 34, // 16:9 1920x1080p @ 29.97/30Hz + _480p4x = 35, // 4:3 (2880)x480p @ 59.94/60Hz + _480p4xH = 36, // 16:9 (2880)x480p @ 59.94/60Hz + _576p4x = 37, // 4:3 (2880)x576p @ 50Hz + _576p4xH = 38, // 16:9 (2880)x576p @ 50Hz + _1080i25b = 39, // 16:9 1920x1080i(1250 Total) @ 50Hz* + _1080i50 = 40, // 16:9 1920x1080i @ 100Hz + _720p100 = 41, // 16:9 1280x720p @ 100Hz + _576p100 = 42, // 4:3 720x576p @ 100Hz + _576p100H = 43, // 16:9 720x576p @ 100Hz + _576i50 = 44, // 4:3 720(1440)x576i @ 100Hz + _576i50H = 45, // 16:9 720(1440)x576i @ 100Hz + _1080i60 = 46, // 16:9 1920x1080i @ 119.88/120Hz + _720p120 = 47, // 16:9 1280x720p @ 119.88/120Hz + _480p119 = 48, // 4:3 720x480p @ 119.88/120Hz + _480p119H = 49, // 16:9 720x480p @ 119.88/120Hz + _480i59 = 50, // 4:3 720(1440)x480i @ 119.88/120Hz + _480i59H = 51, // 16:9 720(1440)x480i @ 119.88/120Hz + _576p200 = 52, // 4:3 720x576p @ 200Hz + _576p200H = 53, // 16:9 720x576p @ 200Hz + _576i100 = 54, // 4:3 720(1440)x576i @ 200Hz + _576i100H = 55, // 16:9 720(1440)x576i @ 200Hz + _480p239 = 56, // 4:3 720x480p @ 239.76/240Hz + _480p239H = 57, // 16:9 720x480p @ 239.76/240Hz + _480i119 = 58, // 4:3 720(1440)x480i @ 239.76/240Hz + _480i119H = 59, // 16:9 720(1440)x480i @ 239.76/240Hz + _720p24 = 60, // 16:9 1280x720p @ 23.98/24Hz + _720p25 = 61, // 16:9 1280x720p @ 25Hz + _720p30 = 62, // 16:9 1280x720p @ 29.97/30Hz + _1080p120 = 63, // 16:9 1920x1080p @ 119.88/120Hz +}; + +typedef struct +{ + SVDIndex index : 7 ; + ubyte native : 1 ; +} SVD ; + +string SVDToString(SVD &svd) +{ + string s; + SPrintf(s, "%s%s (%u)", (svd.native ? "*" : ""), EnumToString(svd.index), svd.index); + return s; +} + +//-------------------------------------- + +string SPAToString(uint16 spa) +{ + string s; + SPrintf(s, "%u.%u.%u.%u", spa>>4&15, spa>>0&15, spa>>12&15, spa>>8&15); + return s; +} + +//-------------------------------------- + +string TDMSFreqToString(ubyte f) +{ + string s; + SPrintf(s, "%u MHz", (uint)f * 5); + return s; +} + +//-------------------------------------- + +string PixelClockToString(uint16 f) +{ + string s; + SPrintf(s, "%.2lf MHz", (double)f / 100); + return s; +} + +void StringToPixelClock(uint16 &f, string s) +{ + f = Atof(s) * 100; +} + +//-------------------------------------- + +typedef ubyte PixelRate ; + +string PixelRateToString(PixelRate f) +{ + string s; + SPrintf(s, "%u MHz", (uint)f * 10); + return s; +} + +void StringToPixelRate(PixelRate &f, string s) +{ + f = Atof(s) / 10; +} + +//-------------------------------------- + +typedef ubyte BitRate ; + +string BitRateToString(BitRate b) +{ + string s; + SPrintf(s, "%u kHz", (uint)b * 8); + return s; +} + +void StringToBitRate(BitRate &b, string s) +{ + b = Atof(s) / 8; +} + +//-------------------------------------- + +typedef ubyte Latency ; + +string LatencyToString(Latency l) +{ + if (l == 0) return "-"; + string s; + SPrintf(s, "%u ms", ((uint)l - 1) * 2); + return s; +} + +void StringToLatency(Latency &l, string s) +{ + if (s == "-") l = 0; else l = (uint)(Atof(s) / 2) + 1; +} + +//-------------------------------------- + +typedef struct +{ + ubyte size : 5 ; + BlockType typeTag : 3 ; + +// local int64 dataStart = FTell(); + switch (typeTag) + { + case AUDIO: + { + ubyte channelCount : 3 ; + FormatCode formatCode : 4 ; + ubyte reserved1 : 1; + struct SampleRates + { + ubyte _32kHz : 1; + ubyte _44kHz : 1; + ubyte _48kHz : 1; + ubyte _88kHz : 1; + ubyte _96kHz : 1; + ubyte _176kHz : 1; + ubyte _192kHz : 1; + ubyte reserved : 1; + } sampleRates ; + if (formatCode == 1) // LPCM + { + ubyte _16bits : 1; + ubyte _20bits : 1; + ubyte _24bits : 1; + ubyte reserved : 5; + } + else + { + BitRate bitrate; + } + break; + } + + case VIDEO: + { + SVD svds[size] ; + break; + } + + case VENDOR_SPECIFIC: + { + ubyte oui[3] ; + uint16 spa ; + if (size >= 3) + { + ubyte DVI_Dual : 1 ; + ubyte reserved : 1; + ubyte reserved : 1; + ubyte dc_Y444 : 1 ; + ubyte dc_30bit : 1 ; + ubyte dc_36bit : 1 ; + ubyte dc_48bit : 1 ; + ubyte supports_AI : 1 ; + } + if (size >= 4) + ubyte max_TMDS_Frequency ; + if (size >= 5) + { + ubyte reserved : 6; + ubyte i_latency_fields : 1 ; + ubyte latency_fields : 1 ; + if (latency_fields) + { + Latency videoLatency ; + Latency audioLatency ; + } + if (i_latency_fields) + { + Latency interlacedVideoLatency ; + Latency interlacedAudioLatency ; + } + } + break; + } + + case SPEAKER: + { + ubyte frontLeftRight : 1 ; + ubyte LFE : 1 ; + ubyte frontCenter : 1 ; + ubyte rearLeftRight : 1 ; + ubyte rearCenter : 1 ; + ubyte frontLeftRightCenter : 1 ; + ubyte rearLeftRightCenter : 1 ; + ubyte reserved : 1; + ubyte reserved[2]; + break; + } + } // switch + +// local int64 dataEnd = FTell(); +// Printf("block size: %u %lu\n", size, dataEnd - dataStart); + +/* Assert(dataEnd - dataStart <= size, "Data block size error"); + if (dataEnd - dataStart < size) + { + ubyte extraData[size - (dataEnd - dataStart)]; + }*/ +} DataBlock ; + +int DataBlockSize(DataBlock &b) +{ + return (ReadUByte(startof(b)) & 0x1F); +} + +//-------------------------------------- + +typedef struct +{ + uint16 pixelClock ; + + ubyte hActive_lsb ; + ubyte hBlanking_lsb ; + ubyte hBlanking_msb : 4 ; + ubyte hActive_msb : 4 ; + ubyte vActive_lsb ; + ubyte vBlanking_lsb ; + ubyte vBlanking_msb : 4 ; + ubyte vActive_msb : 4 ; + ubyte hSyncOffset_lsb ; + ubyte hSync_lsb ; + ubyte vSync_lsb : 4 ; + ubyte vSyncOffset_lsb : 4 ; + ubyte vSync_msb : 2 ; + ubyte vSyncOffset_msb : 2 ; + ubyte hSync_msb : 2 ; + ubyte hSyncOffset_msb : 2 ; + ubyte hSize_lsb ; + ubyte vSize_lsb ; + ubyte vSize_msb : 4 ; + ubyte hSize_msb : 4 ; + ubyte hBorder ; + ubyte vBorder ; + + ubyte _f0 : 1 ; + ubyte _f1 : 1 ; + ubyte _f2 : 1 ; + ubyte _f34 : 2 ; + ubyte _f56 : 2 ; + ubyte interlaced : 1 ; + + //if (_f34 >> 1 & 1) Printf("Digital sync: "); else Printf("Analog sync: "); + //if (_f34 >> 0 & 1) Printf("Bipolar/separate\n"); else Printf("Composite\n"); +} ModeLine ; + +string ModeLineToString(ModeLine &n) +{ + uint hActive = (uint)n.hActive_msb<<8 | n.hActive_lsb; + uint hSyncOffset = (uint)n.hSyncOffset_msb<<8 | n.hSyncOffset_lsb; + uint hSync = (uint)n.hSync_msb<<8 | n.hSync_lsb; + uint hBlanking = (uint)n.hBlanking_msb<<8 | n.hBlanking_lsb; + + uint vActive = (uint)n.vActive_msb<<8 | n.vActive_lsb; + uint vSyncOffset = (uint)n.vSyncOffset_msb<<8 | n.vSyncOffset_lsb; + uint vSync = (uint)n.vSync_msb<<8 | n.vSync_lsb; + uint vBlanking = (uint)n.vBlanking_msb<<8 | n.vBlanking_lsb; + + uint im = n.interlaced ? 2 : 1; + string s; + SPrintf(s, "Modeline \"%ux%u\" %.2lf %4u %4u %4u %4u %4u %4u %4u %4u %chsync %cvsync %s ; %u %u", // relative to absolute + hActive, vActive*im, (double)n.pixelClock / 100, + hActive, hActive + hSyncOffset, hActive + hSyncOffset + hSync, hActive + hBlanking, + vActive*im, (vActive + vSyncOffset)*im, (vActive + vSyncOffset + vSync)*im, (vActive + vBlanking)*im, + n._f1 ? '+' : '-', n._f2 ? '+' : '-', + n.interlaced ? "Interlace" : "", + n.hBorder, n.vBorder + ); + return s; +} + +void StringToModeLine(ModeLine &n, string s) +{ + uint dummy; + uint hActive, hActive_hSyncOffset, hActive_hSyncOffset_hSync, hActive_hBlanking; + uint vActive, vActive_vSyncOffset, vActive_vSyncOffset_vSync, vActive_vBlanking; + char hsync, vsync; + string interlaced; + double f; + SScanf(s, "Modeline \"%ux%u\" %lf %u %u %u %u %u %u %u %u %chsync %cvsync %[^0-9;]", + dummy, dummy, f, + hActive, hActive_hSyncOffset, hActive_hSyncOffset_hSync, hActive_hBlanking, + vActive, vActive_vSyncOffset, vActive_vSyncOffset_vSync, vActive_vBlanking, + hsync, vsync, + interlaced + ); + int p = Strchr(s, ';'); + if (p >= 0) SScanf(SubStr(s, p), "; %u %u", n.hBorder, n.vBorder); + + n.interlaced = (interlaced[0] == 'I'); + uint im = n.interlaced ? 2 : 1; + + uint hBlanking = hActive_hBlanking - hActive; + uint hSync = hActive_hSyncOffset_hSync - hActive_hSyncOffset; + uint hSyncOffset = hActive_hSyncOffset - hActive; + n.hActive_msb = hActive>>8; n.hActive_lsb = (ubyte)hActive; + n.hSyncOffset_msb = hSyncOffset>>8; n.hSyncOffset_lsb = (ubyte)hSyncOffset; + n.hSync_msb = hSync>>8; n.hSync_lsb = (ubyte)hSync; + n.hBlanking_msb = hBlanking>>8; n.hBlanking_lsb = (ubyte)hBlanking; + + uint vBlanking = (vActive_vBlanking - vActive)/im; + uint vSync = (vActive_vSyncOffset_vSync - vActive_vSyncOffset)/im; + uint vSyncOffset = (vActive_vSyncOffset - vActive)/im; + vActive /= im; + n.vActive_msb = vActive>>8; n.vActive_lsb = (ubyte)vActive; + n.vSyncOffset_msb = vSyncOffset>>8; n.vSyncOffset_lsb = (ubyte)vSyncOffset; + n.vSync_msb = vSync>>8; n.vSync_lsb = (ubyte)vSync; + n.vBlanking_msb = vBlanking>>8; n.vBlanking_lsb = (ubyte)vBlanking; + + n._f1 = hsync == '+' ? 1 : 0; + n._f2 = vsync == '+' ? 1 : 0; + n.pixelClock = f * 100; +} + +//-------------------------------------- + +struct File +{ + struct Header + { + ubyte pattern[8] ; + EISAId eisaId ; + uint16 mfgProductId ; + uint32 serial ; + ubyte mfgWeek ; + ubyte mfgYear ; + ubyte edidVersion ; + ubyte edidRevision ; + } header ; + + struct Basic + { + union Bitmap + { + ubyte hmz; + if (hmz & 0x80) + { + struct Digital + { + ubyte vesa : 1 ; + ubyte reserved : 6 ; + ubyte digital : 1 ; + } digital; + } + else + { + struct Analog + { + ubyte vSeparate : 1 ; + ubyte syncOnGreen : 1 ; + + ubyte compositeSync : 1 ; + ubyte separateSync : 1 ; + ubyte blankToBlack : 1 ; + ubyte level : 2 ; + ubyte analog : 1 ; + } analog; + } + } bitmap ; + + ubyte width ; + ubyte height ; + ubyte gamma ; + + struct Features + { + ubyte gtf : 1 ; + ubyte prefTimingDesc1 : 1 ; + ubyte sRGB : 1 ; + if (bitmap.hmz & 0x80) + ubyte displayType : 2 ; + else + ubyte displayType : 2 ; + ubyte dpmsActiveOff : 1 ; + ubyte dpmsSusepend : 1 ; + ubyte dpmsStandby : 1 ; + } features ; + } basic ; + + struct Chromaticity + { + ubyte green_y_lsb : 2 ; + ubyte green_x_lsb : 2 ; + ubyte red_y_lsb : 2 ; + ubyte red_x_lsb : 2 ; + ubyte bluewhite_lsb : 2 ; + ubyte zero : 6; // Lelouch + ubyte red_x_msb ; + ubyte red_y_msb ; + ubyte green_x_msb ; + ubyte green_y_msb ; + ubyte blue_x_msb ; + ubyte blue_y_msb ; + ubyte white_x_msb ; + ubyte white_y_msb ; + } chromaticity ; + + struct Timings + { + ubyte _800x600_60 : 1; + ubyte _800x600_56 : 1; + ubyte _640x480_75 : 1; + ubyte _640x480_72 : 1; + ubyte _640x480_67 : 1; + ubyte _640x480_60 : 1; + ubyte _720x400_88 : 1; + ubyte _720x400_70 : 1; + ubyte _1280x1024_75 : 1; + ubyte _1024x768_75 : 1; + ubyte _1024x768_72 : 1; + ubyte _1024x768_60 : 1; + ubyte _1024x768i_87 : 1; + ubyte _832x624_75 : 1; + ubyte _800x600_75 : 1; + ubyte _800x600_72 : 1; + ubyte mfgSpecific : 7; + ubyte _1152x870_75 : 1; // Apple Macintosh II + } timings ; + + Timing timings2[8] ; + + struct Descriptor + { + if (ReadUShort(FTell()) != 0) + { + ModeLine numbers; + } + else + { + uint16 zero; + ubyte zero; + DescriptorType descriptorType; // FA-FF currently defined. 00-0F reserved for vendors. + ubyte zero; + switch (descriptorType) + { + case TIMINGS: + Timing timings[6] ; + break; + + case MONITOR_NAME: + char name[13] ; + break; + + case SERIAL_NUMBER: + char serial[13] ; + break; + + case UNSPECIFIED_TEXT: + char text[13] ; + break; + + case RANGE_LIMITS: // Monitor range limits. 6- or 13-byte binary descriptor. + { + ubyte vMinRate ; + ubyte vMaxRate ; + ubyte hMinRate ; + ubyte hMaxRate ; + PixelRate maxPixelRate ; + ubyte extended ; + if (extended == 0x02) + { + ubyte reserved; + ubyte startFreqSecondCurve ; + ubyte gtf_C ; + uint16 gtf_M ; + ubyte gtf_K ; + ubyte gtf_J ; + } + else + { + ubyte padding[7] ; + } + break; + } + + case WHITE_POINT: // Additional white point data. 2- 5-byte descriptors, padded with 0A 20 20. + { + struct + { + ubyte indexNumber ; + ubyte white_y_lsb : 2 ; + ubyte white_x_lsb : 2 ; + ubyte unused : 4; // (C) DarkFader + ubyte white_x_msb ; + ubyte white_y_msb ; + ubyte gamma ; + } whitePoints[2] ; + ubyte padding[3] ; + break; + } + + default: + { + ubyte unknown[13]; + Warning("Unknown descriptor type"); + break; + } + } + } + } descriptors[4] ; + + + ubyte extensionCount ; + ubyte checksum ; + +//-------------------------------------- + + struct CEA_EDID + { + local int64 extensionBlockStart = FTell(); + + ubyte extensionTag ; + switch (extensionTag) + { + case 0x02: // Additional Timing Data Block (CEA EDID Timing Extension) + { + ubyte revision ; + ubyte dtdStart ; + ubyte dtdCount : 4 ; + ubyte YCbCr422 : 1 ; + ubyte YCbCr444 : 1 ; + ubyte basic_audio : 1 ; + ubyte underscan : 1 ; + + while (FTell() < extensionBlockStart + dtdStart) + { + DataBlock dataBlock; + } // while + + if (FTell() != extensionBlockStart + dtdStart) + { + Warning("Unexpected DTD start"); + } + + FSeek(extensionBlockStart + dtdStart); + + while (ReadUShort(FTell()) != 0) + { + Descriptor descriptor ; + } + + ubyte padding[127 - (FTell() - extensionBlockStart)] ; + ubyte checksum ; + if (Checksum(CHECKSUM_SUM8, extensionBlockStart, 128) != 0) Warning("Invalid extension block checksum!"); + + break; + } + + default: + Warning("Unsupported extension block"); + break; + } + } extensions[extensionCount] ; + + +} file ; + +//-------------------------------------- diff --git a/cparser/ELFTemplate.bt b/cparser/ELFTemplate.bt new file mode 100644 index 0000000..361ad45 --- /dev/null +++ b/cparser/ELFTemplate.bt @@ -0,0 +1,795 @@ +//---------------------------------------- +//--- 010 Editor v2.0 Binary Template +// +// File: ELFTemplate.bt +// Author: 010Editor (Unknown?) +// Tim "diff" Strazzere +// Revision: 2.2 +// Purpose: Defines a template for +// parsing ELF 32-bit and 64-bit files. +//---------------------------------------- +// +// Version 2.2 +// FIXED: +// - Fixed issues if the section header count is greater +// the actual number of sections that exist. +// More information; +// http://dustri.org/b/?p=832 +// +// Version 2.1 +// FIXED: +// - Fixed issue with local variables so it's actually +// runnable inside v4.0.3 + +// Define structures used in ELF files + +// ELF Header Types +// ELF identification element + +// Accelerate a slow lookup with an array +local int sec_tbl_elem[255]; + +typedef enum { + ELFCLASSNONE =0, + ELFCLASS32 =1, + ELFCLASS64 =2 + }ei_class_2_e; + +typedef enum { + ELFDATAONE =0, + ELFDATA2LSB =1, + ELFDATA2MSB =2 + }ei_data_e; + +typedef enum { + E_NONE =0, + E_CURRENT =1 + }ei_version_e; + +typedef enum { + ELFOSABI_NONE =0, //No extensions or unspecified + ELFOSABI_HPUX =1, //Hewlett-Packard HP-UX + ELFOSABI_NETBSD =2, //NetBSD + ELFOSABI_SOLARIS=6, //Sun Solaris + ELFOSABI_AIX =7, //AIX + ELFOSABI_IRIX =8, //IRIX + ELFOSABI_FREEBSD=9, //FreeBSD + ELFOSABI_TRU64 =10, //Compaq TRU64 UNIX + ELFOSABI_MODESTO=11, //Novell Modesto + ELFOSABI_OPENBSD=12, //Open BSD + ELFOSABI_OPENVMS=13, //Open VMS + ELFOSABI_NSK =14, //Hewlett-Packard Non-Stop Kernel + ELFOSABI_AROS =15 //Amiga Research OS + }ei_osabi_e; + + +typedef struct { + char file_identification[4]; + ei_class_2_e ei_class_2; + ei_data_e ei_data; + if( ei_data == ELFDATA2LSB ) { + LittleEndian(); + } else { + BigEndian(); + } + ei_version_e ei_version; + ei_osabi_e ei_osabi; + uchar ei_abiversion; + uchar ei_pad[6]; + uchar ei_nident_SIZE; +} e_ident_t; + +// Elf Data Types for 32/64 bit +//32 bit +typedef uint32 Elf32_Word; +typedef uint32 Elf32_Off; +typedef uint32 Elf32_Addr ; +typedef uint16 Elf32_Half; +typedef uint32 Elf32_Xword; +//64 bit +typedef uint32 Elf64_Word; +typedef uint64 Elf64_Off; +typedef uint64 Elf64_Addr ; +typedef uint16 Elf64_Half; +typedef uint64 Elf64_Xword; + +string VAddr32( Elf32_Addr &addr ) { + local char buf[128]; + SPrintf( buf, "0x%08X", addr ); + return buf; +} + +string VAddr64( Elf64_Addr &addr ) { + local char buf[128]; + SPrintf( buf, "0x%016LX", addr ); + return buf; +} + +typedef enum { + ET_NONE =0, + ET_REL =1, + ET_EXEC =2, + ET_DYN =3, + ET_CORE =4, + ET_LOOS =0xfe00, + ET_HIOS =0xfeff, + ET_LOPROC =0xff00, + ET_HIPROC =0xffff + } e_type32_e; +typedef e_type32_e e_type64_e; + +typedef enum { // list has to to be completed + EM_NONE =0, //No machine + EM_M32 =1, //AT&T WE 32100 + EM_SPARC =2, //SPARC + EM_386 =3, //Intel 80386 + EM_68K =4, //Motorola 68000 + EM_88K =5, //Motorola 88000 + reserved6 =6, //Reserved for future use (was EM_486) + EM_860 =7, //Intel 80860 + EM_MIPS =8, //MIPS I Architecture + EM_S370 =9, //IBM System/370 Processor + EM_MIPS_RS3_LE =10, //MIPS RS3000 Little-endian + reserved11 =11, //Reserved for future use + reserved12 =12, //Reserved for future use + reserved13 =13, //Reserved for future use + reserved14 =14, //Reserved for future use + EM_PARISC =15, //Hewlett-Packard PA-RISC + reserved16 =16, //Reserved for future use + EM_VPP500 =17, //Fujitsu VPP500 + EM_SPARC32PLUS =18, //Enhanced instruction set SPARC + EM_960 =19, //Intel 80960 + EM_PPC =20, //PowerPC + EM_PPC64 =21, //64-bit PowerPC + EM_S390 =22, //IBM System/390 Processor + reserved23 =23, //Reserved for future use + reserved24 =24, //Reserved for future use + reserved25 =25, //Reserved for future use + reserved26 =26, //Reserved for future use + reserved27 =27, //Reserved for future use + reserved28 =28, //Reserved for future use + reserved29 =29, //Reserved for future use + reserved30 =30, //Reserved for future use + reserved31 =31, //Reserved for future use + reserved32 =32, //Reserved for future use + reserved33 =33, //Reserved for future use + reserved34 =34, //Reserved for future use + reserved35 =35, //Reserved for future use + EM_V800 =36, //NEC V800 + EM_FR20 =37, //Fujitsu FR20 + EM_RH32 =38, //TRW RH-32 + EM_RCE =39, //Motorola RCE + EM_ARM =40, //Advanced RISC Machines ARM + EM_ALPHA =41, //Digital Alpha + EM_SH =42, //Hitachi SH + EM_SPARCV9 =43, //SPARC Version 9 + EM_TRICORE =44, //Siemens TriCore embedded processor + EM_ARC =45, //Argonaut RISC Core, Argonaut Technologies Inc. + EM_H8_300 =46, //Hitachi H8/300 + EM_H8_300H =47, //Hitachi H8/300H + EM_H8S =48, //Hitachi H8S + EM_H8_500 =49, //Hitachi H8/500 + EM_IA_64 =50, //Intel IA-64 processor architecture + EM_MIPS_X =51, //Stanford MIPS-X + EM_COLDFIRE =52, //Motorola ColdFire + EM_68HC12 =53, //Motorola M68HC12 + EM_MMA =54, //Fujitsu MMA Multimedia Accelerator + EM_PCP =55, //Siemens PCP + EM_NCPU =56, //Sony nCPU embedded RISC processor + EM_NDR1 =57, //Denso NDR1 microprocessor + EM_STARCORE =58, //Motorola Star*Core processor + EM_ME16 =59, //Toyota ME16 processor + EM_ST100 =60, //STMicroelectronics ST100 processor + EM_TINYJ =61, //Advanced Logic Corp. TinyJ embedded processor family + EM_X86_64 =62, //AMD x86-64 architecture + EM_PDSP =63, //Sony DSP Processor + EM_PDP10 =64, //Digital Equipment Corp. PDP-10 + EM_PDP11 =65, //Digital Equipment Corp. PDP-11 + EM_FX66 =66, //Siemens FX66 microcontroller + EM_ST9PLUS =67, //STMicroelectronics ST9+ 8/16 bit microcontroller + EM_ST7 =68, //STMicroelectronics ST7 8-bit microcontroller + EM_68HC16 =69, //Motorola MC68HC16 Microcontroller + EM_68HC11 =70, //Motorola MC68HC11 Microcontroller + EM_68HC08 =71, //Motorola MC68HC08 Microcontroller + EM_68HC05 =72, //Motorola MC68HC05 Microcontroller + EM_SVX =73, //Silicon Graphics SVx + EM_ST19 =75, //Digital VAX + EM_CRIS =76, //Axis Communications 32-bit embedded processor + EM_JAVELIN =77, //Infineon Technologies 32-bit embedded processor + EM_FIREPATH =78, //Element 14 64-bit DSP Processor + EM_ZSP =79, //LSI Logic 16-bit DSP Processor + EM_MMIX =80, //Donald Knuth's educational 64-bit processor + EM_HUANY =81, //Harvard University machine-independent object files + EM_PRISM =82, //SiTera Prism + EM_AVR =83, //Atmel AVR 8-bit microcontroller + EM_FR30 =84, //Fujitsu FR30 + EM_D10V =85, //Mitsubishi D10V + EM_D30V =86, //Mitsubishi D30V + EM_V850 =87, //NEC v850 + EM_M32R =88, //Mitsubishi M32R + EM_MN10300 =89, //Matsushita MN10300 + EM_MN10200 =90, //Matsushita MN10200 + EM_PJ =91, //picoJava + EM_OPENRISC =92, //OpenRISC 32-bit embedded processor + EM_ARC_A5 =93, //ARC Cores Tangent-A5 + EM_XTENSA =94, //Tensilica Xtensa Architecture + EM_VIDEOCORE =95, //Alphamosaic VideoCore processor + EM_TMM_GPP =96, //Thompson Multimedia General Purpose Processor + EM_NS32K =97, //National Semiconductor 32000 series + EM_TPC =98, //Tenor Network TPC processor + EM_SNP1K =99, //Trebia SNP 1000 processor + EM_ST200 =100, //STMicroelectronics (www.st.com) ST200 microcontroller + EM_IP2K =101, //Ubicom IP2xxx microcontroller family + EM_MAX =102, //MAX Processor + EM_CR =103, //National Semiconductor CompactRISC microprocessor + EM_F2MC16 =104, //Fujitsu F2MC16 + EM_MSP430 =105, //Texas Instruments embedded microcontroller msp430 + EM_BLACKFIN =106, //Analog Devices Blackfin (DSP) processor + EM_SE_C33 =107, //S1C33 Family of Seiko Epson processors + EM_SEP =108, //Sharp embedded microprocessor + EM_ARCA =109, //Arca RISC Microprocessor + EM_UNICORE =110 //Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University + } e_machine32_e; + +typedef e_machine32_e e_machine64_e; + +typedef enum { + EV_NONE =0, + EV_CURRENT =1 + } e_version32_e; +typedef e_version32_e e_version64_e; + + +// Program Header Types +typedef enum { + PT_NULL =0, + PT_LOAD =1, + PT_DYNAMIC =2, + PT_INERP =3, + PT_NOTE =4, + PT_SHLIB =5, + PT_PHDR =6, + PT_LOOS =0x60000000, + PT_HIOS =0x6fffffff, + PT_LOPROC =0x70000000, + PT_HIPROC =0x7fffffff + } p_type32_e; +typedef p_type32_e p_type64_e; + +typedef enum { + PF_None =0, + PF_Exec =1, + PF_Write =2, + PF_Write_Exec =3, + PF_Read =4, + PF_Read_Exec =5, + PF_Read_Write =6, + PF_Read_Write_Exec =7 + } p_flags32_e; +typedef p_flags32_e p_flags64_e; + +typedef enum { + SHN_UNDEF = 0, /* undefined, e.g. undefined symbol */ + SHN_LORESERVE = 0xff00, /* Lower bound of reserved indices */ + SHN_LOPROC = 0xff00, /* Lower bound processor-specific index */ + SHN_HIPROC = 0xff1f, /* Upper bound processor-specific index */ + SHN_LOOS = 0xff20, /* Lower bound OS-specific index */ + SHN_HIOS = 0xff3f, /* Upper bound OS-specific index */ + SHN_ABS = 0xfff1, /* Absolute value, not relocated */ + SHN_COMMON = 0xfff2, /* FORTRAN common or unallocated C */ + SHN_HIRESERVE = 0xffff /* Upper bound of reserved indices */ + } s_name32_e; +typedef s_name32_e s_name64_e; + +typedef enum { + SHT_NULL = 0, /* Inactive section header */ + SHT_PROGBITS = 1, /* Information defined by the program */ + SHT_SYMTAB = 2, /* Symbol table - not DLL */ + SHT_STRTAB = 3, /* String table */ + SHT_RELA = 4, /* Explicit addend relocations, Elf64_Rela */ + SHT_HASH = 5, /* Symbol hash table */ + SHT_DYNAMIC = 6, /* Information for dynamic linking */ + SHT_NOTE = 7, /* A Note section */ + SHT_NOBITS = 8, /* Like SHT_PROGBITS with no data */ + SHT_REL = 9, /* Implicit addend relocations, Elf64_Rel */ + SHT_SHLIB = 10, /* Currently unspecified semantics */ + SHT_DYNSYM = 11, /* Symbol table for a DLL */ + + SHT_LOOS = 0x60000000, /* Lowest OS-specific section type */ + SHT_HIOS = 0x6fffffff, /* Highest OS-specific section type */ + + SHT_LOPROC = 0x70000000, /* Lowest processor-specific section type */ + SHT_HIPROC = 0x7fffffff /* Highest processor-specific section type */ + } s_type32_e; +typedef s_type32_e s_type64_e; + +string ReservedSectionName( s_name32_e id ) { + local char buf[255]; + if( id == SHN_UNDEF ) return "SHN_UNDEF"; + if( id >= SHN_LOPROC && id <= SHN_HIPROC ) { + SPrintf( buf, "SHN_PROC_%02X", id - SHN_LOPROC ); + return buf; + } + if( id >= SHN_LOOS && id <= SHN_HIOS ) { + SPrintf( buf, "SHN_OS_%02X", id - SHN_LOOS ); + return buf; + } + if( id == SHN_ABS ) return "SHN_ABS"; + if( id == SHN_COMMON ) return "SHN_COMMON"; + + SPrintf( buf, "SHN_RESERVE_%02X", id - SHN_LORESERVE ); + return buf; +} + +// Program Table 32/64 bit +typedef struct { //32bit + local quad off = FTell(); + + p_type32_e p_type; + Elf32_Off p_offset_FROM_FILE_BEGIN ; + Elf32_Addr p_vaddr_VIRTUAL_ADDRESS; + Elf32_Addr p_paddr_PHYSICAL_ADDRESS; + Elf32_Word p_filesz_SEGMENT_FILE_LENGTH; + Elf32_Word p_memsz_SEGMENT_RAM_LENGTH; + p_flags32_e p_flags; + Elf32_Word p_align; + + if( p_filesz_SEGMENT_FILE_LENGTH > 0 ) { + FSeek(p_offset_FROM_FILE_BEGIN); + char p_data[p_filesz_SEGMENT_FILE_LENGTH]; + } + + FSeek(off + file.elf_header.e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE); +} program_table_entry32_t ; +typedef struct { //64bit + local quad off = FTell(); + + p_type64_e p_type; + p_flags64_e p_flags; + Elf64_Off p_offset_FROM_FILE_BEGIN ; + Elf64_Addr p_vaddr_VIRTUAL_ADDRESS; + Elf64_Addr p_paddr_PHYSICAL_ADDRESS; + Elf64_Xword p_filesz_SEGMENT_FILE_LENGTH; + Elf64_Xword p_memsz_SEGMENT_RAM_LENGTH; + Elf64_Xword p_align; + + if( p_filesz_SEGMENT_FILE_LENGTH > 0 ) { + FSeek(p_offset_FROM_FILE_BEGIN); + char p_data[p_filesz_SEGMENT_FILE_LENGTH]; + } + + FSeek(off + file.elf_header.e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE); +} program_table_entry64_t ; + +string ProgramType( p_type64_e type ) { + switch( type ) { + case PT_NULL: return "NULL"; + case PT_LOAD: return "Loadable Segment"; + case PT_DYNAMIC: return "Dynamic Segment"; + case PT_INERP: return "Interpreter Path"; + case PT_NOTE: return "Note"; + case PT_SHLIB: return "PT_SHLIB"; + case PT_PHDR: return "Program Header"; + default: return "Unknown Section"; + } +} + +string ProgramFlags( p_flags64_e flags ) { + local string rv = "("; + + rv += ( flags & PF_Read ) ? "R" : "_"; + rv += ( flags & PF_Write ) ? "W" : "_"; + rv += ( flags & PF_Exec ) ? "X" : "_"; + rv += ")"; + return rv; +} + +string ProgramInfo64( program_table_entry64_t &ent ) { + return ProgramFlags( ent.p_flags ) + " " + ProgramType( ent.p_type ); +} + +string ProgramInfo32( program_table_entry32_t &ent ) { + return ProgramFlags( ent.p_flags ) + " " + ProgramType( ent.p_type ); +} + +// ************************************* Section Table *************************************** + +typedef enum { + SF32_None =0, + SF32_Exec =1, + SF32_Alloc =2, + SF32_Alloc_Exec =3, + SF32_Write =4, + SF32_Write_Exec =5, + SF32_Write_Alloc =6, + SF32_Write_Alloc_Exec =7 + } s_flags32_e; +typedef enum { + SF64_None =0, + SF64_Exec =1, + SF64_Alloc =2, + SF64_Alloc_Exec =3, + SF64_Write =4, + SF64_Write_Exec =5, + SF64_Write_Alloc =6, + SF64_Write_Alloc_Exec =7 + } s_flags64_e; + +// Pointer to where the next name is located +local quad section_name_block_off; + +typedef struct { + s_name32_e s_name_off ; + + local quad off = FTell(); + FSeek( section_name_block_off + s_name_off ); + + string s_name_str; + + FSeek( off ); +} s_name32_t ; + +typedef s_name32_t s_name64_t; + +string SectionName( s_name32_t § ) { + if( sect.s_name_off > SHN_UNDEF && sect.s_name_off < SHN_LORESERVE ) { + return sect.s_name_str; + } + return ReservedSectionName( sect.s_name_off ); +} + +typedef struct { //64bit + local quad off = FTell(); + + s_name64_t s_name; /* Section name */ + s_type64_e s_type; /* Section type */ + s_flags64_e s_flags; /* Section attributes */ + Elf64_Addr s_addr; /* Virtual address in memory */ + Elf64_Off s_offset ; /* Offset in file */ + Elf64_Xword s_size; /* Size of section */ + Elf64_Word s_link; /* Link to other section */ + Elf64_Word s_info; /* Miscellaneous information */ + Elf64_Xword s_addralign; /* Address alignment boundary */ + Elf64_Xword s_entsize; /* Entry size, if section has table */ + + if( s_type != SHT_NOBITS && s_type != SHT_NULL && s_size > 0 ) { + FSeek(s_offset); + + char data[s_size]; + } + FSeek(off + file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE); +} section_table_entry64_t ; +// Section Table 32/64 bit +typedef struct { //32bit + local quad off = FTell(); + + s_name32_t s_name; /* Section name */ + s_type32_e s_type; /* Section type */ + s_flags32_e s_flags; /* Section attributes */ + Elf32_Addr s_addr; /* Virtual address in memory */ + Elf32_Off s_offset ; /* Offset in file */ + Elf32_Xword s_size; /* Size of section */ + Elf32_Word s_link; /* Link to other section */ + Elf32_Word s_info; /* Miscellaneous information */ + Elf32_Xword s_addralign; /* Address alignment boundary*/ + Elf32_Xword s_entsize; /* Entry size, if section has table */ + + if( s_type != SHT_NOBITS && s_type != SHT_NULL && s_size > 0 ) { + FSeek(s_offset); + + char s_data[s_size]; + } + FSeek(off + file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE); +} section_table_entry32_t ; + +string SectionName64( section_table_entry64_t § ) { + return SectionName( sect.s_name ); +} + +string SectionName32( section_table_entry32_t § ) { + return SectionName( sect.s_name ); +} + +// ************************************** Symbol Table *************************************** + +local quad symbol_name_block_off; + +typedef struct { + Elf32_Word sym_name_off ; /* Symbol table name offset */ + + local quad off = FTell(); + FSeek( symbol_name_block_off + sym_name_off ); + + string sym_name_str; + + FSeek( off ); +} sym_name32_t ; +typedef sym_name32_t sym_name64_t; + +string SymbolName( sym_name32_t &sym ) { + if( sym.sym_name_off > 0 ) { + return sym.sym_name_str; + } + return ""; +} + +typedef enum { + STB_LOCAL = 0, + STB_GLOBAL = 1, + STB_WEAK = 2, + STB_OS_1 = 10, + STB_OS_2 = 11, + STB_OS_3 = 12, + STB_PROC_1 = 13, + STB_PROC_2 = 14, + STB_PROC_3 = 15 +} sym_info_bind_e; + +typedef enum { + STT_NOTYPE = 0, + STT_OBJECT = 1, + STT_FUNC = 2, + STT_SECTION = 3, + STT_FILE = 4, + STT_OS_1 = 10, + STT_OS_2 = 11, + STT_OS_3 = 12, + STT_PROC_1 = 13, + STT_PROC_2 = 14, + STT_PROC_3 = 15 +} sym_info_type_e; + +typedef struct { + BitfieldDisablePadding(); + if( IsBigEndian() ) { + uchar sym_info_bind:4; + uchar sym_info_type:4; + } else { + uchar sym_info_type:4; + uchar sym_info_bind:4; + } + BitfieldEnablePadding(); +} sym_info_t ; + +string SymInfoEnums( sym_info_t &info ) { + local sym_info_bind_e x = info.sym_info_bind; + local sym_info_type_e y = info.sym_info_type; + return EnumToString( x ) + " | " + EnumToString( y ); +} + +typedef struct { + Elf64_Word sym_name; /* Symbol name */ + unsigned char sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf64_Half sym_shndx; /* Section table index */ + Elf64_Addr sym_value; /* Symbol value */ + Elf64_Xword sym_size; /* Size of object (e.g., common) */ +} Elf64_Sym_fixed; + +typedef struct { + Elf32_Word sym_name; /* Symbol name */ + Elf32_Addr sym_value; /* Symbol value */ + Elf32_Xword sym_size; /* Size of object (e.g., common) */ + unsigned char sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf32_Half sym_shndx; /* Section table index */ +} Elf32_Sym_fixed; + +typedef struct { + sym_name64_t sym_name; /* Symbol name */ + sym_info_t sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf64_Half sym_shndx; /* Section table index */ + Elf64_Addr sym_value; /* Symbol value */ + Elf64_Xword sym_size; /* Size of object (e.g., common) */ + + if( sym_size && SectionHasData( sym_shndx ) ) { + local quad off = FTell(); + FSeek( SectionVAddrOffset( sym_shndx, sym_value ) ); + + char sym_data[sym_size]; + + FSeek( off ); + } +} Elf64_Sym ; + +typedef struct { + sym_name32_t sym_name; /* Symbol name */ + Elf32_Addr sym_value; /* Symbol value */ + Elf32_Xword sym_size; /* Size of object (e.g., common) */ + sym_info_t sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf32_Half sym_shndx; /* Section table index */ + + if( sym_size && SectionHasData( sym_shndx ) ) { + local quad off = FTell(); + FSeek( SectionVAddrOffset( sym_shndx, sym_value ) ); + + char sym_data[sym_size]; + + FSeek( off ); + } +} Elf32_Sym ; + +string SymbolName64( Elf64_Sym &sym ) { + return ( sym.sym_size ? "" : "[U] " ) + SymbolName( sym.sym_name ); +} + +string SymbolName32( Elf32_Sym &sym ) { + return ( sym.sym_size ? "" : "[U] " ) + SymbolName( sym.sym_name ); +} + +// **************************************** ELF File ***************************************** + +local int iter; + +int FindNamedSection( string sect ) { +// local int iter; + + for( iter=0; iter < file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; iter++ ) { + if( Strcmp( file.section_header_table.section_table_element[ iter ].s_name.s_name_str, sect ) == 0 ) { + return iter; + } + } + + return -1; +} + +quad FindNamedSectionBlock( string sect ) { + local int off = FindNamedSection( sect ); + if( off != -1 ) + return file.section_header_table.section_table_element[off].s_offset; + + return -1; +} + +int SectionHasData( Elf64_Half s_index ) { + // This is ridiculously slow for some reason, so cache our results in an array + if( sec_tbl_elem[s_index] == -1 ) { + sec_tbl_elem[s_index] = exists( file.section_header_table.section_table_element[s_index].s_data ); + } + return sec_tbl_elem[s_index]; +} + +quad SectionVAddrOffset( Elf64_Half s_index, Elf64_Addr s_vaddr ) { + if( s_index < file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES ) { + return file.section_header_table.section_table_element[s_index].s_offset + s_vaddr - + file.section_header_table.section_table_element[s_index].s_addr; + } + return 0; +} + +// Structure of elf +struct { + local int i; + for( i=0; i<255; i++ ) { + sec_tbl_elem[i] = -1; + } + + struct { + e_ident_t e_ident; + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) + { + //32-Bit definitions of ELF Header + e_type32_e e_type; + e_machine32_e e_machine; + e_version32_e e_version; + Elf32_Addr e_entry_START_ADDRESS; + Elf32_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE; + Elf32_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE; + Elf32_Word e_flags; + Elf32_Half e_ehsize_ELF_HEADER_SIZE; + Elf32_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE; + Elf32_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES; + Elf32_Half e_shentzise_SECTION_HEADER_ENTRY_SIZE; + Elf32_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; + Elf32_Half e_shtrndx_STRING_TABLE_INDEX; + } + else + { + //64-Bit definitions of ELF Header + e_type64_e e_type; + e_machine64_e e_machine; + e_version64_e e_version; + Elf64_Addr e_entry_START_ADDRESS; + Elf64_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE; + Elf64_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE; + Elf32_Word e_flags; + Elf64_Half e_ehsize_ELF_HEADER_SIZE; + Elf64_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE; + Elf64_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES; + Elf64_Half e_shentzise_SECTION_HEADER_ENTRY_SIZE; + Elf64_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; + Elf64_Half e_shtrndx_STRING_TABLE_INDEX; + } + } elf_header; + + // Find the program table + if( file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES > 0 ) { + FSeek(file.elf_header.e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + program_table_entry32_t program_table_element[file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES]; + } else { + program_table_entry64_t program_table_element[file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES]; + } + } program_header_table; + } + + // Find the header name location + local quad section_name_off = + file.elf_header.e_shoff_SECTION_HEADER_OFFSET_IN_FILE + + ( file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE * + file.elf_header.e_shtrndx_STRING_TABLE_INDEX ); + + // Find the header name block + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + if( FileSize() >= section_name_off + 2 * sizeof( Elf32_Word ) + + sizeof( Elf32_Xword ) + sizeof( Elf32_Addr ) ) + section_name_block_off = ReadUInt( section_name_off + 2 * sizeof( Elf32_Word ) + + sizeof( Elf32_Xword ) + sizeof( Elf32_Addr ) ); + else { + Printf("Invalid section header found, skipping!\n"); + Warning("Invalid section header found, skipped and attempting to continue..."); + } + } else { + if( FileSize() >= section_name_off + 2 * sizeof( Elf64_Word ) + + sizeof( Elf64_Xword ) + sizeof( Elf64_Addr ) ) + section_name_block_off = ReadUQuad( section_name_off + 2 * sizeof( Elf64_Word ) + + sizeof( Elf64_Xword ) + sizeof( Elf64_Addr ) ); + else { + Printf("Invalid section header found, skipping!\n"); + Warning("Invalid section header found, skipped and attempting to continue..."); + } + } + + local int sec_tbl_cur_elem; + // Find the section headers + if( file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES > 0 ) { + FSeek(file.elf_header.e_shoff_SECTION_HEADER_OFFSET_IN_FILE); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + sec_tbl_cur_elem = 0; + section_table_entry32_t section_table_element[file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES]; + } else { + sec_tbl_cur_elem = 0; + section_table_entry64_t section_table_element[file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES]; + } + } section_header_table; + } + + local int sym_sect; + local int sym_name_sect; + + // Find the symbol section + sym_sect = FindNamedSection( ".symtab" ); + if( sym_sect >= 0 ) { + sym_name_sect = file.section_header_table.section_table_element[sym_sect].s_link; + symbol_name_block_off = file.section_header_table.section_table_element[sym_name_sect].s_offset; + + FSeek( file.section_header_table.section_table_element[sym_sect].s_offset ); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + Elf32_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf32_Sym_fixed)]; + } else { + Elf64_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf64_Sym_fixed)]; + } + } symbol_table; + } + + // Find the dynamic symbol section + sym_sect = FindNamedSection( ".dynsym" ); + if( sym_sect >= 0 ) { + sym_name_sect = file.section_header_table.section_table_element[sym_sect].s_link; + symbol_name_block_off = file.section_header_table.section_table_element[sym_name_sect].s_offset; + + FSeek( file.section_header_table.section_table_element[sym_sect].s_offset ); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + Elf32_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf32_Sym_fixed)]; + } else { + Elf64_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf64_Sym_fixed)]; + } + } dynamic_symbol_table; + } +} file; \ No newline at end of file diff --git a/cparser/ELFTemplate.new.bt b/cparser/ELFTemplate.new.bt new file mode 100644 index 0000000..361ad45 --- /dev/null +++ b/cparser/ELFTemplate.new.bt @@ -0,0 +1,795 @@ +//---------------------------------------- +//--- 010 Editor v2.0 Binary Template +// +// File: ELFTemplate.bt +// Author: 010Editor (Unknown?) +// Tim "diff" Strazzere +// Revision: 2.2 +// Purpose: Defines a template for +// parsing ELF 32-bit and 64-bit files. +//---------------------------------------- +// +// Version 2.2 +// FIXED: +// - Fixed issues if the section header count is greater +// the actual number of sections that exist. +// More information; +// http://dustri.org/b/?p=832 +// +// Version 2.1 +// FIXED: +// - Fixed issue with local variables so it's actually +// runnable inside v4.0.3 + +// Define structures used in ELF files + +// ELF Header Types +// ELF identification element + +// Accelerate a slow lookup with an array +local int sec_tbl_elem[255]; + +typedef enum { + ELFCLASSNONE =0, + ELFCLASS32 =1, + ELFCLASS64 =2 + }ei_class_2_e; + +typedef enum { + ELFDATAONE =0, + ELFDATA2LSB =1, + ELFDATA2MSB =2 + }ei_data_e; + +typedef enum { + E_NONE =0, + E_CURRENT =1 + }ei_version_e; + +typedef enum { + ELFOSABI_NONE =0, //No extensions or unspecified + ELFOSABI_HPUX =1, //Hewlett-Packard HP-UX + ELFOSABI_NETBSD =2, //NetBSD + ELFOSABI_SOLARIS=6, //Sun Solaris + ELFOSABI_AIX =7, //AIX + ELFOSABI_IRIX =8, //IRIX + ELFOSABI_FREEBSD=9, //FreeBSD + ELFOSABI_TRU64 =10, //Compaq TRU64 UNIX + ELFOSABI_MODESTO=11, //Novell Modesto + ELFOSABI_OPENBSD=12, //Open BSD + ELFOSABI_OPENVMS=13, //Open VMS + ELFOSABI_NSK =14, //Hewlett-Packard Non-Stop Kernel + ELFOSABI_AROS =15 //Amiga Research OS + }ei_osabi_e; + + +typedef struct { + char file_identification[4]; + ei_class_2_e ei_class_2; + ei_data_e ei_data; + if( ei_data == ELFDATA2LSB ) { + LittleEndian(); + } else { + BigEndian(); + } + ei_version_e ei_version; + ei_osabi_e ei_osabi; + uchar ei_abiversion; + uchar ei_pad[6]; + uchar ei_nident_SIZE; +} e_ident_t; + +// Elf Data Types for 32/64 bit +//32 bit +typedef uint32 Elf32_Word; +typedef uint32 Elf32_Off; +typedef uint32 Elf32_Addr ; +typedef uint16 Elf32_Half; +typedef uint32 Elf32_Xword; +//64 bit +typedef uint32 Elf64_Word; +typedef uint64 Elf64_Off; +typedef uint64 Elf64_Addr ; +typedef uint16 Elf64_Half; +typedef uint64 Elf64_Xword; + +string VAddr32( Elf32_Addr &addr ) { + local char buf[128]; + SPrintf( buf, "0x%08X", addr ); + return buf; +} + +string VAddr64( Elf64_Addr &addr ) { + local char buf[128]; + SPrintf( buf, "0x%016LX", addr ); + return buf; +} + +typedef enum { + ET_NONE =0, + ET_REL =1, + ET_EXEC =2, + ET_DYN =3, + ET_CORE =4, + ET_LOOS =0xfe00, + ET_HIOS =0xfeff, + ET_LOPROC =0xff00, + ET_HIPROC =0xffff + } e_type32_e; +typedef e_type32_e e_type64_e; + +typedef enum { // list has to to be completed + EM_NONE =0, //No machine + EM_M32 =1, //AT&T WE 32100 + EM_SPARC =2, //SPARC + EM_386 =3, //Intel 80386 + EM_68K =4, //Motorola 68000 + EM_88K =5, //Motorola 88000 + reserved6 =6, //Reserved for future use (was EM_486) + EM_860 =7, //Intel 80860 + EM_MIPS =8, //MIPS I Architecture + EM_S370 =9, //IBM System/370 Processor + EM_MIPS_RS3_LE =10, //MIPS RS3000 Little-endian + reserved11 =11, //Reserved for future use + reserved12 =12, //Reserved for future use + reserved13 =13, //Reserved for future use + reserved14 =14, //Reserved for future use + EM_PARISC =15, //Hewlett-Packard PA-RISC + reserved16 =16, //Reserved for future use + EM_VPP500 =17, //Fujitsu VPP500 + EM_SPARC32PLUS =18, //Enhanced instruction set SPARC + EM_960 =19, //Intel 80960 + EM_PPC =20, //PowerPC + EM_PPC64 =21, //64-bit PowerPC + EM_S390 =22, //IBM System/390 Processor + reserved23 =23, //Reserved for future use + reserved24 =24, //Reserved for future use + reserved25 =25, //Reserved for future use + reserved26 =26, //Reserved for future use + reserved27 =27, //Reserved for future use + reserved28 =28, //Reserved for future use + reserved29 =29, //Reserved for future use + reserved30 =30, //Reserved for future use + reserved31 =31, //Reserved for future use + reserved32 =32, //Reserved for future use + reserved33 =33, //Reserved for future use + reserved34 =34, //Reserved for future use + reserved35 =35, //Reserved for future use + EM_V800 =36, //NEC V800 + EM_FR20 =37, //Fujitsu FR20 + EM_RH32 =38, //TRW RH-32 + EM_RCE =39, //Motorola RCE + EM_ARM =40, //Advanced RISC Machines ARM + EM_ALPHA =41, //Digital Alpha + EM_SH =42, //Hitachi SH + EM_SPARCV9 =43, //SPARC Version 9 + EM_TRICORE =44, //Siemens TriCore embedded processor + EM_ARC =45, //Argonaut RISC Core, Argonaut Technologies Inc. + EM_H8_300 =46, //Hitachi H8/300 + EM_H8_300H =47, //Hitachi H8/300H + EM_H8S =48, //Hitachi H8S + EM_H8_500 =49, //Hitachi H8/500 + EM_IA_64 =50, //Intel IA-64 processor architecture + EM_MIPS_X =51, //Stanford MIPS-X + EM_COLDFIRE =52, //Motorola ColdFire + EM_68HC12 =53, //Motorola M68HC12 + EM_MMA =54, //Fujitsu MMA Multimedia Accelerator + EM_PCP =55, //Siemens PCP + EM_NCPU =56, //Sony nCPU embedded RISC processor + EM_NDR1 =57, //Denso NDR1 microprocessor + EM_STARCORE =58, //Motorola Star*Core processor + EM_ME16 =59, //Toyota ME16 processor + EM_ST100 =60, //STMicroelectronics ST100 processor + EM_TINYJ =61, //Advanced Logic Corp. TinyJ embedded processor family + EM_X86_64 =62, //AMD x86-64 architecture + EM_PDSP =63, //Sony DSP Processor + EM_PDP10 =64, //Digital Equipment Corp. PDP-10 + EM_PDP11 =65, //Digital Equipment Corp. PDP-11 + EM_FX66 =66, //Siemens FX66 microcontroller + EM_ST9PLUS =67, //STMicroelectronics ST9+ 8/16 bit microcontroller + EM_ST7 =68, //STMicroelectronics ST7 8-bit microcontroller + EM_68HC16 =69, //Motorola MC68HC16 Microcontroller + EM_68HC11 =70, //Motorola MC68HC11 Microcontroller + EM_68HC08 =71, //Motorola MC68HC08 Microcontroller + EM_68HC05 =72, //Motorola MC68HC05 Microcontroller + EM_SVX =73, //Silicon Graphics SVx + EM_ST19 =75, //Digital VAX + EM_CRIS =76, //Axis Communications 32-bit embedded processor + EM_JAVELIN =77, //Infineon Technologies 32-bit embedded processor + EM_FIREPATH =78, //Element 14 64-bit DSP Processor + EM_ZSP =79, //LSI Logic 16-bit DSP Processor + EM_MMIX =80, //Donald Knuth's educational 64-bit processor + EM_HUANY =81, //Harvard University machine-independent object files + EM_PRISM =82, //SiTera Prism + EM_AVR =83, //Atmel AVR 8-bit microcontroller + EM_FR30 =84, //Fujitsu FR30 + EM_D10V =85, //Mitsubishi D10V + EM_D30V =86, //Mitsubishi D30V + EM_V850 =87, //NEC v850 + EM_M32R =88, //Mitsubishi M32R + EM_MN10300 =89, //Matsushita MN10300 + EM_MN10200 =90, //Matsushita MN10200 + EM_PJ =91, //picoJava + EM_OPENRISC =92, //OpenRISC 32-bit embedded processor + EM_ARC_A5 =93, //ARC Cores Tangent-A5 + EM_XTENSA =94, //Tensilica Xtensa Architecture + EM_VIDEOCORE =95, //Alphamosaic VideoCore processor + EM_TMM_GPP =96, //Thompson Multimedia General Purpose Processor + EM_NS32K =97, //National Semiconductor 32000 series + EM_TPC =98, //Tenor Network TPC processor + EM_SNP1K =99, //Trebia SNP 1000 processor + EM_ST200 =100, //STMicroelectronics (www.st.com) ST200 microcontroller + EM_IP2K =101, //Ubicom IP2xxx microcontroller family + EM_MAX =102, //MAX Processor + EM_CR =103, //National Semiconductor CompactRISC microprocessor + EM_F2MC16 =104, //Fujitsu F2MC16 + EM_MSP430 =105, //Texas Instruments embedded microcontroller msp430 + EM_BLACKFIN =106, //Analog Devices Blackfin (DSP) processor + EM_SE_C33 =107, //S1C33 Family of Seiko Epson processors + EM_SEP =108, //Sharp embedded microprocessor + EM_ARCA =109, //Arca RISC Microprocessor + EM_UNICORE =110 //Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University + } e_machine32_e; + +typedef e_machine32_e e_machine64_e; + +typedef enum { + EV_NONE =0, + EV_CURRENT =1 + } e_version32_e; +typedef e_version32_e e_version64_e; + + +// Program Header Types +typedef enum { + PT_NULL =0, + PT_LOAD =1, + PT_DYNAMIC =2, + PT_INERP =3, + PT_NOTE =4, + PT_SHLIB =5, + PT_PHDR =6, + PT_LOOS =0x60000000, + PT_HIOS =0x6fffffff, + PT_LOPROC =0x70000000, + PT_HIPROC =0x7fffffff + } p_type32_e; +typedef p_type32_e p_type64_e; + +typedef enum { + PF_None =0, + PF_Exec =1, + PF_Write =2, + PF_Write_Exec =3, + PF_Read =4, + PF_Read_Exec =5, + PF_Read_Write =6, + PF_Read_Write_Exec =7 + } p_flags32_e; +typedef p_flags32_e p_flags64_e; + +typedef enum { + SHN_UNDEF = 0, /* undefined, e.g. undefined symbol */ + SHN_LORESERVE = 0xff00, /* Lower bound of reserved indices */ + SHN_LOPROC = 0xff00, /* Lower bound processor-specific index */ + SHN_HIPROC = 0xff1f, /* Upper bound processor-specific index */ + SHN_LOOS = 0xff20, /* Lower bound OS-specific index */ + SHN_HIOS = 0xff3f, /* Upper bound OS-specific index */ + SHN_ABS = 0xfff1, /* Absolute value, not relocated */ + SHN_COMMON = 0xfff2, /* FORTRAN common or unallocated C */ + SHN_HIRESERVE = 0xffff /* Upper bound of reserved indices */ + } s_name32_e; +typedef s_name32_e s_name64_e; + +typedef enum { + SHT_NULL = 0, /* Inactive section header */ + SHT_PROGBITS = 1, /* Information defined by the program */ + SHT_SYMTAB = 2, /* Symbol table - not DLL */ + SHT_STRTAB = 3, /* String table */ + SHT_RELA = 4, /* Explicit addend relocations, Elf64_Rela */ + SHT_HASH = 5, /* Symbol hash table */ + SHT_DYNAMIC = 6, /* Information for dynamic linking */ + SHT_NOTE = 7, /* A Note section */ + SHT_NOBITS = 8, /* Like SHT_PROGBITS with no data */ + SHT_REL = 9, /* Implicit addend relocations, Elf64_Rel */ + SHT_SHLIB = 10, /* Currently unspecified semantics */ + SHT_DYNSYM = 11, /* Symbol table for a DLL */ + + SHT_LOOS = 0x60000000, /* Lowest OS-specific section type */ + SHT_HIOS = 0x6fffffff, /* Highest OS-specific section type */ + + SHT_LOPROC = 0x70000000, /* Lowest processor-specific section type */ + SHT_HIPROC = 0x7fffffff /* Highest processor-specific section type */ + } s_type32_e; +typedef s_type32_e s_type64_e; + +string ReservedSectionName( s_name32_e id ) { + local char buf[255]; + if( id == SHN_UNDEF ) return "SHN_UNDEF"; + if( id >= SHN_LOPROC && id <= SHN_HIPROC ) { + SPrintf( buf, "SHN_PROC_%02X", id - SHN_LOPROC ); + return buf; + } + if( id >= SHN_LOOS && id <= SHN_HIOS ) { + SPrintf( buf, "SHN_OS_%02X", id - SHN_LOOS ); + return buf; + } + if( id == SHN_ABS ) return "SHN_ABS"; + if( id == SHN_COMMON ) return "SHN_COMMON"; + + SPrintf( buf, "SHN_RESERVE_%02X", id - SHN_LORESERVE ); + return buf; +} + +// Program Table 32/64 bit +typedef struct { //32bit + local quad off = FTell(); + + p_type32_e p_type; + Elf32_Off p_offset_FROM_FILE_BEGIN ; + Elf32_Addr p_vaddr_VIRTUAL_ADDRESS; + Elf32_Addr p_paddr_PHYSICAL_ADDRESS; + Elf32_Word p_filesz_SEGMENT_FILE_LENGTH; + Elf32_Word p_memsz_SEGMENT_RAM_LENGTH; + p_flags32_e p_flags; + Elf32_Word p_align; + + if( p_filesz_SEGMENT_FILE_LENGTH > 0 ) { + FSeek(p_offset_FROM_FILE_BEGIN); + char p_data[p_filesz_SEGMENT_FILE_LENGTH]; + } + + FSeek(off + file.elf_header.e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE); +} program_table_entry32_t ; +typedef struct { //64bit + local quad off = FTell(); + + p_type64_e p_type; + p_flags64_e p_flags; + Elf64_Off p_offset_FROM_FILE_BEGIN ; + Elf64_Addr p_vaddr_VIRTUAL_ADDRESS; + Elf64_Addr p_paddr_PHYSICAL_ADDRESS; + Elf64_Xword p_filesz_SEGMENT_FILE_LENGTH; + Elf64_Xword p_memsz_SEGMENT_RAM_LENGTH; + Elf64_Xword p_align; + + if( p_filesz_SEGMENT_FILE_LENGTH > 0 ) { + FSeek(p_offset_FROM_FILE_BEGIN); + char p_data[p_filesz_SEGMENT_FILE_LENGTH]; + } + + FSeek(off + file.elf_header.e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE); +} program_table_entry64_t ; + +string ProgramType( p_type64_e type ) { + switch( type ) { + case PT_NULL: return "NULL"; + case PT_LOAD: return "Loadable Segment"; + case PT_DYNAMIC: return "Dynamic Segment"; + case PT_INERP: return "Interpreter Path"; + case PT_NOTE: return "Note"; + case PT_SHLIB: return "PT_SHLIB"; + case PT_PHDR: return "Program Header"; + default: return "Unknown Section"; + } +} + +string ProgramFlags( p_flags64_e flags ) { + local string rv = "("; + + rv += ( flags & PF_Read ) ? "R" : "_"; + rv += ( flags & PF_Write ) ? "W" : "_"; + rv += ( flags & PF_Exec ) ? "X" : "_"; + rv += ")"; + return rv; +} + +string ProgramInfo64( program_table_entry64_t &ent ) { + return ProgramFlags( ent.p_flags ) + " " + ProgramType( ent.p_type ); +} + +string ProgramInfo32( program_table_entry32_t &ent ) { + return ProgramFlags( ent.p_flags ) + " " + ProgramType( ent.p_type ); +} + +// ************************************* Section Table *************************************** + +typedef enum { + SF32_None =0, + SF32_Exec =1, + SF32_Alloc =2, + SF32_Alloc_Exec =3, + SF32_Write =4, + SF32_Write_Exec =5, + SF32_Write_Alloc =6, + SF32_Write_Alloc_Exec =7 + } s_flags32_e; +typedef enum { + SF64_None =0, + SF64_Exec =1, + SF64_Alloc =2, + SF64_Alloc_Exec =3, + SF64_Write =4, + SF64_Write_Exec =5, + SF64_Write_Alloc =6, + SF64_Write_Alloc_Exec =7 + } s_flags64_e; + +// Pointer to where the next name is located +local quad section_name_block_off; + +typedef struct { + s_name32_e s_name_off ; + + local quad off = FTell(); + FSeek( section_name_block_off + s_name_off ); + + string s_name_str; + + FSeek( off ); +} s_name32_t ; + +typedef s_name32_t s_name64_t; + +string SectionName( s_name32_t § ) { + if( sect.s_name_off > SHN_UNDEF && sect.s_name_off < SHN_LORESERVE ) { + return sect.s_name_str; + } + return ReservedSectionName( sect.s_name_off ); +} + +typedef struct { //64bit + local quad off = FTell(); + + s_name64_t s_name; /* Section name */ + s_type64_e s_type; /* Section type */ + s_flags64_e s_flags; /* Section attributes */ + Elf64_Addr s_addr; /* Virtual address in memory */ + Elf64_Off s_offset ; /* Offset in file */ + Elf64_Xword s_size; /* Size of section */ + Elf64_Word s_link; /* Link to other section */ + Elf64_Word s_info; /* Miscellaneous information */ + Elf64_Xword s_addralign; /* Address alignment boundary */ + Elf64_Xword s_entsize; /* Entry size, if section has table */ + + if( s_type != SHT_NOBITS && s_type != SHT_NULL && s_size > 0 ) { + FSeek(s_offset); + + char data[s_size]; + } + FSeek(off + file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE); +} section_table_entry64_t ; +// Section Table 32/64 bit +typedef struct { //32bit + local quad off = FTell(); + + s_name32_t s_name; /* Section name */ + s_type32_e s_type; /* Section type */ + s_flags32_e s_flags; /* Section attributes */ + Elf32_Addr s_addr; /* Virtual address in memory */ + Elf32_Off s_offset ; /* Offset in file */ + Elf32_Xword s_size; /* Size of section */ + Elf32_Word s_link; /* Link to other section */ + Elf32_Word s_info; /* Miscellaneous information */ + Elf32_Xword s_addralign; /* Address alignment boundary*/ + Elf32_Xword s_entsize; /* Entry size, if section has table */ + + if( s_type != SHT_NOBITS && s_type != SHT_NULL && s_size > 0 ) { + FSeek(s_offset); + + char s_data[s_size]; + } + FSeek(off + file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE); +} section_table_entry32_t ; + +string SectionName64( section_table_entry64_t § ) { + return SectionName( sect.s_name ); +} + +string SectionName32( section_table_entry32_t § ) { + return SectionName( sect.s_name ); +} + +// ************************************** Symbol Table *************************************** + +local quad symbol_name_block_off; + +typedef struct { + Elf32_Word sym_name_off ; /* Symbol table name offset */ + + local quad off = FTell(); + FSeek( symbol_name_block_off + sym_name_off ); + + string sym_name_str; + + FSeek( off ); +} sym_name32_t ; +typedef sym_name32_t sym_name64_t; + +string SymbolName( sym_name32_t &sym ) { + if( sym.sym_name_off > 0 ) { + return sym.sym_name_str; + } + return ""; +} + +typedef enum { + STB_LOCAL = 0, + STB_GLOBAL = 1, + STB_WEAK = 2, + STB_OS_1 = 10, + STB_OS_2 = 11, + STB_OS_3 = 12, + STB_PROC_1 = 13, + STB_PROC_2 = 14, + STB_PROC_3 = 15 +} sym_info_bind_e; + +typedef enum { + STT_NOTYPE = 0, + STT_OBJECT = 1, + STT_FUNC = 2, + STT_SECTION = 3, + STT_FILE = 4, + STT_OS_1 = 10, + STT_OS_2 = 11, + STT_OS_3 = 12, + STT_PROC_1 = 13, + STT_PROC_2 = 14, + STT_PROC_3 = 15 +} sym_info_type_e; + +typedef struct { + BitfieldDisablePadding(); + if( IsBigEndian() ) { + uchar sym_info_bind:4; + uchar sym_info_type:4; + } else { + uchar sym_info_type:4; + uchar sym_info_bind:4; + } + BitfieldEnablePadding(); +} sym_info_t ; + +string SymInfoEnums( sym_info_t &info ) { + local sym_info_bind_e x = info.sym_info_bind; + local sym_info_type_e y = info.sym_info_type; + return EnumToString( x ) + " | " + EnumToString( y ); +} + +typedef struct { + Elf64_Word sym_name; /* Symbol name */ + unsigned char sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf64_Half sym_shndx; /* Section table index */ + Elf64_Addr sym_value; /* Symbol value */ + Elf64_Xword sym_size; /* Size of object (e.g., common) */ +} Elf64_Sym_fixed; + +typedef struct { + Elf32_Word sym_name; /* Symbol name */ + Elf32_Addr sym_value; /* Symbol value */ + Elf32_Xword sym_size; /* Size of object (e.g., common) */ + unsigned char sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf32_Half sym_shndx; /* Section table index */ +} Elf32_Sym_fixed; + +typedef struct { + sym_name64_t sym_name; /* Symbol name */ + sym_info_t sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf64_Half sym_shndx; /* Section table index */ + Elf64_Addr sym_value; /* Symbol value */ + Elf64_Xword sym_size; /* Size of object (e.g., common) */ + + if( sym_size && SectionHasData( sym_shndx ) ) { + local quad off = FTell(); + FSeek( SectionVAddrOffset( sym_shndx, sym_value ) ); + + char sym_data[sym_size]; + + FSeek( off ); + } +} Elf64_Sym ; + +typedef struct { + sym_name32_t sym_name; /* Symbol name */ + Elf32_Addr sym_value; /* Symbol value */ + Elf32_Xword sym_size; /* Size of object (e.g., common) */ + sym_info_t sym_info; /* Type and Binding attributes */ + unsigned char sym_other; /* Reserved */ + Elf32_Half sym_shndx; /* Section table index */ + + if( sym_size && SectionHasData( sym_shndx ) ) { + local quad off = FTell(); + FSeek( SectionVAddrOffset( sym_shndx, sym_value ) ); + + char sym_data[sym_size]; + + FSeek( off ); + } +} Elf32_Sym ; + +string SymbolName64( Elf64_Sym &sym ) { + return ( sym.sym_size ? "" : "[U] " ) + SymbolName( sym.sym_name ); +} + +string SymbolName32( Elf32_Sym &sym ) { + return ( sym.sym_size ? "" : "[U] " ) + SymbolName( sym.sym_name ); +} + +// **************************************** ELF File ***************************************** + +local int iter; + +int FindNamedSection( string sect ) { +// local int iter; + + for( iter=0; iter < file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; iter++ ) { + if( Strcmp( file.section_header_table.section_table_element[ iter ].s_name.s_name_str, sect ) == 0 ) { + return iter; + } + } + + return -1; +} + +quad FindNamedSectionBlock( string sect ) { + local int off = FindNamedSection( sect ); + if( off != -1 ) + return file.section_header_table.section_table_element[off].s_offset; + + return -1; +} + +int SectionHasData( Elf64_Half s_index ) { + // This is ridiculously slow for some reason, so cache our results in an array + if( sec_tbl_elem[s_index] == -1 ) { + sec_tbl_elem[s_index] = exists( file.section_header_table.section_table_element[s_index].s_data ); + } + return sec_tbl_elem[s_index]; +} + +quad SectionVAddrOffset( Elf64_Half s_index, Elf64_Addr s_vaddr ) { + if( s_index < file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES ) { + return file.section_header_table.section_table_element[s_index].s_offset + s_vaddr - + file.section_header_table.section_table_element[s_index].s_addr; + } + return 0; +} + +// Structure of elf +struct { + local int i; + for( i=0; i<255; i++ ) { + sec_tbl_elem[i] = -1; + } + + struct { + e_ident_t e_ident; + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) + { + //32-Bit definitions of ELF Header + e_type32_e e_type; + e_machine32_e e_machine; + e_version32_e e_version; + Elf32_Addr e_entry_START_ADDRESS; + Elf32_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE; + Elf32_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE; + Elf32_Word e_flags; + Elf32_Half e_ehsize_ELF_HEADER_SIZE; + Elf32_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE; + Elf32_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES; + Elf32_Half e_shentzise_SECTION_HEADER_ENTRY_SIZE; + Elf32_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; + Elf32_Half e_shtrndx_STRING_TABLE_INDEX; + } + else + { + //64-Bit definitions of ELF Header + e_type64_e e_type; + e_machine64_e e_machine; + e_version64_e e_version; + Elf64_Addr e_entry_START_ADDRESS; + Elf64_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE; + Elf64_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE; + Elf32_Word e_flags; + Elf64_Half e_ehsize_ELF_HEADER_SIZE; + Elf64_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE; + Elf64_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES; + Elf64_Half e_shentzise_SECTION_HEADER_ENTRY_SIZE; + Elf64_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; + Elf64_Half e_shtrndx_STRING_TABLE_INDEX; + } + } elf_header; + + // Find the program table + if( file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES > 0 ) { + FSeek(file.elf_header.e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + program_table_entry32_t program_table_element[file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES]; + } else { + program_table_entry64_t program_table_element[file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES]; + } + } program_header_table; + } + + // Find the header name location + local quad section_name_off = + file.elf_header.e_shoff_SECTION_HEADER_OFFSET_IN_FILE + + ( file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE * + file.elf_header.e_shtrndx_STRING_TABLE_INDEX ); + + // Find the header name block + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + if( FileSize() >= section_name_off + 2 * sizeof( Elf32_Word ) + + sizeof( Elf32_Xword ) + sizeof( Elf32_Addr ) ) + section_name_block_off = ReadUInt( section_name_off + 2 * sizeof( Elf32_Word ) + + sizeof( Elf32_Xword ) + sizeof( Elf32_Addr ) ); + else { + Printf("Invalid section header found, skipping!\n"); + Warning("Invalid section header found, skipped and attempting to continue..."); + } + } else { + if( FileSize() >= section_name_off + 2 * sizeof( Elf64_Word ) + + sizeof( Elf64_Xword ) + sizeof( Elf64_Addr ) ) + section_name_block_off = ReadUQuad( section_name_off + 2 * sizeof( Elf64_Word ) + + sizeof( Elf64_Xword ) + sizeof( Elf64_Addr ) ); + else { + Printf("Invalid section header found, skipping!\n"); + Warning("Invalid section header found, skipped and attempting to continue..."); + } + } + + local int sec_tbl_cur_elem; + // Find the section headers + if( file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES > 0 ) { + FSeek(file.elf_header.e_shoff_SECTION_HEADER_OFFSET_IN_FILE); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + sec_tbl_cur_elem = 0; + section_table_entry32_t section_table_element[file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES]; + } else { + sec_tbl_cur_elem = 0; + section_table_entry64_t section_table_element[file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES]; + } + } section_header_table; + } + + local int sym_sect; + local int sym_name_sect; + + // Find the symbol section + sym_sect = FindNamedSection( ".symtab" ); + if( sym_sect >= 0 ) { + sym_name_sect = file.section_header_table.section_table_element[sym_sect].s_link; + symbol_name_block_off = file.section_header_table.section_table_element[sym_name_sect].s_offset; + + FSeek( file.section_header_table.section_table_element[sym_sect].s_offset ); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + Elf32_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf32_Sym_fixed)]; + } else { + Elf64_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf64_Sym_fixed)]; + } + } symbol_table; + } + + // Find the dynamic symbol section + sym_sect = FindNamedSection( ".dynsym" ); + if( sym_sect >= 0 ) { + sym_name_sect = file.section_header_table.section_table_element[sym_sect].s_link; + symbol_name_block_off = file.section_header_table.section_table_element[sym_name_sect].s_offset; + + FSeek( file.section_header_table.section_table_element[sym_sect].s_offset ); + struct { + if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { + Elf32_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf32_Sym_fixed)]; + } else { + Elf64_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf64_Sym_fixed)]; + } + } dynamic_symbol_table; + } +} file; \ No newline at end of file diff --git a/cparser/EMFTemplate.bt b/cparser/EMFTemplate.bt new file mode 100644 index 0000000..40c3e5b --- /dev/null +++ b/cparser/EMFTemplate.bt @@ -0,0 +1,221 @@ +//-------------------------------------- +//--- 010 Editor v2.1.3 Binary Template +// +// File: EMFTemplate.bt +// Author: Dustin D. Trammell +// Revision: 0.1 +// Date: 2008/04/08 - 2008/04/08 +// Purpose: Parsing EMF files. +// References: +// MS-EMF: Enhanced Metafile Format Specification 2.1, Microsoft +//-------------------------------------- + +typedef enum { + EMR_HEADER = 0x00000001, + EMR_POLYBEZIER = 0x00000002, + EMR_POLYGON = 0x00000003, + EMR_POLYLINE = 0x00000004, + EMR_POLYBEZIERTO = 0x00000005, + EMR_POLYLINETO = 0x00000006, + EMR_POLYPOLYLINE = 0x00000007, + EMR_POLYPOLYGON = 0x00000008, + EMR_SETWINDOWEXTEX = 0x00000009, + EMR_SETWINDOWORGEX = 0x0000000A, + EMR_SETVIEWPORTEXTEX = 0x0000000B, + EMR_SETVIEWPORTORGEX = 0x0000000C, + EMR_SETBRUSHORGEX = 0x0000000D, + EMR_EOF = 0x0000000E, + EMR_SETPIXELV = 0x0000000F, + EMR_SETMAPPERFLAGS = 0x00000010, + EMR_SETMAPMODE = 0x00000011, + EMR_SETBKMODE = 0x00000012, + EMR_SETPOLYFILLMODE = 0x00000013, + EMR_SETROP2 = 0x00000014, + EMR_SETSTRETCHBLTMODE = 0x00000015, + EMR_SETTEXTALIGN = 0x00000016, + EMR_SETCOLORADJUSTMENT = 0x00000017, + EMR_SETTEXTCOLOR = 0x00000018, + EMR_SETBKCOLOR = 0x00000019, + EMR_OFFSETCLIPRGN = 0x0000001A, + EMR_MOVETOEX = 0x0000001B, + EMR_SETMETARGN = 0x0000001C, + EMR_EXCLUDECLIPRECT = 0x0000001D, + EMR_INTERSECTCLIPRECT = 0x0000001E, + EMR_SCALEVIEWPORTEXTEX = 0x0000001F, + EMR_SCALEWINDOWEXTEX = 0x00000020, + EMR_SAVEDC = 0x00000021, + EMR_RESTOREDC = 0x00000022, + EMR_SETWORLDTRANSFORM = 0x00000023, + EMR_MODIFYWORLDTRANSFORM = 0x00000024, + EMR_SELECTOBJECT = 0x00000025, + EMR_CREATEPEN = 0x00000026, + EMR_CREATEBRUSHINDIRECT = 0x00000027, + EMR_DELETEOBJECT = 0x00000028, + EMR_ANGLEARC = 0x00000029, + EMR_ELLIPSE = 0x0000002A, + EMR_RECTANGLE = 0x0000002B, + EMR_ROUNDRECT = 0x0000002C, + EMR_ARC = 0x0000002D, + EMR_CHORD = 0x0000002E, + EMR_PIE = 0x0000002F, + EMR_SELECTPALETTE = 0x00000030, + EMR_CREATEPALETTE = 0x00000031, + EMR_SETPALETTEENTRIES = 0x00000032, + EMR_RESIZEPALETTE = 0x00000033, + EMR_REALIZEPALETTE = 0x00000034, + EMR_EXTFLOODFILL = 0x00000035, + EMR_LINETO = 0x00000036, + EMR_ARCTO = 0x00000037, + EMR_POLYDRAW = 0x00000038, + EMR_SETARCDIRECTION = 0x00000039, + EMR_SETMITERLIMIT = 0x0000003A, + EMR_BEGINPATH = 0x0000003B, + EMR_ENDPATH = 0x0000003C, + EMR_CLOSEFIGURE = 0x0000003D, + EMR_FILLPATH = 0x0000003E, + EMR_STROKEANDFILLPATH = 0x0000003F, + EMR_STROKEPATH = 0x00000040, + EMR_FLATTENPATH = 0x00000041, + EMR_WIDENPATH = 0x00000042, + EMR_SELECTCLIPPATH = 0x00000043, + EMR_ABORTPATH = 0x00000044, + EMR_RESERVED_69 = 0x00000045, + EMR_COMMENT = 0x00000046, + EMR_FILLRGN = 0x00000047, + EMR_FRAMERGN = 0x00000048, + EMR_INVERTRGN = 0x00000049, + EMR_PAINTRGN = 0x0000004A, + EMR_EXTSELECTCLIPRGN = 0x0000004B, + EMR_BITBLT = 0x0000004C, + EMR_STRETCHBLT = 0x0000004D, + EMR_MASKBLT = 0x0000004E, + EMR_PLGBLT = 0x0000004F, + EMR_SETDIBITSTODEVICE = 0x00000050, + EMR_STRETCHDIBITS = 0x00000051, + EMR_EXTCREATEFONTINDIRECTW = 0x00000052, + EMR_EXTTEXTOUTA = 0x00000053, + EMR_EXTTEXTOUTW = 0x00000054, + EMR_POLYBEZIER16 = 0x00000055, + EMR_POLYGON16 = 0x00000056, + EMR_POLYLINE16 = 0x00000057, + EMR_POLYBEZIERTO16 = 0x00000058, + EMR_POLYLINETO16 = 0x00000059, + EMR_POLYPOLYLINE16 = 0x0000005A, + EMR_POLYPOLYGON16 = 0x0000005B, + EMR_POLYDRAW16 = 0x0000005C, + EMR_CREATEMONOBRUSH = 0x0000005D, + EMR_CREATEDIBPATTERNBRUSHPT = 0x0000005E, + EMR_EXTCREATEPEN = 0x0000005F, + EMR_POLYTEXTOUTA = 0x00000060, + EMR_POLYTEXTOUTW = 0x00000061, + EMR_SETICMMODE = 0x00000062, + EMR_CREATECOLORSPACE = 0x00000063, + EMR_SETCOLORSPACE = 0x00000064, + EMR_DELETECOLORSPACE = 0x00000065, + EMR_GLSRECORD = 0x00000066, + EMR_GLSBOUNDEDRECORD = 0x00000067, + EMR_PIXELFORMAT = 0x00000068, + EMR_DRAWESCAPE = 0x00000069, + EMR_EXTESCAPE = 0x0000006A, + EMR_RESERVED_107 = 0x0000006B, + EMR_SMALLTEXTOUT = 0x0000006C, + EMR_FORCEUFIMAPPING = 0x0000006D, + EMR_NAMEDESCAPE = 0x0000006E, + EMR_COLORCORRECTPALETTE = 0x0000006F, + EMR_SETICMPROFILEA = 0x00000070, + EMR_SETICMPROFILEW = 0x00000071, + EMR_ALPHABLEND = 0x00000072, + EMR_SETLAYOUT = 0x00000073, + EMR_TRANSPARENTBLT = 0x00000074, + EMR_RESERVED_117 = 0x00000075, + EMR_GRADIENTFILL = 0x00000076, + EMR_SETLINKEDUFIS = 0x00000077, + EMR_SETTEXTJUSTIFICATION = 0x00000078, + EMR_COLORMATCHTOTARGETW = 0x00000079, + EMR_CREATECOLORSPACEW = 0x0000007A +} RecordType; + +typedef struct { + LONG cx; + LONG cy; +} SIZEL; + +typedef struct _RECTL { + LONG left; + LONG top; + LONG right; + LONG bottom; +} RECTL; + +typedef struct { + RecordType iType; // Record type EMR_HEADER. + DWORD nSize; // Record size in bytes. This may be greater + // than the sizeof(ENHMETAHEADER). + RECTL rclBounds; // Inclusive-inclusive bounds in device units. + RECTL rclFrame; // Inclusive-inclusive Picture Frame of + // metafile in .01 mm units. + DWORD dSignature; // Signature. Must be ENHMETA_SIGNATURE. + DWORD nVersion; // Version number. + DWORD nBytes; // Size of the metafile in bytes. + DWORD nRecords; // Number of records in the metafile. + WORD nHandles; // Number of handles in the handle table. + // Handle index zero is reserved. + WORD sReserved; // Reserved. Must be zero. + DWORD nDescription; // Number of chars in the unicode description string. + // This is 0 if there is no description string. + DWORD offDescription; // Offset to the metafile description record. + // This is 0 if there is no description string. + DWORD nPalEntries; // Number of entries in the metafile palette. + SIZEL szlDevice; // Size of the reference device in pixels. + SIZEL szlMillimeters; // Size of the reference device in millimeters. +} Header; + +typedef struct { + WORD desc[header.nDescription]; +} Description; + +typedef struct { + RecordType iType; // Record type EMR_XXX + DWORD nSize; // Record size in bytes + DWORD dParm[((nSize-8)/4)]; // DWORD Array of parameters +} Record; + +typedef struct { + uchar Reserved; + uchar Blue; + uchar Green; + uchar Red; +} PaletteEntry; + +// START + +LittleEndian(); + +// Header +Header header; + +// Optional Description +FSeek(header.offDescription); +Description description; + +// Start of Records (after header) +FSeek(header.nSize); + +// Parse the number of records indicated in the header +local int recCnt = 0; +for( recCnt = 0; recCnt < header.nRecords - 1; recCnt++ ) { + Record record; +} +// If the last record wasn't EMR_EOF, there should be more records +// even though they exceed the count in the header +do { + Record extrarecord; + recCnt++; +} while( record[recCnt-1].iType != EMR_EOF); + +// Check last record or header for presence of Palette +local int palCnt = 0; +for( palCnt = 0; palCnt < header.nPalEntries; palCnt++ ) { + PaletteEntry paletteentry; +} + diff --git a/cparser/EOTTemplate.bt b/cparser/EOTTemplate.bt new file mode 100644 index 0000000..afa6116 --- /dev/null +++ b/cparser/EOTTemplate.bt @@ -0,0 +1,78 @@ +//------------------------------------ +//--- 010 Editor v2.01 Binary Template +// +// Name: EOTTemplate.bt +// Author: Neo (Jiepeng) Tan +// Revision: 1.0 +// Purpose: Parse an Embedded OpenType (EOT) File Format for Version: 0x00020002 +// Reference: http://www.w3.org/Submission/EOT/ +//------------------------------------ + +LittleEndian(); + + +typedef enum {TTEMBED_SUBSET = 0x1, +TTEMBED_TTCOMPRESSED = 0x4, +TTEMBED_FAILIFVARIATIONSIMULATED = 0x10, +TTMBED_EMBEDEUDC = 0x00000020, +TTEMBED_VALIDATIONTESTS = 0x00000040, +TTEMBED_WEBOBJECT = 0x00000080, +TTEMBED_XORENCRYPTDATA = 0x10000000 +} TTEMBED; + +typedef struct embedded_opentype_file { + unsigned long EOTSize; + unsigned long FontDataSize; + unsigned long Version; + TTEMBED Flags;//processing flags #define TTEMBED_TTCOMPRESSED 0x00000004 + byte FontPANOSE[10]; + byte Charset; + byte Italic; + unsigned long Weight; + unsigned short fsType; + unsigned short MagicNumber;//Magic number for EOT file - 0x504C + unsigned long UnicodeRange1; + unsigned long UnicodeRange2; + unsigned long UnicodeRange3; + unsigned long UnicodeRange4; + unsigned long CodePageRange1; + unsigned long CodePageRange2; + unsigned long CheckSumAdjustment; + unsigned long Reserved1;//must be 0 + unsigned long Reserved2;//must be 0 + unsigned long Reserved3;//must be 0 + unsigned long Reserved4;//must be 0 + unsigned short Padding1;//always 0x0000 + unsigned short FamilyNameSize; + byte FamilyName[FamilyNameSize]; + + unsigned short Padding2;//always 0x0000 + unsigned short StyleNameSize; + byte StyleName[StyleNameSize]; + + unsigned short Padding3;//always 0x0000 + unsigned short VersionNameSize; + byte VersionName[VersionNameSize]; + + unsigned short Padding4;//always 0x0000 + unsigned short FullNameSize; + byte FullName[FullNameSize]; + + unsigned short Padding5;//always 0x0000 + unsigned short RootStringSize; + byte RootString[RootStringSize]; + unsigned long RootStringCheckSum; + unsigned long EUDCCodePage; + unsigned short Padding6; + unsigned short SignatureSize; + byte Signature[SignatureSize]; + unsigned long EUDCFlags; + unsigned long EUDCFontSize; + byte EUDCFontData[EUDCFontSize]; + byte FontData[FontDataSize]; +}; + +LittleEndian(); + +FSeek(0); +embedded_opentype_file EOT; \ No newline at end of file diff --git a/cparser/EVSBTemplate.bt b/cparser/EVSBTemplate.bt new file mode 100644 index 0000000..457a77a --- /dev/null +++ b/cparser/EVSBTemplate.bt @@ -0,0 +1,104 @@ +//---------------------------------------------------------------------------- +//--- 010 Editor v2.0.2 Binary Template +// +// File: EVSB_Symbol_Display +// Author: Kip Leitner, Panasonic, PSDC NJ, USA, kleitner@pavcal.com +// Revision: 1.0 21 January, 2006 +// +// Purpose: Decompose EVSB Over-the-Air (OTA) symbols for DTV Transmission +// +// Ref: ATSC Digital Television standard (A/53), Revision D +// Including Ammendment 1 +// 19 July 2005 +// Data Organization (Sect 5.3) +//---------------------------------------------------------------------------- +// Setups for 010 View --> Width --> custom (832) to see segment synks +// View --> Width --> custom (64) to Field sync details +// +// modify template for your own frame length +const int Frame_Count = 951; + + +//---------------------------------------------------------------------------- +typedef struct SYNC_SEGMENT_EVEN + { + SetBackColor(cRed); + char Sync[4]; + SetBackColor(cPurple); + char PN511[511]; + SetBackColor(cLtBlue); + char PN63_a[63]; + SetBackColor(cBlue); + char PN63_b[63]; + SetBackColor(cLtBlue); + char PN63_c[63]; + SetBackColor(cLtGreen); + char VSB_Mode[24]; + SetBackColor(cAqua); + char Kerdock[64]; + SetBackColor(cNone); + char Reserved_a[28]; + SetBackColor(cSilver); + char Reserved_b[12]; + } Sync_Segment_Even; + +typedef struct SYNC_SEGMENT_ODD + { + SetBackColor(cLtRed); + char Sync[4]; + SetBackColor(cPurple); + char PN511[511]; + SetBackColor(cLtBlue); + char PN63_a[63]; + SetBackColor(cBlue); + char PN63_b[63]; + SetBackColor(cLtBlue); + char PN63_c[63]; + SetBackColor(cLtGreen); + char VSB_Mode[24]; + SetBackColor(cAqua); + char Kerdock[64]; + SetBackColor(cNone); + char Reserved_a[28]; + SetBackColor(cSilver); + char Reserved_b[12]; + } Sync_Segment_Odd; + +typedef struct DATA_SEGMENT_EVEN + { + SetBackColor(cRed); + char Data_Segment_Sync[4]; + SetBackColor(cNone); + char Payload_Even[828]; + } Data_Segment_Even; + +typedef struct DATA_SEGMENT_ODD + { + SetBackColor(cLtRed); + char Data_Segment_Sync[4]; + SetBackColor(cNone); + char Payload_Odd[828]; + } Data_Segment_Odd; + +typedef struct FIELD_EVEN + { + Sync_Segment_Even Sync_Seg_Even[1]; + Data_Segment_Even Data_Seg_Even[312]; + } Field_Even; + +typedef struct FIELD_ODD + { + Sync_Segment_Odd Sync_Seg_Odd[1]; + Data_Segment_Odd Data_Seg_Odd[312]; + } Field_Odd; + +typedef struct FRAME + { + Field_Even F_Even; + Field_Odd F_Odd; + } Frame; + +struct FILE + { + Frame Frames[Frame_Count]; + } File; \ No newline at end of file diff --git a/cparser/EXETemplate.bt b/cparser/EXETemplate.bt new file mode 100644 index 0000000..4a93eac --- /dev/null +++ b/cparser/EXETemplate.bt @@ -0,0 +1,384 @@ +//------------------------------------ +//--- 010 Editor v1.2 Binary Template +// +// Autor: Blaine Lefebvre +// Purpose: display the structure of an exe file +// File mask: *.exe,*.dll +// Update: Sergey Evtushenko wildcar@mail.ru +// 2014/07/25: Added Resource structure decode + +// DOS exe format +typedef struct { + char Signature[2]; + if ( Memcmp(Signature,"MZ",2) ) + { + Warning("Invalid file format"); + return 1; + } + WORD LengthOfImage; + WORD SizeOfFile; + WORD NumberOfRelocationItems; + WORD SizeOfHeader; + WORD MinPara; + WORD MaxPara; + WORD OffsetStack; + WORD InitialSp; + WORD NegativeChecksum; + WORD InitialIp; + WORD OffsetCs; + WORD OffsetFirstRelocationItem; + WORD OverlayNumber; + WORD Res1; + WORD Res2; + WORD Res3; + WORD Res4; + WORD OemId; + WORD OemInfo; + WORD Res5[10]; + DWORD OffsetToPEHeader; +} DosExeHeader; + +typedef struct { + int32 DirExport; + int32 DirExportSize; + int32 DirImport; + int32 DirImportSize; + int32 DirResource; + int32 DirResourceSize; + int32 DirException; + int32 DirExceptionSize; + int32 DirSecurity; + int32 DirSecuritySize; + int32 DirBasereloc; + int32 DirBaserelocSize; + int32 DirDebug; + int32 DirDebugSize; + int32 DirArchitecture; + int32 DirArchitectureSize; + int32 DirGlobalptr; + int32 DirGlobalptrSize; + int32 DirTls; + int32 DirTlsSize; + int32 DirLoadConfig; + int32 DirLoadConfig_size; + int32 DirBoundImport; + int32 DirBoundImportSize; + int32 DirIat; + int32 DirIatSize; + int32 DirDelayImport; + int32 DirDelayImportSize; + int32 DirComDescriptor; + int32 DirComDescriptorSize; + int32 DirX; + int32 DirXSize; +} DataDirectory; + +typedef struct { + int32 rva; + int32 size; +} DataDir; + +typedef struct { + char Sig[4]; + if ( Memcmp(Sig,"PE",2) ) + { + Warning("Invalid file format"); + return 1; + } + int16 CpuType; + int16 NumSections; + time_t Tm; + int32 PointerToSymbolTable; + int32 NumberOfSymbols; + int16 NtHeaderSize; + int16 Flags; +} PeHeader; + +typedef struct { + int16 Res3; + char LMajor; + char LMinor; + int32 SizeOfCode; + int32 SizeOfInitData; + int32 SizeOfUninitData; + int32 EntrypointRva; + int32 BaseOfCode; + int32 BaseOfData; + int32 ImageBase; + int32 SectionAlign; + int32 FileAlign; + int16 OsMajor; + int16 OsMinor; + int16 UserMajor; + int16 UserMinor; + int16 SubsystemMajor; + int16 SubsystemMinor; + int32 Win32VersionValue; + int32 ImageSize; + int32 HeaderSize; + int32 FileChecksum; + int16 Subsystem; + int16 DllFlags; + int32 StackReserveSize; + int32 StackCommitSize; + int32 HeapReserveSize; + int32 HeapCommitSize; + int32 LoaderFlags; + int32 NumInterestingRvaSize; + } OptionalHeader; + +typedef struct{ + char Name[8]; + int32 VirtualSize; + int32 VirtualAddress; + int32 SizeOfRawData; + int32 PointerToRawData; + int32 PointerToRelocations; + int32 PointerToLinenumbers; + int16 NumberOfRelocations; + int16 NumberOfLinenumbers; + int32 Characteristics; +} SectionTable; + +void GetResourceDirectory() + { + res_level+=1; + struct + { + local int32 j; + uint32 Characteristics; + DOSTIME TimeStamp; + DOSDATE DataStamp; + uint16 MajorVersion; + uint16 MinorVersion; + uint16 NumberOfNameEntries; + uint16 NumberOfIDEntries; + for( j=0;j; + int TopBit:1; + currentaddress= FTell(); + FSeek(resource_sa+NameRVA); + int16 Length; + wchar_t UnicodeString[Length]; + if (res_show_log==1){Printf("\nLevel %d. ",res_level);} + if (res_show_log==1){Printf("Name: %s",UnicodeString);} + FSeek(currentaddress); + + uint32 DataEntryRVA:31 ; + int PointToChild:1; + currentaddress= FTell(); + if (PointToChild==1) + { + FSeek(resource_sa+DataEntryRVA); + GetResourceDirectory(); + FSeek(currentaddress); + }; + } DirectoryNameEntry; + }; + for( j=0;j; + rTypeID=IntegerID; + if (res_show_log==1){Printf("\n%s",ShowType(rTypeID));} + break; + case 2: + uint32 IntegerID ; + rNameID=IntegerID; + if (res_show_log==1){Printf("\n%s",ShowName(rNameID));} + break; + case 3: + uint32 IntegerID ; + rLanguageID=IntegerID; + if (res_show_log==1){Printf("\n%s",ShowLanguage(rLanguageID));} + break; + } + uint32 DataEntryRVA:31 ; + int PointToChild:1; + currentaddress= FTell(); + if (PointToChild==1) + { + FSeek(resource_sa+DataEntryRVA); + GetResourceDirectory(); + FSeek(currentaddress); + } + else + { + FSeek(resource_sa+DataEntryRVA); + struct + { + local int64 ba1, ba2; + int32 DataRVA ; + int32 Size; + int32 Codepage; + int32 Reserved; + FSeek(DataRVA-(SectionVirtualAddress-resource_sa)); + if (rTypeID==16) + { + struct + { + ba1=FTell(); + char VersionInfoRAWData[Size]; + ba2=FTell(); + FSeek(ba1); + struct{} VersionInfoStructure; + FSeek(ba2); + } versioninfo; + } + else + { + char ResourceRAWData[Size]; + }; + } DataEntry; + FSeek(currentaddress); + }; + } DirectoryIDEntry; + }; + } DirectoryTable; + res_level-=1; + }; + +string ShowType(uint32 ID) + { + local string s; + switch( ID) + { + case 1: s="Cursor";break; + case 2: s="Bitmap";break; + case 3: s="Icon";break; + case 4: s="Menu";break; + case 5: s="Dialog box";break; + case 6: s="String table entry";break; + case 7: s="Font directory";break; + case 8: s="Font";break; + case 9: s="Accelerator table";break; + case 10: s="Application defined resource (raw data)";break; + case 11: s="Message table entry";break; + case 12: s="Group cursor";break; + case 14: s="Group icon";break; + case 16: s="Version information";break; + case 17: s="Dlginclude";break; + case 19: s="Plug and play resource";break; + case 20: s="VXD";break; + case 21: s="Animated cursor";break; + case 22: s="Animated icon";break; + case 23: s="HTML";break; + case 24: s="Side-by-side assembly manifest";break; + } + SPrintf( s, "Level 1. Resource type: %s", s ); + return s; + } +string ShowName(uint32 ID) + { + local string s; + SPrintf( s, "Level 2. Name ID: %d", ID ); + return s; + } + +string ShowLanguage(uint32 ID) + { + local string s; + SPrintf( s, "Level 3. Language ID: %d", ID ); + return s; + } +//////////////////////////////////////////////////////////////// + +local int32 i, done, j; +local int32 rTypeID, rNameID, rLanguageID; +local int64 resource_sa, resource_ea, res_level; +local int64 SectionVirtualAddress; +local int res_show_log=0; +SetBackColor(cLtGray); +DosExeHeader DOSHead; + +char dosstub[DOSHead.OffsetToPEHeader-(DOSHead.SizeOfHeader*0x10)]; + +PeHeader PEHead; + +OptionalHeader OptionalHead; + +DataDir dd[16]; + +SectionTable sec[PEHead.NumSections]; + +for ( i = 0 ; i < PEHead.NumSections ; i++ ) + { + done = 0; + FSeek(sec[i].PointerToRawData); + if ( !Strcmp(sec[i].Name,".text") ) + { + char textsection[sec[i].SizeOfRawData]; + done = 1; + } + if ( !Strcmp(sec[i].Name,".bss") ) + { + char bsssection[sec[i].SizeOfRawData]; + done = 1; + } + if ( !Strcmp(sec[i].Name,".rsrc") ) + { + struct + { + resource_sa= FTell(); + SectionVirtualAddress=sec[i].VirtualAddress; + char rawrsrcsection[sec[i].SizeOfRawData]; + resource_ea= FTell(); + FSeek(resource_sa); + struct + { + if (res_show_log==1){Printf("\nResources list.");} + res_level=0; + GetResourceDirectory(); + } ResourcesStructure; + FSeek(resource_ea); + } rsrcsection; + done = 1; + } + if ( !Strcmp(sec[i].Name,".rdata") ) + { + char rdatasection[sec[i].SizeOfRawData]; + done = 1; + } + if ( !Strcmp(sec[i].Name,".data") ) + { + char datasection[sec[i].SizeOfRawData]; + done = 1; + } + if ( !Strcmp(sec[i].Name,".edata") ) + { + char edatasection[sec[i].SizeOfRawData]; + done = 1; + } + if ( !Strcmp(sec[i].Name,".idata") ) + { + char idatasection[sec[i].SizeOfRawData]; + done = 1; + } + if ( !Strcmp(sec[i].Name,".pdata") ) + { + char pdatasection[sec[i].SizeOfRawData]; + done = 1; + } + if ( !Strcmp(sec[i].Name,".debug") ) + { + char debugsection[sec[i].SizeOfRawData]; + done = 1; + } + if ( done == 0 ) + { + struct + { + char unknownsection[sec[i].SizeOfRawData]; + } unknown; + } + } diff --git a/cparser/EXETemplate2.bt b/cparser/EXETemplate2.bt new file mode 100644 index 0000000..1df40d5 --- /dev/null +++ b/cparser/EXETemplate2.bt @@ -0,0 +1,420 @@ +//-------------------------------------- +//--- 010 Editor v2.0.2 Binary Template +// +// Author: Peter Kankowski http://smallcode.weblogs.us +// File mask: *.exe,*.dll,*.scr,*.8b?,*.drv,*.ocx +// Purpose: to display executable file headers. +// Supports DLLs, Windows CE and Win64 executables. +// Displays informative names for all flags and fields. +// Update: Didier Stevens https://DidierStevens.com +// 2010/09/05: Added DYNAMIC_BASE, FORCE_INTEGRITY, NX_COMPAT and NO_ISOLATION to DLLCHARACTERISTICS struct +//-------------------------------------- +// Recommended reading: +// 1. Bernd Luevelsmeyer. The PE file format +// http://webster.cs.ucr.edu/Page_TechDocs/pe.txt +// 2. DJ Delorie. MS DOS EXE format +// http://www.delorie.com/djgpp/doc/exe/ +// 3. Iczelion. PE tutorial +// http://spiff.tripnet.se/~iczelion/tutorials.html +LittleEndian(); + +typedef struct { // DOS .EXE header + WORD MZSignature ; + if(MZSignature != 0x5A4D) { // "MZ" + Warning("Not a valid EXE file"); + return 1; + } + // One page is 512 bytes, one paragraph is 16 bytes + WORD UsedBytesInTheLastPage; + WORD FileSizeInPages; + WORD NumberOfRelocationItems; + WORD HeaderSizeInParagraphs; + WORD MinimumExtraParagraphs; + WORD MaximumExtraParagraphs; + WORD InitialRelativeSS ; + WORD InitialSP ; + WORD Checksum ; + WORD InitialIP ; + WORD InitialRelativeCS ; + WORD AddressOfRelocationTable ; + WORD OverlayNumber; + WORD Reserved[4]; + WORD OEMid; + WORD OEMinfo; + WORD Reserved2[10]; + LONG AddressOfNewExeHeader ; +} IMAGE_DOS_HEADER; + +typedef struct { + WORD Offset; + WORD Segment; +} DOS_RELOCATION_TABLE_ITEM; + +typedef enum {IMAGE_FILE_MACHINE_UNKNOWN = 0, IMAGE_FILE_MACHINE_I386 = 0x014c, +IMAGE_FILE_MACHINE_AMD64 = 0x8664, IMAGE_FILE_MACHINE_ARM = 0x01c0, + +IMAGE_FILE_MACHINE_R3000 = 0x0162, // Rarely used +IMAGE_FILE_MACHINE_R4000 = 0x0166, IMAGE_FILE_MACHINE_R10000 = 0x0168, +IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x0169, IMAGE_FILE_MACHINE_ALPHA = 0x0184, +IMAGE_FILE_MACHINE_SH3 = 0x01a2, IMAGE_FILE_MACHINE_SH3DSP = 0x01a3, +IMAGE_FILE_MACHINE_SH3E = 0x01a4, IMAGE_FILE_MACHINE_SH4 = 0x01a6, +IMAGE_FILE_MACHINE_SH5 = 0x01a8, IMAGE_FILE_MACHINE_THUMB = 0x01c2, +IMAGE_FILE_MACHINE_AM33 = 0x01d3, IMAGE_FILE_MACHINE_POWERPC = 0x01F0, +IMAGE_FILE_MACHINE_POWERPCFP=0x01f1, IMAGE_FILE_MACHINE_IA64 = 0x0200, +IMAGE_FILE_MACHINE_MIPS16 = 0x0266, IMAGE_FILE_MACHINE_ALPHA64 = 0x0284, +IMAGE_FILE_MACHINE_MIPSFPU = 0x0366, IMAGE_FILE_MACHINE_MIPSFPU16=0x0466, +IMAGE_FILE_MACHINE_TRICORE = 0x0520, IMAGE_FILE_MACHINE_CEF = 0x0CEF, +IMAGE_FILE_MACHINE_EBC = 0x0EBC, IMAGE_FILE_MACHINE_M32R = 0x9041, +IMAGE_FILE_MACHINE_CEE = 0xC0EE} MACHINE; + + +typedef struct { + ushort RelocsStripped : 1; + ushort ExecutableImage : 1; // if not set, then OBJ + ushort LineNumsStripped : 1; + ushort LocalSymsStripped : 1; + ushort AggresiveWorksetTrim : 1; + ushort LargeAddressAware : 1; // Can hadle > 2Gb addresses + ushort Reserved : 1; + ushort BytesReversedLo: 1; // Reversed endianess + ushort _32bitMachine: 1; + ushort DebugStripped: 1; + ushort RemovableRunFromSwap: 1; // Should copy to swap file when run from removable media such as CD-ROM + ushort NetRunFromSwap: 1; + ushort System: 1; // File is a system driver + ushort DLL: 1; + ushort UPSystemOnly: 1; // If set, multiprocessor systems are not supported + ushort BytesReversedHi: 1; +} CHARACTERISTICS; + +string ReadCHARACTERISTICS(CHARACTERISTICS &flags) { + string s=""; + if(flags.AggresiveWorksetTrim) Strcat(s,"AggresiveWorksetTrim "); + if(flags.LargeAddressAware) Strcat(s,"LargeAddressAware "); + if(flags.RemovableRunFromSwap) Strcat(s,"RemovableRunFromSwap "); + if(flags.NetRunFromSwap) Strcat(s,"NetRunFromSwap "); + if(flags.System) Strcat(s,"SystemDriver "); + if(flags.DLL) Strcat(s,"DLL "); + if(flags.UPSystemOnly) Strcat(s,"UniprocessorSystemOnly "); + if(flags.BytesReversedLo) Strcat(s,"BytesReversedLo "); + if(flags.BytesReversedHi) Strcat(s,"BytesReversedHi "); + if(flags.DebugStripped) Strcat(s,"NoDebug "); + if(flags.RelocsStripped) Strcat(s, "NoRelocs "); + if(flags.LineNumsStripped) Strcat(s,"NoLineNums "); + if(flags.LocalSymsStripped) Strcat(s,"NoLocalSyms "); + if(flags._32bitMachine) Strcat(s,"32bit "); + if(flags.ExecutableImage) Strcat(s, "Executable "); + return s; +} + +typedef struct { + MACHINE Machine; + WORD NumberOfSections; + time_t TimeDateStamp; + DWORD PointerToSymbolTable ; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + CHARACTERISTICS Characteristics; +} IMAGE_FILE_HEADER; + +typedef enum {UNKNOWN=0, NATIVE=1, WINDOWS_GUI=2, + WINDOWS_CONSOLE=3, OS2_CONSOLE=5, POSIX_CONSOLE=7, NATIVE_WIN9X_DRIVER=8, + WINDOWS_CE_GUI=9, EFI_APPLICATION=10, EFI_BOOT_SERVICE_DRIVER=11, EFI_RUNTIME_DRIVER=12, + EFI_ROM = 13, XBOX = 14} SUBSYSTEM; + +typedef struct { + ushort NOTIFY_DLL_PROCESS_INIT: 1; // Not valid in modern OSes + ushort NOTIFY_DLL_PROCESS_TERM: 1; // Not valid in modern OSes + ushort NOTIFY_DLL_THREAD_TERM: 1; // Not valid in modern OSes + ushort NOTIFY_DLL_THREAD_TERM: 1; // Not valid in modern OSes + ushort Reserved:2; + ushort DYNAMIC_BASE:1; + ushort FORCE_INTEGRITY:1; + ushort NX_COMPAT:1; + ushort NO_ISOLATION:1; + ushort NO_SEH:1; + ushort NO_BIND:1; + ushort Reserved2: 1; + ushort WDM_DRIVER: 1; + ushort Reserved3: 1; + ushort TERMINAL_SERVER_AWARE: 1; +} DLLCHARACTERISTICS; + +typedef struct { + DWORD VirtualAddress ; + DWORD Size; +} DATA_DIR; + +typedef struct { + local int len = OptionalHeader.NumberOfRvaAndSizes; + if(len > 16) + len = 16; + if(len > 0) DATA_DIR Export; + if(len > 1) DATA_DIR Import; + if(len > 2) DATA_DIR Resource; + if(len > 3) DATA_DIR Exception; + if(len > 4) DATA_DIR Security; + if(len > 5) DATA_DIR BaseRelocationTable; + if(len > 6) DATA_DIR DebugDirectory; + if(len > 7) DATA_DIR CopyrightOrArchitectureSpecificData; + if(len > 8) DATA_DIR GlobalPtr; + if(len > 9) DATA_DIR TLSDirectory; + if(len >10) DATA_DIR LoadConfigurationDirectory; + if(len >11) DATA_DIR BoundImportDirectory; + if(len >12) DATA_DIR ImportAddressTable; + if(len >13) DATA_DIR DelayLoadImportDescriptors; + if(len >14) DATA_DIR COMRuntimedescriptor; + if(len >15) DATA_DIR Reserved; +} IMAGE_DATA_DIRECTORIES; + +typedef struct { + // Standard fields. + WORD Magic ; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint ; + DWORD BaseOfCode ; + DWORD BaseOfData ; + // NT additional fields. + DWORD ImageBase ; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum ; + SUBSYSTEM Subsystem; + DLLCHARACTERISTICS DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORIES DataDirectory; +} IMAGE_OPTIONAL_HEADER32; + +typedef struct { + WORD Magic ; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint ; + DWORD BaseOfCode ; + quad ImageBase ; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum ; + SUBSYSTEM Subsystem; + DLLCHARACTERISTICS DllCharacteristics; + quad SizeOfStackReserve; + quad SizeOfStackCommit; + quad SizeOfHeapReserve; + quad SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORIES DataDirectory; +} IMAGE_OPTIONAL_HEADER64; + +typedef struct { + DWORD PESignature ; + if(PESignature != 0x00004550) { // "PE\0\0" + Warning("Not a valid PE file"); + return 1; + } + IMAGE_FILE_HEADER FileHeader; + local short OptionalHeaderMagic = ReadShort(FTell()); + if(OptionalHeaderMagic == 0x10b) + IMAGE_OPTIONAL_HEADER32 OptionalHeader; + else if(OptionalHeaderMagic == 0x20b) + IMAGE_OPTIONAL_HEADER64 OptionalHeader; + else { + Warning("Not a valid PE file %x", OptionalHeaderMagic); + return 1; + } +} IMAGE_NT_HEADERS; + +typedef struct { + DWORD Reserved : 5; + DWORD Code : 1; + DWORD InitializedData: 1; + DWORD UninitializedData : 1; + DWORD Reserved2: 1; + DWORD LinkerInfoOrComments: 1; + DWORD Reserved3: 1; + DWORD LinkerShouldRemove: 1; + DWORD CommonBlockData: 1; + DWORD Reserved4: 1; + DWORD NoDeferSpeculativeExceptions: 1; + DWORD FarData: 1; + DWORD Reserved5: 1; + DWORD PurgeableOr16Bit: 1; + DWORD Locked: 1; + DWORD PreLoad: 1; + DWORD Alignment: 4; + DWORD ExtendedRelocations: 1; + DWORD Discardable: 1; + DWORD NotCachable: 1; + DWORD NotPageable: 1; + DWORD Shareable: 1; + DWORD Executable: 1; + DWORD Readable: 1; + DWORD Writeable: 1; +} SECTION_FLAGS; + +string ReadSECTION_FLAGS(SECTION_FLAGS &flags) { + string s=""; + if(flags.Code) Strcat(s, "Code "); + if(flags.InitializedData) Strcat(s, "InitializedData "); + if(flags.UninitializedData) Strcat(s, "UninitializedData "); + if(flags.LinkerInfoOrComments) Strcat(s, "LinkerInfoOrComments "); + if(flags.LinkerShouldRemove) Strcat(s, "LinkerShouldRemove "); + if(flags.CommonBlockData) Strcat(s, "CommonBlockData "); + if(flags.NoDeferSpeculativeExceptions) Strcat(s, "NoDeferSpeculativeExceptions "); + if(flags.FarData) Strcat(s, "FarData "); + if(flags.PurgeableOr16Bit) Strcat(s, "PurgeableOr16Bit "); + if(flags.Locked) Strcat(s, "Locked "); + if(flags.PreLoad) Strcat(s, "PreLoad "); + if(flags.ExtendedRelocations) Strcat(s, "ExtendedRelocations "); + if(flags.Discardable) Strcat(s, "Discardable "); + if(flags.NotCachable) Strcat(s, "NotCachable "); + if(flags.NotPageable) Strcat(s, "NotPageable "); + if(flags.Shareable) Strcat(s, "Shareable "); + if(flags.Executable) Strcat(s, "Executable "); + if(flags.Readable) Strcat(s, "Readable "); + if(flags.Writeable) Strcat(s, "Writeable "); + if(flags.Alignment) { + string p; + SPrintf(p, "Alignment: %g", Pow(2, flags.Alignment - 1)); + Strcat(s, p); + } + return s; +} + +typedef struct { + BYTE Name[8]; + DWORD VirtualSize; + DWORD VirtualAddress ; + DWORD SizeOfRawData; + DWORD PointerToRawData ; + DWORD NonUsedPointerToRelocations; + DWORD NonUsedPointerToLinenumbers; + WORD NonUsedNumberOfRelocations; + WORD NonUsedNumberOfLinenumbers; + SECTION_FLAGS Characteristics; +} IMAGE_SECTION_HEADER; + +string ReadIMAGE_SECTION_HEADER(IMAGE_SECTION_HEADER §) { + if(exists(sect.Name)) + return sect.Name; + else + return ""; +} + +// Main code start +IMAGE_DOS_HEADER dos_header; +FSeek(dos_header.HeaderSizeInParagraphs * 16); +local int dosstubsize = dos_header.FileSizeInPages * 512; +if(dos_header.UsedBytesInTheLastPage) + dosstubsize -= (512 - dos_header.UsedBytesInTheLastPage); +if(dosstubsize > dos_header.AddressOfNewExeHeader) + dosstubsize = dos_header.AddressOfNewExeHeader; +dosstubsize -= dos_header.HeaderSizeInParagraphs * 16; +local quad richpos; // Microsoft linker signature ("Rich") +local quad richstart, richsize=0; +if((richpos = FindFirst("Rich",true,false,false,0.0,1,FTell(),dosstubsize)) > 0 && + (ReadUInt(richpos - 4) & 0xFFFFFF00) == (ReadUInt(richpos + 4) & 0xFFFFFF00)) { + local int a = 0; + local quad save = FTell(); + FSeek(richpos); // Find the first zero DWORD preceeding richpos + richstart = FindFirst(a, true, false,false,0.0,0,FTell(),richpos-FTell()); + FSeek(save); + richpos += 8; // advance richpos to the end of the "Rich" signature + richstart += 4; // advance richstart to the non-null byte + richsize = richpos - richstart; + dosstubsize = richstart - FTell(); +} +if(dosstubsize > 0) + UCHAR doscode[dosstubsize]; +if(richsize > 0) { + FSeek(richstart); + DWORD MSlinkerSignatureRich[richsize/4]; +} + +if(dos_header.NumberOfRelocationItems) { + FSeek(dos_header.AddressOfRelocationTable); + if(FileSize() - FTell() >= dos_header.NumberOfRelocationItems * + sizeof(DOS_RELOCATION_TABLE_ITEM)) + DOS_RELOCATION_TABLE_ITEM relocation_items[dos_header.NumberOfRelocationItems]; +} + +FSeek(dos_header.AddressOfNewExeHeader); +IMAGE_NT_HEADERS nt_headers; +FSeek(dos_header.AddressOfNewExeHeader + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + + nt_headers.FileHeader.SizeOfOptionalHeader); +IMAGE_SECTION_HEADER sections_table[nt_headers.FileHeader.NumberOfSections]; +local int sectend = FTell(); +local int i, max=0; +for(i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) + if(sections_table[i].PointerToRawData && sections_table[i].SizeOfRawData) { + FSeek(sections_table[i].PointerToRawData); + if(0 == Strcmp(sections_table[i].Name,".text") && !exists(textsection)) + BYTE textsection[sections_table[i].SizeOfRawData]; + else if(0 == Strcmp(sections_table[i].Name,".data") && !exists(datasection)) + BYTE datasection[sections_table[i].SizeOfRawData]; + else if(0 == Strcmp(sections_table[i].Name,".rsrc") && !exists(rsrcsection)) + BYTE rsrcsection[sections_table[i].SizeOfRawData]; + else if(0 == Strcmp(sections_table[i].Name,".idata") && !exists(idatasection)) + BYTE idatasection[sections_table[i].SizeOfRawData]; + else if(0 == Strcmp(sections_table[i].Name,".rdata") && !exists(rdatasection)) + BYTE rdatasection[sections_table[i].SizeOfRawData]; + else if(0 == Strcmp(sections_table[i].Name,".pdata") && !exists(pdatasection)) + BYTE pdatasection[sections_table[i].SizeOfRawData]; + else if(0 == Strcmp(sections_table[i].Name,".reloc") && !exists(relocsection)) + BYTE relocsection[sections_table[i].SizeOfRawData]; + else if(0 == Strcmp(sections_table[i].Name,".edata") && !exists(edatasection)) + BYTE edatasection[sections_table[i].SizeOfRawData]; // Borland's export data + else if(0 == Strcmp(sections_table[i].Name,".tls") && !exists(tlssection)) + BYTE tlssection[sections_table[i].SizeOfRawData]; // Borland's tls section + else if((0 == Strcmp(sections_table[i].Name,"CODE") || + 0 == Strcmp(sections_table[i].Name,".code")) && !exists(codesection)) + BYTE codesection[sections_table[i].SizeOfRawData]; + // Borland's CODE section; ".code" is used by some other linkers + else if(0 == Strcmp(sections_table[i].Name,"DATA") && !exists(datasection)) + BYTE datasection[sections_table[i].SizeOfRawData];// Borland's DATA section + else if(0 == Strcmp(SubStr(sections_table[i].Name,0,3),"UPX") && !exists(upxsection)) + BYTE upxsection[sections_table[i].SizeOfRawData]; // UPX compressor + else if(0 == Strcmp(sections_table[i].Name,".flat") && !exists(fasmsection)) + BYTE fasmsection[sections_table[i].SizeOfRawData]; // Flat Assembler's section + else if(0 == Strcmp(sections_table[i].Name,".aspack") && !exists(aspacksection)) + BYTE aspacksection[sections_table[i].SizeOfRawData]; // Alexey Solodovnikov's packer + else + struct { + BYTE sectiondata[sections_table[i].SizeOfRawData]; + } section; + if(sections_table[i].PointerToRawData + sections_table[i].SizeOfRawData > max) + max = sections_table[i].PointerToRawData + sections_table[i].SizeOfRawData; + } +if(max < FileSize()) { + BYTE Overlay[FileSize()-max]; +} \ No newline at end of file diff --git a/cparser/ElTorito.bt b/cparser/ElTorito.bt new file mode 100644 index 0000000..b943795 --- /dev/null +++ b/cparser/ElTorito.bt @@ -0,0 +1,66 @@ +BitfieldRightToLeft(); +BitfieldDisablePadding(); + +#define BLOCK_SIZE 2048 +#define BOOT_RECORD_OFFSET 2048 * 16 +#define ELTORITO_OFFSET 2048 * 17 + +typedef struct { + ubyte BootIndicator; + char IsoId[5]; + ubyte Version; + char Identifier[32]; + ubyte Unused[32]; + uint32 BootCatalog; + ubyte Unused2[5]; + uint32 VolSpaceSize[2]; +} BOOT_RECORD_DESC; + +typedef union { + struct { + ubyte HeaderId; + ubyte PlatformId; + uint16 Res0; + char Id[24]; + uint16 Checksum ; + uint16 Sig ; // 0xaa55 + } ValEntry; + + struct { + enum { BOOTABLE=0x88, NOT_BOOTABLE=0x0 } BootId ; + enum { NO_EMULATION=0x0, DISKETTE_1_2=0x1, DISKETTE_1_44=0x2, DISKETTE_2_88=0x3, HARDDISK=0x4 } MediaType ; + uint16 LoadSegment ; + ubyte SystemType; + ubyte Unused; + uint16 SectorCount; + uint32 LoadLba; + } DefaultEntry; + + struct { + enum { NOT_LAST_HEADER=0x90, LAST_HEADER=0x91 } HeaderId ; + enum { PC_80x86=0x0, POWERPC=0x1, MAC=0x2 } PlatformId ; + uint16 NumSectionEntries; + char IdString[28]; + } SecHeader; + + struct { + enum { SECTION_BOOTABLE=0x88, SECTION_NOT_BOOTABLE=0x0 } BootId ; + enum { SEC_NO_EMULATION=0x0, SEC_DISKETTE_1_2=0x1, SEC_DISKETTE_1_44=0x2, SEC_DISKETTE_2_88=0x3, SEC_HARDDISK=0x4 } MediaType ; + uint16 LoadSegment ; + ubyte SystemType; + ubyte Unused; + uint16 SectorCount; + uint32 LoadLba; + enum { NO_SELECTION_CRITERIA=0x0, LANGUAGE_AND_VERSION=0x1 } SelectionType; + ubyte Criteria[19]; + } SecEntry; + +} EL_TORITO_ENTRIES; + +LittleEndian(); + +FSeek(ELTORITO_OFFSET); +BOOT_RECORD_DESC boot_record; + +FSeek(boot_record.BootCatalog * BLOCK_SIZE); +EL_TORITO_ENTRIES el_torito[BLOCK_SIZE / sizeof(EL_TORITO_ENTRIES) - 1]; diff --git a/cparser/FAT16Template.bt b/cparser/FAT16Template.bt new file mode 100644 index 0000000..90ef29c --- /dev/null +++ b/cparser/FAT16Template.bt @@ -0,0 +1,154 @@ +//-------------------------------------- +//--- 010 Editor v3.1.2 Binary Template +// +// File: FAT16Template.bt +// Author: +// Revision: +// Purpose: This template can find the +// partitions and display the FAT16 +// partitions on the disk. +//-------------------------------------- + +//-------------------------------------- +//Master Boot record +//-------------------------------------- +typedef struct _CHS +{ + BYTE Head; + BYTE Sector; + BYTE Cylinder; +}CHS; +//-------------------------------------- +typedef union _CHSAddr +{ + CHS chs; + BYTE Address[3]; +}CHSAddr; +//-------------------------------------- +typedef struct _Partion_Table_Entry{ + BYTE Status; + CHSAddr StartCHSAddress; + BYTE PartitionType; + CHSAddr EndCHSAddress; + DWORD FirstLBA; + DWORD TotalSectors; +}Partion_Table_Entry; +//-------------------------------------- +typedef struct { + BYTE Code[446]; + Partion_Table_Entry ptable[4]; + WORD Signature55AA ; + if ( Signature55AA != 0xAA55 ) + { + Warning("Invalid MBR"); + return 1; + } +}MBR; +//-------------------------------------- +//FAT Boot sector FAT12,FAT16 +//-------------------------------------- +typedef struct _FAT16BootSector +{ + BYTE JumpCode[3]; + BYTE OEM_Name[8]; + WORD BytesPerSector; + BYTE SectorsPerCluster; + WORD ReservedSectorCount; //Number of sectors before the first FAT, including the boot sector + BYTE NumberOfFAT; + WORD MAX_RootDirEntry; + WORD TotalSectors; //If Less than 65535 else see offset 0x20 + BYTE MediaDescriptor; + WORD SectorsPerFAT; //For FAT12/16 + WORD SectorsPerTrack; + WORD NumberOfHeads; + DWORD HiddenSectorsBeforePartition; + DWORD TotalSectors; + BYTE PhysicalDriveNumber; + BYTE Reserved; //Current Head + BYTE ExtendedBootSignature; + BYTE SerialNumber[4]; + BYTE VolumeLable[11]; + BYTE FAT_Type[8]; + BYTE BootCode[448]; + WORD BootSectorSignature; //0x55 0xAA +}FAT16BootSector; +//-------------------------------------- +//FAT16 +//-------------------------------------- +local unsigned int FATEntryCount=0; +typedef struct _FAT16 +{ + WORD Table[FATEntryCount]; +}FAT16; +//-------------------------------------- +//FAT root dir entry FAT12,FAT16 +//-------------------------------------- +typedef struct _RootDirEntry +{ + BYTE name[8]; + BYTE extn[3]; + BYTE attributes; + BYTE reserved[10]; + WORD time; + WORD date; + WORD firstDataBlock; + DWORD size; +}RootDirEntry; +//-------------------------------------- +LittleEndian(); +FSeek(0); +//-------------------------------------- +//MBR Object +MBR MasterBootRecord; +//-------------------------------------- +//Partition Info +//-------------------------------------- +local unsigned int partition_index=0; +typedef struct _Fat16Partition +{ + + local unsigned int startBYTE = (MasterBootRecord.ptable[partition_index].FirstLBA*512); + FSeek( startBYTE); + FAT16BootSector BtSector; + + //-------------------------------------- + //Find the FATs + //-------------------------------------- + //Skip the reserved sectors (-1 for accounting the bootrecord) + FSkip((BtSector.ReservedSectorCount-1)*512); + + local unsigned int FATsize = (BtSector.SectorsPerFAT * 512)/2; + local unsigned int FATcnt = 0; + for(FATcnt = 0;FATcnt < BtSector.NumberOfFAT;++FATcnt) + { + FATEntryCount=FATsize; + FAT16 FAT; + } + + //-------------------------------------- + //Find the Root Dir Entries + //-------------------------------------- + RootDirEntry rootDir[BtSector.MAX_RootDirEntry]; + //-------------------------------------- + +}Fat16Partition; +//-------------------------------------- +//disk Info +//-------------------------------------- +typedef struct _Disk +{ + //find all the partitions + local int part; + for(part=0;part<4;++part) + { + if(MasterBootRecord.ptable[part].FirstLBA) + { + partition_index=part; + Fat16Partition FAT16partition; + } + } +}Disk; +//-------------------------------------- +Disk dsk; +//-------------------------------------- + diff --git a/cparser/FLVTemplate.bt b/cparser/FLVTemplate.bt new file mode 100644 index 0000000..2bb3cf6 --- /dev/null +++ b/cparser/FLVTemplate.bt @@ -0,0 +1,92 @@ +//----------------------------------- +//--- 010 Editor v3.0 Binary Template +// +// File: FLVTemplate.bt +// Author: lafei(indep@263.net) +// Revision: 2.1 +// Purpose: Defines a template for +// parsing FLV files. +//----------------------------------- + +// Define structures used in FLV files + +typedef struct { + CHAR signature[3]; //"FLV" + UBYTE version; + UBYTE dummy : 5; + UBYTE audio : 1; //1 if audio present + UBYTE dummy2 : 1; + UBYTE video : 1; //1 if video present + DWORD dataoffset; //in abs. file offset + DWORD zero; //previous tag size +} HEADER; + +local UINT taglen; + +typedef struct { + UINT type : 8; + UINT datasize : 24; + UINT timestamp : 24; + UINT timestamphi : 8; + UINT streamid : 24; + taglen = datasize - 1; + Printf("tag length: %x\n",taglen); + if(type==8) //audio + { + UINT fmt : 4; + UINT sr : 2; + UINT bits : 1; + UINT channels : 1; + if(fmt==10) + { + --taglen; + UBYTE frmtype; + } + } + else if(type==9)//video + { + UINT frmtype : 4; + UINT codecid : 4; + if(codecid==7) + { + taglen -= 4; + UINT pkttype : 8; + UINT compotime : 24; + } + } + else if(type==18)//script + { + UINT fristbyte : 8; + } + UBYTE data[taglen]; + UINT lastsize; //last tag size + + //for debugging + //Printf("lastsize: %x\n",lastsize); + //Printf("Pos: %x\n",FTell()); +} Tag; + +BigEndian(); +SetBackColor( cLtGray ); +HEADER hdr; + +// Check for header +if( hdr.signature != "FLV" ) +{ + Warning( "File is not a FLV. Template stopped." ); + return -1; +} + +if( hdr.version != 1 ) +{ + Warning( "Unsupported FLV version. Template stopped." ); + return -1; +} + +// Define the bytes of the data +SetBackColor( cNone ); + +while( !FEof() ) +{ + Tag tag; +} diff --git a/cparser/GIFTemplate.bt b/cparser/GIFTemplate.bt new file mode 100644 index 0000000..07f1cea --- /dev/null +++ b/cparser/GIFTemplate.bt @@ -0,0 +1,200 @@ +//----------------------------------- +//--- 010 Editor v2.0 Binary Template +// +// File: BMGIFTemplate.bt +// Author: Berend-Jan "SkyLined" Wever +// Revision: 1.1 +// Purpose: Defines a template for +// parsing GIF image files. +// SweetScape: Added bug fixes for +// reading global color table (May 2nd, 2007) +// SweetScape: Added bug fixes for +// reading local color table and +// changed ReadShort to ReadUShort (Sept 25, 2007) +//----------------------------------- + +// From GIF89a Specification: + +// ::= Header * Trailer +// ::= Logical Screen Descriptor [Global Color Table] +// ::= | +// ::= [Graphic Control Extension] +// ::= | Plain Text Extension +// ::= Image Descriptor [Local Color Table] Image Data +// ::= Application Extension | Comment Extension + +LittleEndian(); + +typedef struct { + UBYTE R; + UBYTE G; + UBYTE B; +} RGB ; +string ReadRGB( RGB &color ) +{ + string s; + SPrintf( s, "#%02X%02X%02X", color.R, color.G, color.B ); + return s; +} +typedef struct { + local UBYTE size = ReadUByte(FTell()); + while (size != 0) { + struct DATASUBBLOCK { + UBYTE Size; + char Data[size]; + } DataSubBlock; + size = ReadUByte(FTell()); + } + UBYTE BlockTerminator; +} DATASUBBLOCKS; + +typedef struct { + char Signature[3]; + char Version[3]; +} GIFHEADER; + +typedef struct { + ushort Width; + ushort Height; + BitfieldLeftToRight(); + struct LOGICALSCREENDESCRIPTOR_PACKEDFIELDS { + UBYTE GlobalColorTableFlag : 1; + UBYTE ColorResolution : 3; + UBYTE SortFlag : 1; + UBYTE SizeOfGlobalColorTable : 3; + } PackedFields; + UBYTE BackgroundColorIndex; + UBYTE PixelAspectRatio; +} LOGICALSCREENDESCRIPTOR; + +// ::= Header * Trailer +// Header +SetBackColor( 0xFFFFFF ); +GIFHEADER GifHeader; +if( GifHeader.Signature != "GIF" ) +{ + Warning( "File is not a valid GIF. Template stopped." ); + return -1; +} +// ::= Logical Screen Descriptor [Global Color Table] +// Logical Screen Descriptor +SetBackColor( 0xE0E0E0 ); +LOGICALSCREENDESCRIPTOR LogicalScreenDescriptor; +// [Global Color Table] +if (LogicalScreenDescriptor.PackedFields.GlobalColorTableFlag == 1) { + SetBackColor( 0xC0C0C0 ); + struct GLOBALCOLORTABLE { + local int i; + local int size = 1; + for (i = 0; i <= LogicalScreenDescriptor.PackedFields.SizeOfGlobalColorTable; i++) { + size *= 2; + } + RGB rgb[size]; + } GlobalColorTable ;; +} +// ::= | +SetBackColor( 0xFFFFFF ); +struct DATA { + while (ReadUByte(FTell()) != 0x3B) { + // ::= [Graphic Control Extension] + if (ReadUByte(FTell()) == 0x2C) { + SetBackColor( 0xE0FFE0 ); + struct IMAGEDESCRIPTOR { + UBYTE ImageSeperator; + ushort ImageLeftPosition; + ushort ImageTopPosition; + ushort ImageWidth; + ushort ImageHeight; + struct IMAGEDESCRIPTOR_PACKEDFIELDS { + UBYTE LocalColorTableFlag : 1; + UBYTE InterlaceFlag : 1; + UBYTE SortFlag : 1; + UBYTE Reserved : 2; + UBYTE SizeOfLocalColorTable : 3; + } PackedFields; + } ImageDescriptor; + if (ImageDescriptor.PackedFields.LocalColorTableFlag == 1) { + SetBackColor( 0xC0FFC0 ); + struct LOCALCOLORTABLE { + local int i; + local int size = 1; + for (i = 0; i <= ImageDescriptor.PackedFields.SizeOfLocalColorTable; i++) { + size *= 2; + } + RGB rgb[size]; + } LocalColorTable ;; + } + SetBackColor( 0xA0FFA0 ); + struct IMAGEDATA { + UBYTE LZWMinimumCodeSize; + DATASUBBLOCKS DataSubBlocks; + } ImageData; + } else if (ReadUShort(FTell()) == 0xF921) { + SetBackColor( 0xC0FFFF ); + struct GRAPHICCONTROLEXTENSION { + UBYTE ExtensionIntroducer; // 0x21 + UBYTE GraphicControlLabel; // 0xF9 + struct GRAPHICCONTROLSUBBLOCK { + UBYTE BlockSize; + struct GRAPHICCONTROLEXTENSION_DATASUBBLOCK_PACKEDFIELDS { + UBYTE Reserved : 3; + UBYTE DisposalMethod : 3; + UBYTE UserInputFlag : 1; + UBYTE TransparentColorFlag : 1; + } PackedFields; + ushort DelayTime; + UBYTE TransparentColorIndex; + } GraphicControlSubBlock; + UBYTE BlockTerminator; + } GraphicControlExtension; + } else if (ReadUShort(FTell()) == 0xFE21) { + SetBackColor( 0xFFFFC0 ); + struct COMMENTEXTENSION { + UBYTE ExtensionIntroducer; // 0x21 + UBYTE CommentLabel; // 0xFE + DATASUBBLOCKS CommentData; + } CommentExtension; + } else if (ReadUShort(FTell()) == 0x0121) { + SetBackColor( 0xC0C0C0 ); + struct PLAINTEXTEXTENTION { + UBYTE ExtensionIntroducer; // 0x21 + UBYTE PlainTextLabel; // 0x01 + struct PLAINTEXTSUBBLOCK { + UBYTE BlockSize; + ushort TextGridLeftPosition; + ushort TextGridTopPosition; + ushort TextGridWidth; + ushort TextGridHeight; + UBYTE CharacterCellWidth; + UBYTE CharacterCellHeight; + UBYTE TextForegroundColorIndex; + UBYTE TextBackgroundColorIndex; + } PlainTextSubBlock; + DATASUBBLOCKS PlainTextData; + } PlainTextExtension; + } else if (ReadUShort(FTell()) == 0xFF21) { + SetBackColor( 0xC0C0FF ); + struct APPLICATIONEXTENTION { + UBYTE ExtensionIntroducer; // 0x21 + UBYTE ApplicationLabel; // 0xFF + struct APPLICATIONSUBBLOCK { + UBYTE BlockSize; + char ApplicationIdentifier[8]; + char ApplicationAuthenticationCode[3]; + } ApplicationSubBlock; + DATASUBBLOCKS ApplicationData; + } ApplicationExtension; + } else { + SetBackColor( 0xFF8080 ); + struct UNDEFINEDDATA { + UBYTE ExtensionIntroducer; // 21 + UBYTE Label; // F9 + DATASUBBLOCKS DataSubBlocks; + } UndefinedData; + } + } +} Data; +SetBackColor( 0xFFFFFF ); +struct TRAILER { + UBYTE GIFTrailer; +} Trailer; \ No newline at end of file diff --git a/cparser/GPTTemplate.bt b/cparser/GPTTemplate.bt new file mode 100644 index 0000000..0bff5b8 --- /dev/null +++ b/cparser/GPTTemplate.bt @@ -0,0 +1,68 @@ +//-------------------------------------- +//--- 010 Editor v5.0 Binary Template +// +// File: GPTTemplate +// Author: lurker0ster@gmail.com +// Revision: V1.0 +// Purpose: Guid Partition Table +//-------------------------------------- +typedef struct { + BYTE BootIndicator; + BYTE StartHead; + WORD StartSector:6; + WORD StartCylinder:10; + BYTE PartitionType; + BYTE EndHead; + WORD EndSector:6; + WORD EndCylider:10; + DWORD SectorsPrecedingPartion; + DWORD SectorsInPartition; +}MBRPARTITIONTABLE; + + +typedef struct{ + char SIGNATURE[8]; + DWORD Revision; + DWORD Headersize; + DWORD CRC32OfHeader; + DWORD Reserved; + uint64 CurrentLBA; + uint64 BackupLBA; //location of the other head copy + uint64 FirstUsableLBA; //primary partition table last LBA+1 + uint64 LastUsableLBA; //secondary parition table first LBA-1 + BYTE DiskGUID[16]; + uint64 PartitionEntries; + DWORD NumOfPartitions; + DWORD SizeOfPartitionEntry; + DWORD CRC32ofPartitionArray; + BYTE reserved[420]; +}GPT; + +typedef struct { + BYTE PartitionTypeGUID[16]; + BYTE PartitionGUID[16]; + uint64 PartitionStartLBA; + uint64 PartitionEndLBA; + uint64 PartitionProperty; + wchar_t PartitionName[36]; //Unicode +}GPTPAPTITIONTABLE ; + +LittleEndian(); +struct { + BYTE bootcode[446]; + MBRPARTITIONTABLE partitionTable[4]; + WORD signature; +}MBR ; + + + + +if ((MBR.partitionTable[0].PartitionType & 0xFF) == 0xEE) { + Printf("Protected MBR. GPT reserved"); + GPT gptheader; + GPTPAPTITIONTABLE table[128]; + FSeek(FileSize()-sizeof(GPT)-sizeof(GPTPAPTITIONTABLE)*128); + GPTPAPTITIONTABLE BackupTable[128]; + FSeek(FileSize()-sizeof(GPT)); + GPT Backupgptheader; +} \ No newline at end of file diff --git a/cparser/GZipTemplate.bt b/cparser/GZipTemplate.bt new file mode 100644 index 0000000..64c768a --- /dev/null +++ b/cparser/GZipTemplate.bt @@ -0,0 +1,185 @@ +//-------------------------------------- +//--- 010 Editor v4.0.3 Binary Template +// +// File: GZipTemplate.bt +// Author: Tim "diff" Strazzere +// Revision: 1.2 +// Purpose: Quick template for parsing GZip data/files +//-------------------------------------- +// +// Version 1.2 +// - Fix processing of part numbers for continuation based gzips +// - Added some notes on the encrypted header information +// +// Version 1.1 +// - Fix small typos +// - Added comments to fields +// - Fix compression/flag names according to gzip 1.2.4 source +// - Added uncompressed length and CRC32 +// - Check for different common magic bytes, and display properly +// - Minor code clean up +// +// Version 1.0 +// - First implementation of the template +// +// TODO: +// - Parse encrypted header information + +// GZip's should be Little Endian only +LittleEndian(); + +// utility type to show the magic bytes in the value column +typedef ubyte MAGIC[2] ; + +string MAGICRead(MAGIC magic) { + string ret; + string tmp; + int i; + + for(i = 0; i<2; i++) { + SPrintf(tmp, "%.2X", magic[i]); + ret += tmp; + } + + return ret; +} + +typedef enum { + // All below, except DEFLATE are reserved + STORED = 0, + COMPRESSED = 1, + PACKED = 2, + LZHED = 3, + RESERVED_4 = 4, + RESERVED_5 = 5, + RESERVED_6 = 6, + RESERVED_7 = 7, + // Default (and most common) + DEFLATE = 8 +} COMPRESSION; + + +// TODO : Probably some better way to do this +typedef struct { + // File is probably ascii text (determined by compressor) + byte FLAG_ASCII_TEXT : 1; + + // Continuation of multi-part gzip file + byte FLAG_CONTINUATION : 1; + + // Generic extra field present + byte FLAG_EXTRA : 1; + + // Original filename present + byte FLAG_NAME : 1; + + // File comment present + byte FLAG_COMMENT : 1; + + // Is file encrypted? + byte FLAG_ENCRYPTED : 1; + + // Reserved for future use (nothing as of gzip 1.2.4 + byte FLAG_RESERVED : 1; + byte FLAG_RESERVED : 1; +} FLAGS; + +typedef enum { + FAT_FILESYSTEM = 0, + AMIGA = 1, + VMS = 2, + UNIX = 3, + VM_CMS = 4, + ATARI_TOS = 5, + HPFS_FILESYSTEM = 6, + MACINTOSH = 7, + Z_SYSTEM = 8, + CPM = 9, + TOPS_20 = 10, + NTFS_FILESYSTEM = 11, + QDOS = 12, + ACORN_RISCOS = 13, + UNKNOWN = 255 +} OS; + +typedef struct { + MAGIC magic_bytes ; + + // Should be a better way to parse the magic bytes and complain to user... + if(magic_bytes[0] == 0x1F) { + if(magic_bytes[1] == 0x8B) { + // GZIP_MAGIC + Printf("Appears to be a valid GZIP compressed file, attempting to parse.\n"); + } else if(magic_bytes[1] == 0x1E) { + // PACK_MAGIC + Printf("Appears to be a generic compressed file, attempting to parse - don't expect much though.\n"); + } else if(magic_bytes[1] == 0x9E) { + // OLD_GZIP_MAGIC + Printf("Appears to be an old GZip compressed file, attempting to parse - don't expect much though.\n"); + } else if(magic_bytes[1] == 0xA0) { + // LZH_MAGIC + Printf("Appears to be a LZH compressed file, attempting to parse - don't expect much though.\n"); + } + } else if(magic_bytes[0] == 0x50 && magic_bytes[1] == 0x4B) { + Warning("Appears to be a possible ZIP file - unable to parse with this template!"); + Exit(-1); + } else { + Warning("Does not appear to be a GZip file!"); + Exit(-1); + } + + COMPRESSION compression_method ; + FLAGS flags ; + + // Convert to proper timestamp + uint modification_time ; + + // Extra flags + ubyte extra_flags ; + + // OS where compression took place + OS operating_system ; + + // The file is marked as a continuation, so it should have a part number + if(flags.FLAG_CONTINUATION == 1) { + ushort part ; + } + + // Read in extras from flags + if(flags.FLAG_EXTRA == 1) { + ushort extra_length ; + byte extra_bytes[extra_length] ; + } + + if(flags.FLAG_NAME == 1) { + string original_file_name ; + } + + if(flags.FLAG_COMMENT == 1) { + string file_comment ; + } + + // TODO: Parse encrypted header info + // -- according to the docs this is grabbed from the zip lib (crypt.h/crypt.c) + // which according to their docs is hardly used or fully supported. + // It would appear you would need to compile this directly into your gzip + // sources for it to properly work, even though it's considered "valid". + if(flags.FLAG_ENCRYPTED == 1) { + // 12 bytes of encryption header data + } +} gzip_header; + +// Structure of gzip file +struct { + // Header information + gzip_header header ; + + // Everything else should just be compress bytes, less the last 8 bytes + // which contain the CRC32 and uncompressed size + byte compressed[FileSize() - FTell() - 8] ; + + uint CRC32 ; + + // 4 bytes uncompressed input size modulo 2^32 + uint uncompressed_sized ; +} gzip_file; \ No newline at end of file diff --git a/cparser/GeoTIFTemplate.bt b/cparser/GeoTIFTemplate.bt new file mode 100644 index 0000000..cc1bf71 --- /dev/null +++ b/cparser/GeoTIFTemplate.bt @@ -0,0 +1,1118 @@ +//-------------------------------------- +//--- 010 Editor v2.1 Binary Template +// +// $Id: TIFTemplate.bt 61 2007-03-06 16:53:31Z kogrover $ +// +// File: TIFTemplate.bt +// Author: Kevin O. Grover +// Purpose: A template for parsing TIFF (Tagged Image File Format) files. +// Version: $Revision: 61 $ +// History: +// 2005-05-09 KOG Initial version +// 2005-05-11 KOG *Many* more TIFF Tag IDs (generated with a Perl script) +// 2005-05-19 KOG Added new iFax tags and best guess for MS Fax Tags +// 2005-06-30 KOG Updated MSFax Tag list +// 2007-02-28 KOG Updated for 010 2.1 (uses EnumToString) +// 2012-09 ELB add interpretation for GeoTiff (rev 1.8.2) +// +// This template was written to the TIFF6 specification. You can get the TIFF +// documentation from Adobe (http://www.adobe.com) after registering, or +// from the libtiff home page (http://www.libtiff.org). +// +// GeoTiff template written to GeoTIFF specification 1.8.2, which can be found at the following address: +// http://www.remotesensing.org/geotiff/spec/geotiffhome.html +// +// NOTE: This is NOT a comprehensive list of TIFF tags. Many are tags +// registered as private and not reported anywhere. If you run +// across any definitions, forward them to me and I'll add them +// to this template. +//-------------------------------------- + +// TODO +// - ADD: ??Color highlighting?? (ENT=gray, DATA=??, EXTERNAL DATA=??) +// - Types to Test: eBYTE, eSBYTE, eSSHORT, eSLONG, eFLOAT, eDOUBLE + +// Check the Byte Order Mark to determine if file is Little or Big Endian +local uint16 tbom; +tbom = ReadUShort(0); +if (tbom == 0x4949) { LittleEndian(); } +else if (tbom == 0x4D4D) { BigEndian(); } +else { + Warning("Invalid TIFF File: Bad BOM (Byte Order Mark). Template Terminated."); + return -1; +} + +local quad nextIFD = 0; // Pointer to next IFD (or 0) + +// DO NOT EDIT. This structure is generated from TIFF_Tags.pl +// enum of TAG ids +typedef enum eTAG { + GPSVersionID=0,GPSLatitudeRef,GPSLatitude,GPSLongitudeRef,GPSLongitude,GPSAltitudeRef,GPSAltitude,GPSTimeStamp,GPSSatellites,GPSStatus,GPSMeasureMode,GPSDOP,GPSSpeedRef,GPSSpeed,GPSTrackRef,GPSTrack,GPSImgDirectionRef,GPSImgDirection,GPSMapDatum,GPSDestLatitudeRef,GPSDestLatitude,GPSDestLongitudeRef,GPSDestLongitude,GPSDestBearingRef,GPSDestBearing,GPSDestDistanceRef,GPSDestDistance,GPSProcessingMethod,GPSAreaInformation,GPSDateStamp,GPSDifferential, + NewSubFileType=254,SubFileType,ImageWidth,ImageLength,BitsPerSample,Compression, + PhotometricInterpretation=262,Thresholding,CellWidth,CellLength,FillOrder, + DocumentName=269,ImageDescription,Make,Model,StripOffsets,Orientation, + SamplesPerPixel=277,RowsPerStrip,StripByteCounts,MinSampleValue,MaxSampleValue,XResolution,YResolution,PlanarConfiguration,PageName,XPosition,YPosition,FreeOffsets,FreeByteCounts,GrayResponseUnit,GrayResponseCurve,Group3Options,Group4Options, + ResolutionUnit=296,PageNumber, + ColorResponseUnit=300,TransferFunction, + Software=305,DateTime, + Artist=315,HostComputer,Predictor,WhitePoint,PrimaryChromacities,ColorMap,HalftoneHints,TileWidth,TileLength,TileOffsets,TileByteCounts,BadFaxLines,CleanFaxData,ConsecutiveBadFaxLines, + SubIFDs=330, + InkSet=332,InkNames,NumberOfInks, + DotRange=336,TargetPrinter,ExtraSamples,SampleFormat,SMinSampleValue,SMaxSampleValue,TransferRange,ClipPath,XClipPathUnits,YClipPathUnits,Indexed,JPEGTables, + OPIProxy=351, + GlobalParametersIFD=400,ProfileType,FaxProfile,CodingMethods,VersionYear,ModeNumber, + JPEGProc=512,JPEGInterchangeFormat,JPEGInterchangeFormatLength,JPEGRestartInterval, + JPEGLosslessPredictors=517,JPEGPointTransforms,JPEGQTables,JPEGDCTables,JPEGACTables, + YCbCrCoefficients=529,YCbCrSubsampling,YCbCrPositioning,ReferenceBlackWhite, + XMP=700, + ImageID=32781, + Wang_Annotation=32932, + Matteing=32995,DataType,ImageDepth,TileDepth, + CFARepeatPatternDim=33421,CFAPattern,BatteryLevel, + Copyright=33432, + ExposureTime=33434, + FNumber=33437, + ModelPixelScaleTag=33550, + IPTC_NAA=33723, + INGR_Packet_Data_Tag=33918,INGR_Flag_Registers,IntergraphMatrixTag, + ModelTiepointTag=33922, + Site=34016,ColorSequence,IT8Header,RasterPadding,BitsPerRunLength,BitsPerExtendedRunLength,ColorTable,ImageColorIndicator,BackgroundColorIndicator,ImageColorValue,BackgroundColorValue,PixelInensityRange,TransparencyIndicator,ColorCharacterization,HCUsage, + ModelTransformationTag=34264, + PhotoshopImageResources=34377, + ExifIFD=34665, + InterColourProfile=34675, + GeoKeyDirectoryTag=34735,GeoDoubleParamsTag,GeoAsciiParamsTag, + ExposureProgram=34850, + SpectralSensitibity=34852,GPSInfo, + ISOSpeedRatings=34855,OECF,Interlace,TimeZoneOffset,SelfTimerMode, + FaxRecvParams=34908,FaxSubAddress,FaxRecvTime, + ExifVersion=36864, + DateTimeOriginal=36867,DateTimeDigitized, + ComponentsConfiguration=37121,CompressedBitsPerPixel, + ShutterSpeedValue=37377,ApertureValue,BrightnessValue,ExposureBiasValue,MaxApertureValue,SubjectDistance,MeteringMode,LightSource,Flash,FocalLength,FlashEnergy,SpatialFrequencyResponse,Noise,FocalPlaneXResolution,FocalPlaneYResolution,FocalPlaneResolutionUnit,ImageNumber,SecurityClassification,ImageHistory,SubjectArea,ExposureIndex,TIFF_EPStandardID,SensingMethod, + StoNits=37439, + MakerNote=37500, + UserComment=37510, + SubSecTime=37520,SubSecTimeOriginal,SubSecTimeDigitized, + ImageSourceData=37724, + MSFax_CSID=40001,MSFax_TSID,MSFax_Device,MSFax_RoutingInfo,MSFax_CallerID,MSFax_RecipientName,MSFax_RecipientFaxNumber,MSFax_RecipientCompany,MSFax_RecipientAddress,MSFax_RecipientStreet,MSFax_RecipientCity,MSFax_RecipientZipCode,MSFax_RecipientCountry,MSFax_RecipientTitle,MSFax_RecipientDepartment,MSFax_RecipientOffice,MSFax_RecipientOfficePhone,MSFax_RecipientHomePhone,MSFax_Recipient40019,MSFax_RecipientEmail,MSFax_SenderName,MSFax_SenderFaxNumber,MSFax_SenderCompany,MSFax_SenderAddress,MSFax_SenderStreet,MSFax_SenderCity,MSFax_SenderZipCode,MSFax_SenderCountry,MSFax_SenderTitle,MSFax_SenderDepartment,MSFax_SenderOffice,MSFax_SenderOfficePhone,MSFax_SenderHomePhone,MSFax_Sender40034,MSFax_SenderEmail,MSFax_BillingCode,MSFax_UserName,MSFax_40038,MSFax_Document,MSFax_CoverPageSubject,MSFax_Retries,MSFax_Priority,MSFax_ParentJobID,MSFax_SubmissionTime,MSFax_Scheduled,MSFax_TotalPages,MSFax_Type,MSFax_40048,MSFax_ErrorCode,MSFax_40050,MSFax_StartTime,MSFax_EndTime,MSFax_40053, + FlashpixVersion=40960,ColorSpace,PixelXDimension,PixelYDimension,RelatedSoundFile,InteroperabilityIFD, + FlashEnergy_Exif=41483,SpatialFrequencyResponse_Exif, + FocalPlaneXResolution_Exif=41486,FocalPlaneYResolution_Exif,FocalPlaneResolutionUnit_Exif, + SubjectLocation_Exif=41492,ExposureIndex_Exif, + SensingMethod_Exif=41495, + FileSource=41728,SceneType,CFAPattern_Exif, + CustomRendered=41985,ExposureMode,WhiteBalance,DigitalZoomRatio,FocalLengthIn35mmFilm,SceneCaptureType,GainControl,Contrast,Saturation,Sharpness,DeviceSettingDescription,SubjectDistanceRange, + GDAL_METADATA=42112,GDAL_NODATA, + Oce_Scanjob_Description=50215,Oce_Application_Selector,Oce_Identification_Number,Oce_ImageLogic_Characteristics, + PhotoshopAnnotations=50255, + DNGVersion=50706,DNGBackwardVersion,UniqueCameraModel,LocalizedCameraModel,CFAPlaneColor,CFALayout,LinearizationTable,BlackLevelRepeatDim,BlackLevel,BlackLevelDeltaH,BlackLevelDeltaV,WhiteLevel,DefaultScale,DefaultCropOrigin,DefaultCropSize,ColorMatrix1,ColorMatrix2,CameraCalibration1,CameraCalibration2,ReductionMatrix1,ReductionMatrix2,AnalogBalnace,AsShortNeutral,AsShortWhiteXY,BaselineExposure,BaselineNoise,BaselineSharpness,BayerGreenSplit,LinearResponseLimit,CameraSerialNumber,LensInfo,ChromaBlurRadius,AntiAliasStrength, + DNGPrivateDatea=50740,MakerNoteSafety, + CalibrationIlluminant1=50778,CalibrationIlluminant2,BestQualityScale, + Alias_Layer_Metadata=50784 +} TAG; + +// enum of TAG types +typedef enum eTAGTYPE { + eBYTE=1, eASCII, eSHORT, eLONG, eRATIONAL, + eSBYTE, eUNDEF, eSSHORT, eSLONG, eSRATIONAL, + eFLOAT, eDOUBLE +} TAGTYPE; + +//enum for Compression types +typedef enum eCOMP { + Uncompressed=1,CCITT_1D,Group3Fax,Group4Fax,LZW,JPEG,JPEG2, + Deflate=8, + NeXT2Bit=32766,CCITT_RLE=32771,PackBits=32773, + ThunderScan4bit=32809,cRasterPadding=32895, + RLEforLW=32896,RLEforHC,RLEforBL, + Pixar10bitLZW=32908,PixarCompanded11bitZIP, + PKZIP_Deflate=32946, + Kodak_DCS=32947, + JBIG=34661, + SGI32LogLum=34676, + SIG24LogLum=34677, + JPEG_2000=34712 +} COMP; + +//enum for PhotometricInterpretation +typedef enum ePHOTO { + WhiteIsZero,BlackIsZero,RGB,RGB_Palette,Transparency_Mask,CMYK,YCbCr, + CIELab=8,ICCLab,ITULab,CFA=32803,CIELog2L=32844,CIELog2Luv,LinearRaw=34892 +} PHOTO; + +//enum for ResolutionUnit +typedef enum eRES { + None=1,Inch,Centimeter +} RES; + +// enum of GeoKEYs for GeoTiff +typedef enum eKEYGeoTiff { + undefinedGeoKey=1, +/* GeoTIFF GeoKey Database */ + +/* Note: Any changes/additions to this database require */ +/* a change in the revision value in geokeys.h */ +/* Revised 28 Sep 1995 NDR -- Added Rev. 1.0 aliases. */ + +/* 6.2.1 GeoTIFF Configuration Keys */ + +GTModelTypeGeoKey= 1024, /* Section 6.3.1.1 Codes */ +GTRasterTypeGeoKey= 1025, /* Section 6.3.1.2 Codes */ +GTCitationGeoKey= 1026, /* documentation */ + +/* 6.2.2 Geographic CS Parameter Keys */ + +GeographicTypeGeoKey= 2048, /* Section 6.3.2.1 Codes */ +GeogCitationGeoKey= 2049, /* documentation */ +GeogGeodeticDatumGeoKey= 2050, /* Section 6.3.2.2 Codes */ +GeogPrimeMeridianGeoKey= 2051, /* Section 6.3.2.4 codes */ +GeogLinearUnitsGeoKey= 2052, /* Section 6.3.1.3 Codes */ +GeogLinearUnitSizeGeoKey= 2053, /* meters */ +GeogAngularUnitsGeoKey= 2054, /* Section 6.3.1.4 Codes */ +GeogAngularUnitSizeGeoKey= 2055, /* radians */ +GeogEllipsoidGeoKey= 2056, /* Section 6.3.2.3 Codes */ +GeogSemiMajorAxisGeoKey= 2057, /* GeogLinearUnits */ +GeogSemiMinorAxisGeoKey= 2058, /* GeogLinearUnits */ +GeogInvFlatteningGeoKey= 2059, /* ratio */ +GeogAzimuthUnitsGeoKey= 2060, /* Section 6.3.1.4 Codes */ +GeogPrimeMeridianLongGeoKey= 2061, /* GeoAngularUnit */ +GeogTOWGS84GeoKey= 2062, /* 2011 - proposed addition */ + +/* 6.2.3 Projected CS Parameter Keys */ +/* Several keys have been renamed,*/ +/* and the deprecated names aliased for backward compatibility */ + +ProjectedCSTypeGeoKey= 3072, /* Section 6.3.3.1 codes */ +PCSCitationGeoKey= 3073, /* documentation */ +ProjectionGeoKey= 3074, /* Section 6.3.3.2 codes */ +ProjCoordTransGeoKey= 3075, /* Section 6.3.3.3 codes */ +ProjLinearUnitsGeoKey= 3076, /* Section 6.3.1.3 codes */ +ProjLinearUnitSizeGeoKey= 3077, /* meters */ +ProjStdParallel1GeoKey= 3078, /* GeogAngularUnit */ +/* ProjStdParallelGeoKey=ProjStdParallel1GeoKey, alias ** */ +ProjStdParallel2GeoKey= 3079, /* GeogAngularUnit */ +ProjNatOriginLongGeoKey= 3080, /* GeogAngularUnit */ +/* ProjOriginLongGeoKey=ProjNatOriginLongGeoKey, alias ** */ +ProjNatOriginLatGeoKey= 3081, /* GeogAngularUnit */ +/* ProjOriginLatGeoKey=ProjNatOriginLatGeoKey, alias ** */ +ProjFalseEastingGeoKey= 3082, /* ProjLinearUnits */ +ProjFalseNorthingGeoKey= 3083, /* ProjLinearUnits */ +ProjFalseOriginLongGeoKey= 3084, /* GeogAngularUnit */ +ProjFalseOriginLatGeoKey= 3085, /* GeogAngularUnit */ +ProjFalseOriginEastingGeoKey= 3086, /* ProjLinearUnits */ +ProjFalseOriginNorthingGeoKey= 3087, /* ProjLinearUnits */ +ProjCenterLongGeoKey= 3088, /* GeogAngularUnit */ +ProjCenterLatGeoKey= 3089, /* GeogAngularUnit */ +ProjCenterEastingGeoKey= 3090, /* ProjLinearUnits */ +ProjCenterNorthingGeoKey= 3091, /* ProjLinearUnits */ +ProjScaleAtNatOriginGeoKey= 3092, /* ratio */ +/* ProjScaleAtOriginGeoKey=ProjScaleAtNatOriginGeoKey, alias ** */ +ProjScaleAtCenterGeoKey= 3093, /* ratio */ +ProjAzimuthAngleGeoKey= 3094, /* GeogAzimuthUnit */ +ProjStraightVertPoleLongGeoKey= 3095, /* GeogAngularUnit */ +ProjRectifiedGridAngleGeoKey= 3096, /* GeogAngularUnit */ + +/* 6.2.4 Vertical CS Keys */ + +VerticalCSTypeGeoKey= 4096, /* Section 6.3.4.1 codes */ +VerticalCitationGeoKey= 4097, /* documentation */ +VerticalDatumGeoKey= 4098, /* Section 6.3.4.2 codes */ +VerticalUnitsGeoKey= 4099, /* Section 6.3.1 (.x, codes */ + +/* End of Data base */ + + userDefinedGeoKey = 32767 +} GeoKEYlabel; + + +/************************************************************ + * 6.3.1 GeoTIFF General Codes + ************************************************************/ + +/* 6.3.1.1 Model Type Codes */ +typedef enum { + ModelTypeProjected = 1, /* Projection Coordinate System */ + ModelTypeGeographic = 2, /* Geographic latitude-longitude System */ + ModelTypeGeocentric = 3, /* Geocentric (X,Y,Z) Coordinate System */ +// ModelProjected = ModelTypeProjected, /* alias */ +// ModelGeographic = ModelTypeGeographic, /* alias */ +// ModelGeocentric = ModelTypeGeocentric /* alias */ +} modeltype_t; + +/* 6.3.1.2 Raster Type Codes */ +typedef enum { + RasterPixelIsArea = 1, /* Standard pixel-fills-grid-cell */ + RasterPixelIsPoint = 2 /* Pixel-at-grid-vertex */ +} rastertype_t; + +/* 6.3.1.3 Linear Units Codes */ +typedef enum { + Linear_Meter= 9001, + Linear_Foot= 9002, + Linear_Foot_US_Survey= 9003, + Linear_Foot_Modified_American= 9004, + Linear_Foot_Clarke= 9005, + Linear_Foot_Indian= 9006, + Linear_Link= 9007, + Linear_Link_Benoit= 9008, + Linear_Link_Sears= 9009, + Linear_Chain_Benoit= 9010, + Linear_Chain_Sears= 9011, + Linear_Yard_Sears= 9012, + Linear_Yard_Indian= 9013, + Linear_Fathom= 9014, + Linear_Mile_International_Nautical= 9015 + } LinearUnitCode_t; + +/* 6.3.1.4 Angular Units Codes */ +typedef enum { + Angular_Radian= 9101, + Angular_Degree= 9102, + Angular_Arc_Minute= 9103, + Angular_Arc_Second= 9104, + Angular_Grad= 9105, + Angular_Gon= 9106, + Angular_DMS= 9107, + Angular_DMS_Hemisphere= 9108 + } AngularUnitCode_t; + + +/* 6.3.2.1 Geographic CS Type Codes */ +typedef enum { +GCS_Adindan = 4201, +GCS_AGD66 = 4202, +GCS_AGD84 = 4203, +GCS_Ain_el_Abd = 4204, +GCS_Afgooye = 4205, +GCS_Agadez = 4206, +GCS_Lisbon = 4207, +GCS_Aratu = 4208, +GCS_Arc_1950 = 4209, +GCS_Arc_1960 = 4210, +GCS_Batavia = 4211, +GCS_Barbados = 4212, +GCS_Beduaram = 4213, +GCS_Beijing_1954 = 4214, +GCS_Belge_1950 = 4215, +GCS_Bermuda_1957 = 4216, +GCS_Bern_1898 = 4217, +GCS_Bogota = 4218, +GCS_Bukit_Rimpah = 4219, +GCS_Camacupa = 4220, +GCS_Campo_Inchauspe = 4221, +GCS_Cape = 4222, +GCS_Carthage = 4223, +GCS_Chua = 4224, +GCS_Corrego_Alegre = 4225, +GCS_Cote_d_Ivoire = 4226, +GCS_Deir_ez_Zor = 4227, +GCS_Douala = 4228, +GCS_Egypt_1907 = 4229, +GCS_ED50 = 4230, +GCS_ED87 = 4231, +GCS_Fahud = 4232, +GCS_Gandajika_1970 = 4233, +GCS_Garoua = 4234, +GCS_Guyane_Francaise = 4235, +GCS_Hu_Tzu_Shan = 4236, +GCS_HD72 = 4237, +GCS_ID74 = 4238, +GCS_Indian_1954 = 4239, +GCS_Indian_1975 = 4240, +GCS_Jamaica_1875 = 4241, +GCS_JAD69 = 4242, +GCS_Kalianpur = 4243, +GCS_Kandawala = 4244, +GCS_Kertau = 4245, +GCS_KOC = 4246, +GCS_La_Canoa = 4247, +GCS_PSAD56 = 4248, +GCS_Lake = 4249, +GCS_Leigon = 4250, +GCS_Liberia_1964 = 4251, +GCS_Lome = 4252, +GCS_Luzon_1911 = 4253, +GCS_Hito_XVIII_1963 = 4254, +GCS_Herat_North = 4255, +GCS_Mahe_1971 = 4256, +GCS_Makassar = 4257, +GCS_EUREF89 = 4258, +GCS_Malongo_1987 = 4259, +GCS_Manoca = 4260, +GCS_Merchich = 4261, +GCS_Massawa = 4262, +GCS_Minna = 4263, +GCS_Mhast = 4264, +GCS_Monte_Mario = 4265, +GCS_M_poraloko = 4266, +GCS_NAD27 = 4267, +GCS_NAD_Michigan = 4268, +GCS_NAD83 = 4269, +GCS_Nahrwan_1967 = 4270, +GCS_Naparima_1972 = 4271, +GCS_GD49 = 4272, +GCS_NGO_1948 = 4273, +GCS_Datum_73 = 4274, +GCS_NTF = 4275, +GCS_NSWC_9Z_2 = 4276, +GCS_OSGB_1936 = 4277, +GCS_OSGB70 = 4278, +GCS_OS_SN80 = 4279, +GCS_Padang = 4280, +GCS_Palestine_1923 = 4281, +GCS_Pointe_Noire = 4282, +GCS_GDA94 = 4283, +GCS_Pulkovo_1942 = 4284, +GCS_Qatar = 4285, +GCS_Qatar_1948 = 4286, +GCS_Qornoq = 4287, +GCS_Loma_Quintana = 4288, +GCS_Amersfoort = 4289, +GCS_RT38 = 4290, +GCS_SAD69 = 4291, +GCS_Sapper_Hill_1943 = 4292, +GCS_Schwarzeck = 4293, +GCS_Segora = 4294, +GCS_Serindung = 4295, +GCS_Sudan = 4296, +GCS_Tananarive = 4297, +GCS_Timbalai_1948 = 4298, +GCS_TM65 = 4299, +GCS_TM75 = 4300, +GCS_Tokyo = 4301, +GCS_Trinidad_1903 = 4302, +GCS_TC_1948 = 4303, +GCS_Voirol_1875 = 4304, +GCS_Voirol_Unifie = 4305, +GCS_Bern_1938 = 4306, +GCS_Nord_Sahara_1959 = 4307, +GCS_Stockholm_1938 = 4308, +GCS_Yacare = 4309, +GCS_Yoff = 4310, +GCS_Zanderij = 4311, +GCS_MGI = 4312, +GCS_Belge_1972 = 4313, +GCS_DHDN = 4314, +GCS_Conakry_1905 = 4315, +GCS_WGS_72 = 4322, +GCS_WGS_72BE = 4324, +GCS_WGS_84 = 4326, +GCS_Bern_1898_Bern = 4801, +GCS_Bogota_Bogota = 4802, +GCS_Lisbon_Lisbon = 4803, +GCS_Makassar_Jakarta = 4804, +GCS_MGI_Ferro = 4805, +GCS_Monte_Mario_Rome = 4806, +GCS_NTF_Paris = 4807, +GCS_Padang_Jakarta = 4808, +GCS_Belge_1950_Brussels = 4809, +GCS_Tananarive_Paris = 4810, +GCS_Voirol_1875_Paris = 4811, +GCS_Voirol_Unifie_Paris = 4812, +GCS_Batavia_Jakarta = 4813, +GCS_ATF_Paris = 4901, +GCS_NDG_Paris = 4902, +GCSE_Airy1830 = 4001, +GCSE_AiryModified1849 = 4002, +GCSE_AustralianNationalSpheroid = 4003, +GCSE_Bessel1841 = 4004, +GCSE_BesselModified = 4005, +GCSE_BesselNamibia = 4006, +GCSE_Clarke1858 = 4007, +GCSE_Clarke1866 = 4008, +GCSE_Clarke1866Michigan = 4009, +GCSE_Clarke1880_Benoit = 4010, +GCSE_Clarke1880_IGN = 4011, +GCSE_Clarke1880_RGS = 4012, +GCSE_Clarke1880_Arc = 4013, +GCSE_Clarke1880_SGA1922 = 4014, +GCSE_Everest1830_1937Adjustment = 4015, +GCSE_Everest1830_1967Definition = 4016, +GCSE_Everest1830_1975Definition = 4017, +GCSE_Everest1830Modified = 4018, +GCSE_GRS1980 = 4019, +GCSE_Helmert1906 = 4020, +GCSE_IndonesianNationalSpheroid = 4021, +GCSE_International1924 = 4022, +GCSE_International1967 = 4023, +GCSE_Krassowsky1940 = 4024, +GCSE_NWL9D = 4025, +GCSE_NWL10D = 4026, +GCSE_Plessis1817 = 4027, +GCSE_Struve1860 = 4028, +GCSE_WarOffice = 4029, +GCSE_WGS84 = 4030, +GCSE_GEM10C = 4031, +GCSE_OSU86F = 4032, +GCSE_OSU91A = 4033, +GCSE_Clarke1880 = 4034, +GCSE_Sphere = 4035 + } GCSCode_t; + + + +/* 6.3.2.2 Geodetic Datum Codes */ +typedef enum { +Datum_Adindan = 6201, +Datum_Australian_Geodetic_Datum_1966 = 6202, +Datum_Australian_Geodetic_Datum_1984 = 6203, +Datum_Ain_el_Abd_1970 = 6204, +Datum_Afgooye = 6205, +Datum_Agadez = 6206, +Datum_Lisbon = 6207, +Datum_Aratu = 6208, +Datum_Arc_1950 = 6209, +Datum_Arc_1960 = 6210, +Datum_Batavia = 6211, +Datum_Barbados = 6212, +Datum_Beduaram = 6213, +Datum_Beijing_1954 = 6214, +Datum_Reseau_National_Belge_1950 = 6215, +Datum_Bermuda_1957 = 6216, +Datum_Bern_1898 = 6217, +Datum_Bogota = 6218, +Datum_Bukit_Rimpah = 6219, +Datum_Camacupa = 6220, +Datum_Campo_Inchauspe = 6221, +Datum_Cape = 6222, +Datum_Carthage = 6223, +Datum_Chua = 6224, +Datum_Corrego_Alegre = 6225, +Datum_Cote_d_Ivoire = 6226, +Datum_Deir_ez_Zor = 6227, +Datum_Douala = 6228, +Datum_Egypt_1907 = 6229, +Datum_European_Datum_1950 = 6230, +Datum_European_Datum_1987 = 6231, +Datum_Fahud = 6232, +Datum_Gandajika_1970 = 6233, +Datum_Garoua = 6234, +Datum_Guyane_Francaise = 6235, +Datum_Hu_Tzu_Shan = 6236, +Datum_Hungarian_Datum_1972 = 6237, +Datum_Indonesian_Datum_1974 = 6238, +Datum_Indian_1954 = 6239, +Datum_Indian_1975 = 6240, +Datum_Jamaica_1875 = 6241, +Datum_Jamaica_1969 = 6242, +Datum_Kalianpur = 6243, +Datum_Kandawala = 6244, +Datum_Kertau = 6245, +Datum_Kuwait_Oil_Company = 6246, +Datum_La_Canoa = 6247, +Datum_Provisional_S_American_Datum_1956 = 6248, +Datum_Lake = 6249, +Datum_Leigon = 6250, +Datum_Liberia_1964 = 6251, +Datum_Lome = 6252, +Datum_Luzon_1911 = 6253, +Datum_Hito_XVIII_1963 = 6254, +Datum_Herat_North = 6255, +Datum_Mahe_1971 = 6256, +Datum_Makassar = 6257, +Datum_European_Reference_System_1989 = 6258, +Datum_Malongo_1987 = 6259, +Datum_Manoca = 6260, +Datum_Merchich = 6261, +Datum_Massawa = 6262, +Datum_Minna = 6263, +Datum_Mhast = 6264, +Datum_Monte_Mario = 6265, +Datum_M_poraloko = 6266, +Datum_North_American_Datum_1927 = 6267, +Datum_NAD_Michigan = 6268, +Datum_North_American_Datum_1983 = 6269, +Datum_Nahrwan_1967 = 6270, +Datum_Naparima_1972 = 6271, +Datum_New_Zealand_Geodetic_Datum_1949 = 6272, +Datum_NGO_1948 = 6273, +Datum_Datum_73 = 6274, +Datum_Nouvelle_Triangulation_Francaise = 6275, +Datum_NSWC_9Z_2 = 6276, +Datum_OSGB_1936 = 6277, +Datum_OSGB_1970_SN = 6278, +Datum_OS_SN_1980 = 6279, +Datum_Padang_1884 = 6280, +Datum_Palestine_1923 = 6281, +Datum_Pointe_Noire = 6282, +Datum_Geocentric_Datum_of_Australia_1994 = 6283, +Datum_Pulkovo_1942 = 6284, +Datum_Qatar = 6285, +Datum_Qatar_1948 = 6286, +Datum_Qornoq = 6287, +Datum_Loma_Quintana = 6288, +Datum_Amersfoort = 6289, +Datum_RT38 = 6290, +Datum_South_American_Datum_1969 = 6291, +Datum_Sapper_Hill_1943 = 6292, +Datum_Schwarzeck = 6293, +Datum_Segora = 6294, +Datum_Serindung = 6295, +Datum_Sudan = 6296, +Datum_Tananarive_1925 = 6297, +Datum_Timbalai_1948 = 6298, +Datum_TM65 = 6299, +Datum_TM75 = 6300, +Datum_Tokyo = 6301, +Datum_Trinidad_1903 = 6302, +Datum_Trucial_Coast_1948 = 6303, +Datum_Voirol_1875 = 6304, +Datum_Voirol_Unifie_1960 = 6305, +Datum_Bern_1938 = 6306, +Datum_Nord_Sahara_1959 = 6307, +Datum_Stockholm_1938 = 6308, +Datum_Yacare = 6309, +Datum_Yoff = 6310, +Datum_Zanderij = 6311, +Datum_Militar_Geographische_Institut = 6312, +Datum_Reseau_National_Belge_1972 = 6313, +Datum_Deutsche_Hauptdreiecksnetz = 6314, +Datum_Conakry_1905 = 6315, +Datum_WGS72 = 6322, +Datum_WGS72_Transit_Broadcast_Ephemeris = 6324, +Datum_WGS84 = 6326, +Datum_Ancienne_Triangulation_Francaise = 6901, +Datum_Nord_de_Guerre = 6902, +/* Ellipsoid-Only Datum: +Note: the numeric code is equal to the corresponding ellipsoid +code, minus 1000. */ +DatumE_Airy1830 = 6001, +DatumE_AiryModified1849 = 6002, +DatumE_AustralianNationalSpheroid = 6003, +DatumE_Bessel1841 = 6004, +DatumE_BesselModified = 6005, +DatumE_BesselNamibia = 6006, +DatumE_Clarke1858 = 6007, +DatumE_Clarke1866 = 6008, +DatumE_Clarke1866Michigan = 6009, +DatumE_Clarke1880_Benoit = 6010, +DatumE_Clarke1880_IGN = 6011, +DatumE_Clarke1880_RGS = 6012, +DatumE_Clarke1880_Arc = 6013, +DatumE_Clarke1880_SGA1922 = 6014, +DatumE_Everest1830_1937Adjustment = 6015, +DatumE_Everest1830_1967Definition = 6016, +DatumE_Everest1830_1975Definition = 6017, +DatumE_Everest1830Modified = 6018, +DatumE_GRS1980 = 6019, +DatumE_Helmert1906 = 6020, +DatumE_IndonesianNationalSpheroid = 6021, +DatumE_International1924 = 6022, +DatumE_International1967 = 6023, +DatumE_Krassowsky1960 = 6024, +DatumE_NWL9D = 6025, +DatumE_NWL10D = 6026, +DatumE_Plessis1817 = 6027, +DatumE_Struve1860 = 6028, +DatumE_WarOffice = 6029, +DatumE_WGS84 = 6030, +DatumE_GEM10C = 6031, +DatumE_OSU86F = 6032, +DatumE_OSU91A = 6033, +DatumE_Clarke1880 = 6034, +DatumE_Sphere = 6035 +} DatumCode_t; + + + +/* 6.3.2.3 Ellipsoid Codes */ +typedef enum { +Ellipse_Airy_1830 = 7001, +Ellipse_Airy_Modified_1849 = 7002, +Ellipse_Australian_National_Spheroid = 7003, +Ellipse_Bessel_1841 = 7004, +Ellipse_Bessel_Modified = 7005, +Ellipse_Bessel_Namibia = 7006, +Ellipse_Clarke_1858 = 7007, +Ellipse_Clarke_1866 = 7008, +Ellipse_Clarke_1866_Michigan = 7009, +Ellipse_Clarke_1880_Benoit = 7010, +Ellipse_Clarke_1880_IGN = 7011, +Ellipse_Clarke_1880_RGS = 7012, +Ellipse_Clarke_1880_Arc = 7013, +Ellipse_Clarke_1880_SGA_1922 = 7014, +Ellipse_Everest_1830_1937_Adjustment = 7015, +Ellipse_Everest_1830_1967_Definition = 7016, +Ellipse_Everest_1830_1975_Definition = 7017, +Ellipse_Everest_1830_Modified = 7018, +Ellipse_GRS_1980 = 7019, +Ellipse_Helmert_1906 = 7020, +Ellipse_Indonesian_National_Spheroid = 7021, +Ellipse_International_1924 = 7022, +Ellipse_International_1967 = 7023, +Ellipse_Krassowsky_1940 = 7024, +Ellipse_NWL_9D = 7025, +Ellipse_NWL_10D = 7026, +Ellipse_Plessis_1817 = 7027, +Ellipse_Struve_1860 = 7028, +Ellipse_War_Office = 7029, +Ellipse_WGS_84 = 7030, +Ellipse_GEM_10C = 7031, +Ellipse_OSU86F = 7032, +Ellipse_OSU91A = 7033, +Ellipse_Clarke_1880 = 7034, +Ellipse_Sphere = 7035 +} EllipsoidCode_t; + + +/* 6.3.2.4 Prime Meridian Codes */ +typedef enum { +PM_Greenwich = 8901, +PM_Lisbon = 8902, +PM_Paris = 8903, +PM_Bogota = 8904, +PM_Madrid = 8905, +PM_Rome = 8906, +PM_Bern = 8907, +PM_Jakarta = 8908, +PM_Ferro = 8909, +PM_Brussels = 8910, +PM_Stockholm = 8911 +} PrimeMeridianCode_t; + + +/*6.3.3.1 Projected CS Type Codes */ +/* 6.3.3.2 Projection Codes */ + +/* 6.3.3.3 Coordinate Transformation Codes */ +typedef enum { +CT_TransverseMercator = 1, +CT_TransvMercator_Modified_Alaska = 2, +CT_ObliqueMercator = 3, +CT_ObliqueMercator_Laborde = 4, +CT_ObliqueMercator_Rosenmund = 5, +CT_ObliqueMercator_Spherical = 6, +CT_Mercator = 7, +CT_LambertConfConic_2SP = 8, +CT_LambertConfConic_Helmert = 9, +CT_LambertAzimEqualArea = 10, +CT_AlbersEqualArea = 11, +CT_AzimuthalEquidistant = 12, +CT_EquidistantConic = 13, +CT_Stereographic = 14, +CT_PolarStereographic = 15, +CT_ObliqueStereographic = 16, +CT_Equirectangular = 17, +CT_CassiniSoldner = 18, +CT_Gnomonic = 19, +CT_MillerCylindrical = 20, +CT_Orthographic = 21, +CT_Polyconic = 22, +CT_Robinson = 23, +CT_Sinusoidal = 24, +CT_VanDerGrinten = 25, +CT_NewZealandMapGrid = 26, +CT_TransvMercator_SouthOriented= 27 +} CTCode_t; + +/* 6.3.4.1 Vertical CS Type Codes */ +/* 6.3.4.2 Vertical CS Datum Codes */ + +// GeoTIFF Data Types +typedef struct { + SetBackColor( cLtAqua ); + GeoKEYlabel label; + if (ReadUShort(FTell()) != 0) + { + TAG TiffTagLocation; + uint16 Length; + uint16 Offset; + } + else + { + uint16 direct; + uint16 size; + + /* size indicate if value is SHORT or DOUBLE: !!!! to be confirmed !!!!! */ + switch (size){ + case 1: /* Size SHORT */ + + + switch (label){ + case GTModelTypeGeoKey: /* Section 6.3.1.1 codes */ + modeltype_t value; + break; + + case GTRasterTypeGeoKey: /* Section 6.3.1.2 codes */ + rastertype_t value; + break; + + case GeographicTypeGeoKey: /* Section 6.3.2.1 codes */ + GCSCode_t value; + break; + + case GeogGeodeticDatumGeoKey: /* Section 6.3.2.2 codes */ + DatumCode_t value; + break; + + case GeogPrimeMeridianGeoKey: /* Section 6.3.2.4 codes */ + PrimeMeridianCode_t value; + break; + + case GeogLinearUnitsGeoKey: /* Section 6.3.1.3 codes */ + LinearUnitCode_t value; + break; + + case GeogAngularUnitsGeoKey: /* Section 6.3.1.4 codes */ + AngularUnitCode_t value; + break; + + case GeogEllipsoidGeoKey: /* Section 6.3.2.3 Codes */ + EllipsoidCode_t value; + break; + + case GeogAzimuthUnitsGeoKey: /* Section 6.3.1.4 codes */ + AngularUnitCode_t value; + break; + + case ProjectedCSTypeGeoKey: /* Section 6.3.3.1 codes */ + short value; + break; + + case ProjectionGeoKey: /* Section 6.3.3.2 codes */ + short value; + break; + + case ProjCoordTransGeoKey: /* Section 6.3.3.3 codes */ + short value; + break; + + case ProjLinearUnitsGeoKey: /* Section 6.3.1.3 codes */ + short value; + break; + + case VerticalCSTypeGeoKey: /* Section 6.3.4.1 Codes */ + short value; + break; + + case VerticalDatumGeoKey: /* Section 6.3.4.2 Codes */ + short value; + break; + + case VerticalUnitsGeoKey: /* Section 6.3.1.3 Codes */ + LinearUnitCode_t value; + break; + + default: + short value; + }; + break; + + default: /* size <> SHORT !!!! to be confirmed !!!!! */ + double value; + }; + + } +} GEOKEY ; + +/** + * Reader for GEOKEY Types + * Shows the Number of entries and the type of the first directory tag + * @param ifd Pointer to the structure + */ +string readGEOKEY(local GEOKEY &gk) { + local string s; + // NOTE: This only works with 010 v2.1 or greater... + SPrintf(s,"%s (%d)",EnumToString(gk.label), gk.label); + return s; +} + + +typedef struct eGEOKEYDIR { + SetBackColor( cLtAqua ); + uint16 GeoTiffVersion; + uint16 GeoTiffRevMajor; + uint16 GeoTiffRevMinor; + uint16 GeoKeyCount; + local uint16 i; + for (i==0;i; + +string readRATIONAL(local RATIONAL &r) { + local string s; + SPrintf(s,"%d/%d",r.num,r.dom); + return s; +} + +void writeRATIONAL(local RATIONAL &r, local string s) { + SScanf(s,"%d/%d",r.num,r.dom); +} + +// Signed Rational (e.g. fraction: NUMERATOR/DENOMINATOR) + +typedef struct { + int32 num; // Numerator + int32 dom; // Denominator +} SRATIONAL ; + +string readSRATIONAL(local SRATIONAL &r) { + local string s; + SPrintf(s,"%d/%d",r.num,r.dom); + return s; +} + +void writeSRATIONAL(local SRATIONAL &r, local string s) { + SScanf(s,"%d/%d",r.num,r.dom); +} + + + + +// ENT: Directory Entry +// An Entry holds one tag and tag data (or a pointer to the data) +// Entries are contained in IFDs (Image File Directories) +typedef struct { + SetBackColor( cLtGreen ); + + TAG tag; + TAGTYPE typ; + uint32 count; + if (typ==eBYTE) { + if (count<4) { + ubyte data[count]; + ubyte padding[4-count]; + } else if (count==4) { // NO padding in this case + ubyte data[count]; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + + ubyte value[count]; + FSeek(curpos); + } + } else if (typ==eASCII) { + if (count<4) { + char data[count]; + char padding[4-count]; + } else if (count==4) { + char data[count]; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + char data[count]; + FSeek(curpos); + } + } else if (typ==eSHORT) { + if (count==1) { + if (tag==Compression) { + COMP value; + } else if (tag==PhotometricInterpretation) { + PHOTO value; + } else if (tag==ResolutionUnit) { + RES value; + } else { + uint16 value; + + } + uint16 padding; + } else if (count==2) { + uint16 value[2]; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + +/*-----------GeoTiff entry ------------------*/ + if (tag==GeoKeyDirectoryTag) { + GEOKEYDIR value; + } else { +/*-----------end of GeoTiff entry ------------------*/ + + uint16 value[count]; + } + + FSeek(curpos); + } + } else if (typ==eLONG) { + if (count==1) { + uint32 value; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + uint32 value[count]; + FSeek(curpos); + } + } else if (typ==eRATIONAL) { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + if (count==1) { + RATIONAL value; + } else { + RATIONAL value[count]; + } + FSeek(curpos); + } else if (typ==eSBYTE) { + if (count<4) { + byte data[count]; + ubyte padding[4-count]; + } else if (count==4) { // NO padding in this case + byte data[count]; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + byte value[count]; + FSeek(curpos); + } + } else if (typ==eUNDEF) { + if (count<4) { + ubyte data[count]; + ubyte padding[4-count]; + } else if (count==4) { // NO padding in this case + ubyte data[count]; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + ubyte value[count]; + FSeek(curpos); + } + } else if (typ==eSSHORT) { + if (count==1) { + int16 value; + int16 padding; + } else if (count==2) { + int16 value[2]; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + int16 value[count]; + FSeek(curpos); + } + } else if (typ==eSLONG) { + if (count==1) { + int32 value; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + int32 value[count]; + FSeek(curpos); + } + } else if (typ==eSRATIONAL) { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + if (count==1) { + SRATIONAL value; + } else { + SRATIONAL value[count]; + } + FSeek(curpos); + } else if (typ==eFLOAT) { + if (count==1) { + float value; + } else { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + float value[count]; + FSeek(curpos); + } + } else if (typ==eDOUBLE) { + SetBackColor( cLtBlue ); + uint32 offset ; + local quad curpos = FTell(); + FSeek(offset); + if (count==1) { + double value; + } else { + double value[count]; + } + FSeek(curpos); + } else { + //UNKNOWN data type, so we can't tell if this is a value or + //an offset. Nor do we know the size of the data, so we can't + //know how big it is. (Might be a newer TIFF spec) + uint32 valOffset ; + } +} ENT ; + +/** + * Reader for ENT Types + * Shows the tag string, number, and type (as a string) + * @param ent Pointer to the structure + */ +string readENT(local ENT &ent) { + local string s; + // NOTE: This only works with 010 v2.1 or greater... + SPrintf(s,"%s (%d): %s",EnumToString(ent.tag), ent.tag, EnumToString(ent.typ)); + return s; +} + +// IFD: Image File Directory +typedef struct { + uint16 numentries; + ENT dir[numentries] ; + uint32 offset ; + nextIFD = (quad)offset; // This is how we find the next one +} IFD ; + +/** + * Reader for IFD Types + * Shows the Number of entries and the type of the first directory tag + * @param ifd Pointer to the structure + */ +string readIFD(local IFD &ifd) { + local string s; + // NOTE: This only works with 010 v2.1 or greater... + SPrintf(s,"%d: %s", ifd.numentries, (ifd.numentries>0) ? EnumToString(ifd.dir[0].tag) : ""); + return s; +} + +// IFH: Image File Header +typedef struct { + char bom[2]; + uint16 magic; // Should always be 42 + if (magic!=42) { + Warning("Invalid TIFF File: Bad Magic number"); + return -1; + } + uint32 offset ; // Offset to first IFD + + // Sanity check: There must be an initial IFD + if (offset == 0) { + Warning("Invalid TIFF File: No initial IFD"); + return -1; + } + + nextIFD = (quad)offset; // This is how we find it later +} IFH; + +// --------------------------------------------------------------------------- +// MAIN -- Here's where we really allocate the data +// --------------------------------------------------------------------------- + +SetBackColor( cLtRed ); +IFH ifh; // Allocate the Header (and set nextIFD) +while(nextIFD) { // while there is another IFD, ... + SetBackColor( cLtGreen ); + FSeek(nextIFD); // Go to it + IFD ifd; // Allocate it (and set nextIFD) +} diff --git a/cparser/GocleverTemplate.bt b/cparser/GocleverTemplate.bt new file mode 100644 index 0000000..8f84f58 --- /dev/null +++ b/cparser/GocleverTemplate.bt @@ -0,0 +1,41 @@ +//-------------------------------------- +//--- 010 Editor v3.2.1 Binary Template +// +// File:GocleverTemplate.bt +// Author:Artur Babecki +// Revision: 21.02.2012 +// Purpose: template for GOCLEVER Navigation log format +// GPSLogYYYY-MM-DD_xx-xx-xx.bin +// (Model GC-4335 and others) +// Generates raport in the human readable form: +// Date, Longitude, Latitude, Geoid, Altitude, Direction. +// +//-------------------------------------- + + +local uint number_of_records; +local int i; +local string s; + +number_of_records=FileSize()/48; +struct gps +{ + double longitude ; + double latitude ; + time_t date; + int direction; + int speed; + uchar unknown_data [12]; + int geoid; + int altitude ; +} goclever[number_of_records]; +OutputPaneClear(); + +Printf("GOCLEVER Navigation log: %s \n\n",GetFileName()); +Printf(" Date\t\tLongitude Latitude Geoid Altitude Direction Speed\n"); +Printf("mm/dd/yyyy hh:mm:ss\n"); +for (i=0;i=8bpp) + BYTE bReserved; // Reserved ( must be 0) + WORD wPlanes; // Color Planes + WORD wBitCount; // Bits per pixel + DWORD dwBytesInRes; // How many bytes in this resource? + DWORD dwImageOffset; // Where in the file is this image? +} ICONDIRENTRY ; + +typedef struct +{ + WORD idReserved; // Reserved (must be 0) + WORD idType; // Resource Type (1 for icons) + WORD idCount; // How many images? + ICONDIRENTRY idEntries[idCount]; // An entry for each image (idCount of 'em) +} ICONDIR; + +typedef struct { // rgbq + UBYTE rgbBlue; + UBYTE rgbGreen; + UBYTE rgbRed; + UBYTE rgbReserved; +} RGBQUAD ; + +typedef struct { // rgbt + UBYTE rgbBlue; + UBYTE rgbGreen; + UBYTE rgbRed; +} RGBTRIPLE ; + +typedef struct { // bmih + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; + } BITMAPINFOHEADER; + +typedef struct { + // Define the color table + if( (bmiHeader.biBitCount != 24) && (bmiHeader.biBitCount != 32) ) + { + if( bmiHeader.biClrUsed > 0 ) + RGBQUAD aColors[ bmiHeader.biClrUsed ]; + else + RGBQUAD aColors[ 1 << bmiHeader.biBitCount ]; + } + + // Calculate bytes per line and padding required + local int bytesPerLine = (int)Ceil( bmiHeader.biWidth * bmiHeader.biBitCount / 8.0 ); + local int padding = 4 - (bytesPerLine % 4); + if( padding == 4 ) + padding = 0; + + // Define each line of the image + struct BITMAPLINE { + + // Define color data + if( bmiHeader.biBitCount < 8 ) + UBYTE imageData[ bytesPerLine ]; + else if( bmiHeader.biBitCount == 8 ) + UBYTE colorIndex[ bmiHeader.biWidth ]; + else if( bmiHeader.biBitCount == 24 ) + RGBTRIPLE colors[ bmiHeader.biWidth ]; + else if( bmiHeader.biBitCount == 32 ) + RGBQUAD colors[ bmiHeader.biWidth ]; + + // Pad if necessary + if( padding != 0 ) + UBYTE padBytes[ padding ]; + + } lines[ bmiHeader.biHeight/2 ]; + + // Define each line of the mask + struct MASKLINE { + UBYTE line[((bmiHeader.biWidth + 31)/32)*4]; + }mask[bmiHeader.biHeight/2]; + +}IMAGEDATA; + +typedef struct { + SetBackColor( cLtAqua ); + BITMAPINFOHEADER bmiHeader; + SetBackColor( cLtGray ); + IMAGEDATA data; +}ICONIMAGE ; + +//--------------------------------------------- +// Custom read functions - this allows the data to be displayed without having to open up the structure. + + +string ReadIconDirEntry( ICONDIRENTRY &dirEntry ) +{ + string s; + SPrintf( s, "%dx%d %dbit %d colors", dirEntry.bWidth, dirEntry.bHeight, dirEntry.wBitCount, dirEntry.bColorCount ); + return s; +} + +string ReadDIBHeader( ICONIMAGE &image ) +{ + string s; + SPrintf( s, "%dx%d %dbit", image.bmiHeader.biWidth, image.bmiHeader.biHeight, image.bmiHeader.biBitCount ); + return s; +} + +string ReadRGBQUAD( RGBQUAD &a ) +{ + string s; + SPrintf( s, "#%02X%02X%02X%02X", a.rgbReserved, a.rgbRed, a.rgbGreen, a.rgbBlue ); + return s; +} + +string ReadRGBTRIPLE( RGBTRIPLE &a ) +{ + string s; + SPrintf( s, "#%02X%02X%02X", a.rgbRed, a.rgbGreen, a.rgbBlue ); + return s; +} + +//--------------------------------------------- + +// Define the headers +LittleEndian(); + +local short res = ReadShort( FTell() ); +local short type = ReadShort(FTell() +2 ); + +//Check icon dir +if( res != 0 || type != 1) +{ + Warning( "File is not an Icon. Template stopped." ); + return -1; +} + +SetBackColor( cNone ); +ICONDIR icondir; +ICONIMAGE images[icondir.idCount] ; \ No newline at end of file diff --git a/cparser/ISOBMFTemplate.bt b/cparser/ISOBMFTemplate.bt new file mode 100644 index 0000000..13add7b --- /dev/null +++ b/cparser/ISOBMFTemplate.bt @@ -0,0 +1,157 @@ +//-------------------------------------- +//--- 010 Editor v4.0.3 Binary Template +// +// File: ISOBMFTemplate.bt +// Author: @RReverser +// Revision: 201302261710 +// Purpose: Parse ISO Base Media File Format files (QuickTime, JPEG2000, MPEG-4, etc.) +//-------------------------------------- + +BigEndian(); + +typedef struct +{ + uint32 size ; + char type[4] ; + switch (type) + { + case "ftyp": + char fileType[4] ; + break; + + case "co64": + ubyte version ; + ubyte flags[3] ; + uint32 n ; + uint64 entries[n] ; + break; + + case "ctts": + ubyte version ; + ubyte flags[3] ; + uint32 n ; + struct { + uint32 sampleCount ; + uint32 offset ; + } entries[n] ; + break; + + case "elst": + ubyte version ; + ubyte flags[3] ; + uint32 n ; + struct { + uint32 duration ; + uint32 mediaTime ; + uint32 playbackSpeed ; + } entries[n] ; + break; + + case "fiel": + ubyte fields ; + ubyte detail ; + break; + + case "hdlr": + ubyte version ; + ubyte flags[3] ; + char component_type[4] ; + char subtype[4] ; + uint32 manufacturer ; + uint32 flags ; + uint32 flags_mask ; + string name ; + break; + + case "mdhd": + ubyte version ; + ubyte flags[3] ; + if (version < 1) + { + uint32 creation_time ; + uint32 modification_time ; + } + else + { + uint64 creation_time ; + uint64 modification_time ; + } + uint32 time_scale ; + if (version < 1) + { + uint32 duration ; + } + else + { + uint64 duration ; + } + uint16 lang ; + uint16 quality ; + break; + + case "stco": + ubyte version ; + ubyte flags[3] ; + uint32 n ; + uint32 entries[n] ; + break; + + case "stss": + ubyte version ; + ubyte flags[3] ; + uint32 n ; + uint32 entries[n] ; + break; + + case "stsz": + ubyte version ; + ubyte flags[3] ; + uint32 uniform_size ; + uint32 n ; + uint32 entries[n] ; + break; + + case "cmov": + case "edts": + case "mdia": + case "minf": + case "moov": + case "rmda": + case "rmra": + case "stbl": + case "trak": + while (FTell() - startof(this) < size) + { + struct Atom child; + } + break; + + default: + FSeek(FTell() - 8); + break; + } + + local int left = size - (FTell() - startof(this)); + if (left > 0) + { + ubyte data[left] ; + } +} +Atom ; + +int GetAtomSize(Atom &atom) +{ + return ReadUInt(startof(atom)); +} + +string GetAtomName(Atom &atom) +{ + char type[4]; + ReadBytes(type, startof(atom) + 4, 4); + return type; +} + +while (!FEof()) +{ + Atom atom; +} \ No newline at end of file diff --git a/cparser/ISOTemplate.bt b/cparser/ISOTemplate.bt new file mode 100644 index 0000000..d245c4c --- /dev/null +++ b/cparser/ISOTemplate.bt @@ -0,0 +1,108 @@ +//-------------------------------------- +//--- 010 Editor v5.0 Binary Template +// +// File: ISOTemplate.bt +// Author: Anton Kochkov +// Revision: 0.1 +// Purpose: Show contents of the ISO headers +//-------------------------------------- + +BitfieldRightToLeft(); +BitfieldDisablePadding(); + +#define BLOCK_SIZE 2048 +#define BOOT_RECORD_OFFSET 2048 * 16 + +typedef struct _BOOT_RECORD +{ + ubyte BootIndicator; + char IsoId[5]; + ubyte Version; + char Identifier[32]; + ubyte Unused[32]; + uint32 BootCatalog; + ubyte Unused2[5]; + uint32 VolSpaceSize[2]; +} BOOT_RECORD_DESC; + +typedef struct { + ubyte VolDescType; + byte StdId[5]; + ubyte VolDescVer; +} VOLUME_DESCRIPTOR_HEADER; + +typedef struct { + uint32 Year; + uint16 Month; + uint16 Day; + uint16 Hour; + uint16 Minute; + uint16 Second; + uint16 HSecond; + byte Offset; +} CD_DATE_TIME; + +typedef struct { + ubyte Year; + ubyte Month; + ubyte Day; + ubyte Hour; + ubyte Minute; + ubyte Second; + byte Offset; +} FILE_DATE_TIME; + +typedef struct { + ubyte RecordLength; + ubyte ExtAttrRecLength; + uint64 StartLba; + uint64 DataLength; + FILE_DATE_TIME RecTime; + ubyte Flags; + ubyte FileUnitSize; + ubyte InterleaveGap; + uint32 VolSeqNum; + ubyte FileIdLength; + ubyte FileId[1]; +} ROOT_DIR_HEADER; + +typedef struct { + VOLUME_DESCRIPTOR_HEADER Header; + ubyte Flags; + byte SysId[32]; + byte VolId[32]; + uint64 Unused; + uint64 VolSpaceSize; + byte EscSeq[32]; + uint32 VolSetSize; + uint32 VolSeqNum; + uint32 LBlockSize; + uint64 PathTblSize; + uint32 LPathTbl1; + uint32 LPathTbl2; + uint32 MPathTbl1; + uint32 MPathTbl2; + ROOT_DIR_HEADER Root; + byte VolSetId[128]; + byte PublisherId[128]; + byte DataPrepId[128]; + byte ApplicationId[128]; + byte CopyrightFileId[37]; + byte AbstractFileId[37]; + byte BiblioFileId[37]; + CD_DATE_TIME CreationTime; + CD_DATE_TIME ModifyTime; + CD_DATE_TIME ExpireTime; + CD_DATE_TIME EffectiveTime; + ubyte FileStrucVer; + ubyte Unused1; +} PRIMARY_VOLUME_DESC_HEADER; + +LittleEndian(); +FSeek(BOOT_RECORD_OFFSET); + +union { + BOOT_RECORD_DESC boot_record; + PRIMARY_VOLUME_DESC_HEADER primary_volume; +} disk_header; + diff --git a/cparser/InspectorDates.bt b/cparser/InspectorDates.bt new file mode 100644 index 0000000..9ac0f55 --- /dev/null +++ b/cparser/InspectorDates.bt @@ -0,0 +1,174 @@ +//----------------------------------- +//--- 010 Editor v4.0 Binary Template +// +// File: InspectorDates.bt +// Author: SweetScape Software +// Revision: 1.0 +// Purpose: Demonstrates how to add +// a series of date types to the +// Inspector.bt file. Includes +// WebkitTime, HFSTime, AppleTime, PRTime +// JavaTime, GPSTime, and BlackberryDate. +//----------------------------------- +RequiresVersion( 4.0 ); + +// Calculate the position for each variable, +// either at the beginning of the selection +// or at the current cursor position. +local int64 pos; +if( GetSelSize() > 0 ) + pos = GetSelStart(); +else + pos = GetCursorPos(); + +// Define variables for the inspector +FSeek( pos ); byte _si8 ; +FSeek( pos ); ubyte _ui8 ; +FSeek( pos ); short _si16 ; +FSeek( pos ); ushort _ui16 ; +FSeek( pos ); int _si32 ; +FSeek( pos ); uint _ui32 ; +FSeek( pos ); int64 _si64 ; +FSeek( pos ); uint64 _ui64 ; +FSeek( pos ); float _f ; +FSeek( pos ); double _d ; +FSeek( pos ); char _s [ReadStringLength(pos,256)] ; // limit to 256 characters +FSeek( pos ); wchar_t _ws[ReadWStringLength(pos,256)] ; // limit to 256 characters +FSeek( pos ); DOSDATE _dd ; +FSeek( pos ); DOSTIME _dt ; +FSeek( pos ); time_t _tt ; +FSeek( pos ); FILETIME _ft ; +FSeek( pos ); OLETIME _ot ; + +//---------------------------------------------------------------- +// WebkitTime +// 64-bit integer, number of microseconds since 01/01/1601 00:00:00 +typedef uint64 WebkitTime ; +FSeek( pos ); WebkitTime _wkt ; +string WebkitTimeRead( WebkitTime t ) +{ + // Convert to FILETIME + return FileTimeToString( t*10 ); +} +int WebkitTimeWrite( WebkitTime &t, string value ) +{ + // Convert from FILETIME + FILETIME ft; + int result = StringToFileTime( value, ft ); + t = (int64)ft/10; + return result; +} + +//---------------------------------------------------------------- +// HFSTime +// 32-bit integer, number of seconds since 01/01/1904 00:00:00 +typedef uint HFSTime ; +FSeek( pos ); HFSTime _hft ; +string HFSTimeRead( HFSTime t ) +{ + // Convert to FILETIME + return FileTimeToString( t*10000000L + 95616288000000000L ); +} +int HFSTimeWrite( HFSTime &t, string value ) +{ + // Convert from FILETIME + FILETIME ft; + int result = StringToFileTime( value, ft ); + t = (int)(((uint64)ft - 95616288000000000L)/10000000L); + return result; +} + +//---------------------------------------------------------------- +// AppleTime +// 32-bit integer, number of seconds since 01/01/2001 00:00:00 +typedef uint AppleTime ; +FSeek( pos ); AppleTime _at ; +string AppleTimeRead( AppleTime t ) +{ + // Convert to FILETIME + return FileTimeToString( t*10000000L + 126227808000000000L ); +} +int AppleTimeWrite( AppleTime &t, string value ) +{ + // Convert from FILETIME + FILETIME ft; + int result = StringToFileTime( value, ft ); + t = (int)(((uint64)ft - 126227808000000000L)/10000000L); + return result; +} + +//---------------------------------------------------------------- +// PRTime +// 64-bit integer, number of microseconds since 01/01/1970 00:00:00 +typedef uint64 PRTime ; +FSeek( pos ); PRTime _prt ; +string PRTimeRead( PRTime t ) +{ + // Convert to FILETIME + return FileTimeToString( t*10L + 116444736000000000L ); +} +int PRTimeWrite( PRTime &t, string value ) +{ + // Convert from FILETIME + FILETIME ft; + int result = StringToFileTime( value, ft ); + t = (((uint64)ft - 116444736000000000L)/10L); + return result; +} + +//---------------------------------------------------------------- +// JavaTime +// 64-bit integer, number of microseconds since 01/01/1970 00:00:00 +typedef uint64 JavaTime ; +FSeek( pos ); JavaTime _jt ; +string JavaTimeRead( JavaTime t ) +{ + // Convert to FILETIME + return FileTimeToString( t*10000L + 116444736000000000L ); +} +int JavaTimeWrite( JavaTime &t, string value ) +{ + // Convert from FILETIME + FILETIME ft; + int result = StringToFileTime( value, ft ); + t = (((uint64)ft - 116444736000000000L)/10000L); + return result; +} + +//---------------------------------------------------------------- +// GPSTime +// 32-bit integer, number of seconds since 01/06/1980 00:00:00 +typedef uint GPSTime ; +FSeek( pos ); GPSTime _gpst ; +string GPSTimeRead( GPSTime t ) +{ + // Convert to FILETIME + return FileTimeToString( t*10000000L + 119604384000000000 ); +} +int GPSTimeWrite( GPSTime &t, string value ) +{ + // Convert from FILETIME + FILETIME ft; + int result = StringToFileTime( value, ft ); + t = (int)(((uint64)ft - 119604384000000000)/10000000L); + return result; +} + +//---------------------------------------------------------------- +// BlackberryDate +// 32-bit integer, number of minutes since 01/01/1900 00:00:00 +typedef uint BlackberryDate ; +FSeek( pos ); BlackberryDate _gt ; +string BlackberryDateRead( BlackberryDate t ) +{ + // Convert to FILETIME + return FileTimeToString( t*600000000L + 94354848000000000L ); +} +int BlackberryDateWrite( BlackberryDate &t, string value ) +{ + // Convert from FILETIME + FILETIME ft; + int result = StringToFileTime( value, ft ); + t = (int)(((uint64)ft - 94354848000000000L)/600000000L); + return result; +} diff --git a/cparser/InspectorWithMP4DateTime.bt b/cparser/InspectorWithMP4DateTime.bt new file mode 100644 index 0000000..1e3927b --- /dev/null +++ b/cparser/InspectorWithMP4DateTime.bt @@ -0,0 +1,116 @@ +//----------------------------------- +//--- 010 Editor v4.0 Binary Template +// +// File: InspectorMoje.bt +// Author: SweetScape Software +// Revision: 1.1 +// Purpose: This template may be used +// to customize the auto tab of the +// Inspector with your own variables. +// See the Inspector section of the +// Options dialog for more information. +// Changes: +// 1.1 (SweetScape): +// - Added hfloat data type. +// 1.2 (Marian Denes): +// - Added MP4_Time data type +//----------------------------------- +RequiresVersion( 4.0 ); + +// Calculate the position for each variable, +// either at the beginning of the selection +// or at the current cursor position. +local int64 position; +if( GetSelSize() > 0 ) + position = GetSelStart(); +else + position = GetCursorPos(); + + +int leap(int year) +{ + return year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ); +} + +int daysInYear(int year) {return 365 + leap(year);} + + +typedef uint MP4_Time ; + + string MP4_TimeRead( MP4_Time secs ) + { + // secs - seconds since midnight, January 1, 1904 + + int days = secs / 86400; + secs = secs % 86400; + + int year = 1904; + int month = 1; + + int daysInMonth[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int extraDay [13] = {-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + while (days > daysInYear(year)) + { + days -= daysInYear(year); + year++; + } + + while (days > daysInMonth[month] + leap(year) * extraDay[month]) + { + days -= daysInMonth[month] + leap(year) * extraDay[month]; + month++; + } + + int day = ++days; // 0 (full) days remaining means the 1st day of the monht, and so on + + int hours = secs / 3600; + secs = secs % 3600; + int mins = secs / 60; + secs = secs % 60; + + string s; + SPrintf( s, "%02d.%02d.%4d %02d:%02d:%02d", day, month, year, hours, mins, secs ); + return s; + } + + void MP4_TimeWrite( MP4_Time &secs, string dateTime ) + { + int daysInMonth[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int extraDay [13] = {-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + int day, month, year, hour, min, sec; //secs = 0x1122; + SScanf(dateTime, "%d.%d.%d %d:%d:%d", day, month, year, hour, min, sec); + + int days = day - 1; // January 1, 1994 is 0 days after this date, and so on + int months, hours, mins, y, m; + + for (y = 1904; y < year; ++y) + days += daysInYear(y); + + for (m = 1; m < month; ++m) + days += daysInMonth[m] + leap(year) * extraDay[m]; + + secs = days * 86400 + hour * 3600 + min * 60 + sec; + } + +// Define variables for the inspector +FSeek( position ); MP4_Time _mp4t ; +FSeek( position ); byte _si8 ; +FSeek( position ); ubyte _ui8 ; +FSeek( position ); short _si16 ; +FSeek( position ); ushort _ui16 ; +FSeek( position ); int _si32 ; +FSeek( position ); uint _ui32 ; +FSeek( position ); int64 _si64 ; +FSeek( position ); uint64 _ui64 ; +FSeek( position ); float _f ; +FSeek( position ); double _d ; +FSeek( position ); hfloat _hf ; +FSeek( position ); char _s [ReadStringLength(position,256)] ; // limit to 256 characters +FSeek( position ); wchar_t _ws[ReadWStringLength(position,256)] ; // limit to 256 characters +FSeek( position ); DOSDATE _dd ; +FSeek( position ); DOSTIME _dt ; +FSeek( position ); FILETIME _ft ; +FSeek( position ); OLETIME _ot ; +FSeek( position ); time_t _tt ; diff --git a/cparser/JPGTemplate.bt b/cparser/JPGTemplate.bt new file mode 100644 index 0000000..7323a2e --- /dev/null +++ b/cparser/JPGTemplate.bt @@ -0,0 +1,1604 @@ +// 010 Editor v2.02 Binary Template +// +// File : JpgTemplate.bt +// Author : Mor FTP +// Purpose : Designed for jpg files +// E-Mail : morftp AT hotmail DOT com +// LAST MODIFIED : Nov 3 2014 +// This is a detailed JPEG File analysis. +//Features +// 1. Huffmann and quantization tables. +// 2. Exif (APP1) information including jpeg and other thubnail images +// 3. SOS, SOF0, JIFF and APP0 sections +// +// Note : This code doesn't parse all known sections. The reson is the application sections +// contain camera specific information and this information sometimes is not public or +// related to the camera and not important for image display softwares. +// +// New Features: Parses MakerNote for casio qv-r62 +// +// 2014-11-03 SweetScape +// * fixed using FTell instead of Ftell +// +// 2012-10-04 dxp +// * added JPEG-LS marker structure. +// +// 2009-03-14 modified by Kuang-che Wu +// * fix parse fail if encounter unknown APP1 +// * fix uShort typo +// * parse inlined EXIF data correctly +// * recognize more sections and fields, especially EXIF tags, GPS tags, and CIFF tags +// * and many improvements +// +//-------------------------------------- + +// references: +// JPEG http://www.w3.org/Graphics/JPEG/itu-t81.pdf +// JFIF http://www.w3.org/Graphics/JPEG/jfif3.pdf +// EXIF http://www.exif.org/Exif2-2.PDF +// CIFF http://xyrion.org/ciff/CIFFspecV1R04.pdf +// exiftool http://www.sno.phy.queensu.ca/~phil/exiftool/ +// JPEG-LS http://www.itu.int/rec/T-REC-T.87-199806-I/en + + +// set left to right for both endian +LittleEndian(); BitfieldLeftToRight(); +BigEndian(); BitfieldLeftToRight(); + +local quad JpegFileEnd = 0; +local int colorId = 0; +local int colorSelect = 0; +local DWORD clr = 0; +local DWORD jetMap[6*3] = { // blue, red green + 0x0000cc,0x0000ff,0x0033ff,0x0066ff,0x0099ff,0x00ccff, + 0x00ffff,0x33ffcc,0x66ff99,0x99ff66,0xccff33,0xffff00, + 0xffcc00,0xff9900,0xff6600,0xff3300,0xff0000,0xcc0000 +}; +local char CameraMake[32]; +local char CameraModel[40]; + +local string stack_IFD_dirtype = ""; + +enum IFD_dirtype { + IFD_TYPE_EXIF = 1, + IFD_TYPE_GEOTAG, + IFD_TYPE_CASIO_QV_R62, +}; + +// ------------------------------------------------------------ +// helper functions +void Stack_push(string &s, int x) +{ + s += (char)x; +} + +void Stack_pop(string &s) +{ + s = SubStr(s, 0, Strlen(s) - 1); +} + +int Stack_top(string &s) +{ + return s[Strlen(s) - 1]; +} + +string ReadStringN(int64 pos, int n) +{ + local uchar s[n]; + ReadBytes(s, pos, n); + return s; +} + +// ------------------------------------------------------------ + +void ChangeColor(byte bChangeColor) { + if(bChangeColor == 1) {colorSelect++; colorId = 0;} + clr = jetMap[(colorSelect%3)*6+(colorId%6)]; + SetBackColor(clr); + //Printf("clrIdx = [%d %d], RGB(%d,%d,%d)\n",colorSelect,colorId,(clr>>16),(clr>>8)&0x00FF,clr&0x0000FF); + colorId++; +} + +// ------------------------------------------------------------ +// JPEG +typedef enum tagID +{ + M_SOF0 = 0xFFC0, // Start Of Frame N + M_SOF1,// N indicates which compression process + M_SOF2,// Only SOF0-SOF2 are now in common use + M_SOF3, + M_DHT, //Huffman Table + M_SOF5, + M_SOF6, + M_SOF7, + M_JPG, + M_SOF9, + M_SOF10, + M_SOF11, + M_DAC = 0xffcc, + M_SOF13, + M_SOF14, + M_SOF15, + M_RST0 = 0xffd0, + M_RST1, M_RST2, M_RST3, M_RST4, M_RST5, M_RST6, M_RST7, + M_SOI = 0xFFD8, // Start Of Image + M_EOI,// End Of Image + M_SOS,// Start Of Scan (begins compressed data) + M_DQT, + M_DNL, + M_DRI, + M_DHP, + M_EXP, + M_APP0 = 0xFFE0, // Jfif marker + M_APP1,// Exif marker + M_APP2, + M_APP3, + M_APP4, + M_APP5, + M_APP6, + M_APP7, + M_APP8, + M_APP9, + M_APP10, + M_APP11, + M_APP12, + M_APP13, + M_APP14, + M_APP15, + M_JPG0 = 0xfff0, + M_JPG1, M_JPG2, M_JPG3, M_JPG4, M_JPG5, M_JPG6, M_JPGLS, + M_JPG8, M_JPG9, M_JPG10, M_JPG11, M_JPG12, M_JPG13, M_JPG14, M_JPG15, + M_COMM = 0xFFFE // Comment +} M_ID ; + + +// ------------------------------------------------------------ +// EXIF tags + +typedef enum tagExifTag { + /////////////////////////////////// Format Comp Description + InteropIndex = 0x0001, + InteropVersion = 0x0002, + SubfileType = 0x00fe, + OldSubfileType = 0x00ff, + ImageWidth = 0x0100, + ImageHeight = 0x0101, + BitsPerSample = 0x0102, + Compression = 0x0103, + PhotometricInterpretation = 0x0106, + Thresholding = 0x0107, + CellWidth = 0x0108, + CellLength = 0x0109, + FillOrder = 0x010a, + DocumentName = 0x010d, + ImageDescription = 0x010e, + Make = 0x010f, + Model = 0x0110, + StripOffsets = 0x0111, + Orientation = 0x0112, + SamplesPerPixel = 0x0115, + RowsPerStrip = 0x0116, + StripByteCounts = 0x0117, + MinSampleValue = 0x0118, + MaxSampleValue = 0x0119, + XResolution = 0x011a, + YResolution = 0x011b, + PlanarConfiguration = 0x011c, + PageName = 0x011d, + XPosition = 0x011e, + YPosition = 0x011f, + FreeOffsets = 0x0120, + FreeByteCounts = 0x0121, + GrayResponseUnit = 0x0122, + GrayResponseCurve = 0x0123, + T4Options = 0x0124, + T6Options = 0x0125, + ResolutionUnit = 0x0128, + PageNumber = 0x0129, + ColorResponseUnit = 0x012c, + TransferFunction = 0x012d, + Software = 0x0131, + ModifyDate = 0x0132, + Artist = 0x013b, + HostComputer = 0x013c, + Predictor = 0x013d, + WhitePoint = 0x013e, + PrimaryChromaticities = 0x013f, + ColorMap = 0x0140, + HalftoneHints = 0x0141, + TileWidth = 0x0142, + TileLength = 0x0143, + TileOffsets = 0x0144, + TileByteCounts = 0x0145, + BadFaxLines = 0x0146, + CleanFaxData = 0x0147, + ConsecutiveBadFaxLines = 0x0148, + SubIFD = 0x014a, + InkSet = 0x014c, + InkNames = 0x014d, + NumberofInks = 0x014e, + DotRange = 0x0150, + TargetPrinter = 0x0151, + ExtraSamples = 0x0152, + SampleFormat = 0x0153, + SMinSampleValue = 0x0154, + SMaxSampleValue = 0x0155, + TransferRange = 0x0156, + ClipPath = 0x0157, + XClipPathUnits = 0x0158, + YClipPathUnits = 0x0159, + Indexed = 0x015a, + JPEGTables = 0x015b, + OPIProxy = 0x015f, + GlobalParametersIFD = 0x0190, + ProfileType = 0x0191, + FaxProfile = 0x0192, + CodingMethods = 0x0193, + VersionYear = 0x0194, + ModeNumber = 0x0195, + Decode = 0x01b1, + DefaultImageColor = 0x01b2, + JPEGProc = 0x0200, + ThumbnailOffset = 0x0201, + ThumbnailLength = 0x0202, + JPEGRestartInterval = 0x0203, + JPEGLosslessPredictors = 0x0205, + JPEGPointTransforms = 0x0206, + JPEGQTables = 0x0207, + JPEGDCTables = 0x0208, + JPEGACTables = 0x0209, + YCbCrCoefficients = 0x0211, + YCbCrSubSampling = 0x0212, + YCbCrPositioning = 0x0213, + ReferenceBlackWhite = 0x0214, + StripRowCounts = 0x022f, + ApplicationNotes = 0x02bc, + RelatedImageFileFormat = 0x1000, + RelatedImageWidth = 0x1001, + RelatedImageLength = 0x1002, + ImageID = 0x800d, + WangAnnotation = 0x80a4, + Matteing = 0x80e3, + DataType = 0x80e4, + ImageDepth = 0x80e5, + TileDepth = 0x80e6, + Model2 = 0x827d, + CFARepeatPatternDim = 0x828d, + CFAPattern2 = 0x828e, + BatteryLevel = 0x828f, + Copyright = 0x8298, + ExposureTime = 0x829a, + FNumber = 0x829d, + PixelScale = 0x830e, + IPTC_NAA = 0x83bb, + IntergraphPacketData = 0x8474, + IntergraphFlagRegisters = 0x847f, + IntergraphMatrix = 0x8480, + ModelTiePoint = 0x8482, + Site = 0x84e0, + ColorSequence = 0x84e1, + IT8Header = 0x84e2, + RasterPadding = 0x84e3, + BitsPerRunLength = 0x84e4, + BitsPerExtendedRunLength = 0x84e5, + ColorTable = 0x84e6, + ImageColorIndicator = 0x84e7, + BackgroundColorIndicator = 0x84e8, + ImageColorValue = 0x84e9, + BackgroundColorValue = 0x84ea, + PixelIntensityRange = 0x84eb, + TransparencyIndicator = 0x84ec, + ColorCharacterization = 0x84ed, + HCUsage = 0x84ee, + IPTC_NAA2 = 0x8568, + ModelTransform = 0x85d8, + PhotoshopSettings = 0x8649, + ExifOffset = 0x8769, + ICC_Profile = 0x8773, + ImageLayer = 0x87ac, + GeoTiffDirectory = 0x87af, + GeoTiffDoubleParams = 0x87b0, + GeoTiffAsciiParams = 0x87b1, + ExposureProgram = 0x8822, + SpectralSensitivity = 0x8824, + GPSInfo = 0x8825, + ISO = 0x8827, + OptoElectricConvFactor = 0x8828, + Interlace = 0x8829, + TimeZoneOffset = 0x882a, + SelfTimerMode = 0x882b, + FaxRecvParams = 0x885c, + FaxSubAddress = 0x885d, + FaxRecvTime = 0x885e, + ExifVersion = 0x9000, + DateTimeOriginal = 0x9003, + CreateDate = 0x9004, + ComponentsConfiguration = 0x9101, + CompressedBitsPerPixel = 0x9102, + ShutterSpeedValue = 0x9201, + ApertureValue = 0x9202, + BrightnessValue = 0x9203, + ExposureCompensation = 0x9204, + MaxApertureValue = 0x9205, + SubjectDistance = 0x9206, + MeteringMode = 0x9207, + LightSource = 0x9208, + Flash = 0x9209, + FocalLength = 0x920a, + FlashEnergy = 0x920b, + SpatialFrequencyResponse = 0x920c, + Noise = 0x920d, + FocalPlaneXResolution = 0x920e, + FocalPlaneYResolution = 0x920f, + FocalPlaneResolutionUnit = 0x9210, + ImageNumber = 0x9211, + SecurityClassification = 0x9212, + ImageHistory = 0x9213, + SubjectLocation = 0x9214, + ExposureIndex = 0x9215, + TIFF_EPStandardID = 0x9216, + SensingMethod = 0x9217, + StoNits = 0x923f, + MakerNote = 0x927c, + UserComment = 0x9286, + SubSecTime = 0x9290, + SubSecTimeOriginal = 0x9291, + SubSecTimeDigitized = 0x9292, + ImageSourceData = 0x935c, + XPTitle = 0x9c9b, + XPComment = 0x9c9c, + XPAuthor = 0x9c9d, + XPKeywords = 0x9c9e, + XPSubject = 0x9c9f, + FlashpixVersion = 0xa000, + ColorSpace = 0xa001, + ExifImageWidth = 0xa002, + ExifImageLength = 0xa003, + RelatedSoundFile = 0xa004, + InteropOffset = 0xa005, + FlashEnergy2 = 0xa20b, + SpatialFrequencyResponse2 = 0xa20c, + Noise2 = 0xa20d, + FocalPlaneXResolution2 = 0xa20e, + FocalPlaneYResolution2 = 0xa20f, + FocalPlaneResolutionUnit2 = 0xa210, + ImageNumber2 = 0xa211, + SecurityClassification2 = 0xa212, + ImageHistory2 = 0xa213, + SubjectLocation2 = 0xa214, + ExposureIndex2 = 0xa215, + TIFF_EPStandardID2 = 0xa216, + SensingMethod2 = 0xa217, + FileSource = 0xa300, + SceneType = 0xa301, + CFAPattern = 0xa302, + CustomRendered = 0xa401, + ExposureMode = 0xa402, + WhiteBalance = 0xa403, + DigitalZoomRatio = 0xa404, + FocalLengthIn35mmFormat = 0xa405, + SceneCaptureType = 0xa406, + GainControl = 0xa407, + Contrast = 0xa408, + Saturation = 0xa409, + Sharpness = 0xa40a, + DeviceSettingDescription = 0xa40b, + SubjectDistanceRange = 0xa40c, + ImageUniqueID = 0xa420, + GDALMetadata = 0xa480, + GDALNoData = 0xa481, + Gamma = 0xa500, + FilmProductCode = 0xc350, + ImageSourceEK = 0xc351, + CaptureConditionsPAR = 0xc352, + CameraOwner = 0xc353, + SerialNumber = 0xc354, + UserSelectGroupTitle = 0xc355, + DealerIDNumber = 0xc356, + CaptureDeviceFID = 0xc357, + EnvelopeNumber = 0xc358, + FrameNumber = 0xc359, + FilmCategory = 0xc35a, + FilmGencode = 0xc35b, + ModelAndVersion = 0xc35c, + FilmSize = 0xc35d, + SBA_RGBShifts = 0xc35e, + SBAInputImageColorspace = 0xc35f, + SBAInputImageBitDepth = 0xc360, + SBAExposureRecord = 0xc361, + UserAdjSBA_RGBShifts = 0xc362, + ImageRotationStatus = 0xc363, + RollGuidElements = 0xc364, + MetadataNumber = 0xc365, + EditTagArray = 0xc366, + Magnification = 0xc367, + NativeXResolution = 0xc36c, + NativeYResolution = 0xc36d, + KodakEffectsIFD = 0xc36e, + KodakBordersIFD = 0xc36f, + NativeResolutionUnit = 0xc37a, + SourceImageDirectory = 0xc418, + SourceImageFileName = 0xc419, + SourceImageVolumeName = 0xc41a, + OceScanjobDesc = 0xc427, + OceApplicationSelector = 0xc428, + OceIDNumber = 0xc429, + OceImageLogic = 0xc42a, + Annotations = 0xc44f, + PrintQuality = 0xc46c, + ImagePrintStatus = 0xc46e, + PrintIM = 0xc4a5, + DNGVersion = 0xc612, + DNGBackwardVersion = 0xc613, + UniqueCameraModel = 0xc614, + LocalizedCameraModel = 0xc615, + CFAPlaneColor = 0xc616, + CFALayout = 0xc617, + LinearizationTable = 0xc618, + BlackLevelRepeatDim = 0xc619, + BlackLevel = 0xc61a, + BlackLevelDeltaH = 0xc61b, + BlackLevelDeltaV = 0xc61c, + WhiteLevel = 0xc61d, + DefaultScale = 0xc61e, + DefaultCropOrigin = 0xc61f, + DefaultCropSize = 0xc620, + ColorMatrix1 = 0xc621, + ColorMatrix2 = 0xc622, + CameraCalibration1 = 0xc623, + CameraCalibration2 = 0xc624, + ReductionMatrix1 = 0xc625, + ReductionMatrix2 = 0xc626, + AnalogBalance = 0xc627, + AsShotNeutral = 0xc628, + AsShotWhiteXY = 0xc629, + BaselineExposure = 0xc62a, + BaselineNoise = 0xc62b, + BaselineSharpness = 0xc62c, + BayerGreenSplit = 0xc62d, + LinearResponseLimit = 0xc62e, + DNGCameraSerialNumber = 0xc62f, + DNGLensInfo = 0xc630, + ChromaBlurRadius = 0xc631, + AntiAliasStrength = 0xc632, + ShadowScale = 0xc633, + DNGPrivateData = 0xc634, + MakerNoteSafety = 0xc635, + CalibrationIlluminant1 = 0xc65a, + CalibrationIlluminant2 = 0xc65b, + BestQualityScale = 0xc65c, + AliasLayerMetadata = 0xc660, + OwnerName = 0xfde8, + SerialNumber2 = 0xfde9, + Lens = 0xfdea, + RawFile = 0xfe4c, + Converter = 0xfe4d, + WhiteBalance2 = 0xfe4e, + Exposure = 0xfe51, + Shadows = 0xfe52, + Brightness = 0xfe53, + Contrast2 = 0xfe54, + Saturation2 = 0xfe55, + Sharpness2 = 0xfe56, + Smoothness = 0xfe57, + MoireFilter = 0xfe58, +} ExifTag; + +enum GeoTag { + GPSVersionID, + GPSLatitudeRef, + GPSLatitude, + GPSLongitudeRef, + GPSLongitude, + GPSAltitudeRef, + GPSAltitude, + GPSTimeStamp, + GPSSatellites, + GPSStatus, + GPSMeasureMode, + GPSDOP, + GPSSpeedRef, + GPSSpeed, + GPSTrackRef, + GPSTrack, + GPSImgDirectionRef, + GPSImgDirection, + GPSMapDatum, + GPSDestLatitudeRef, + GPSDestLatitude, + GPSDestLongitudeRef, + GPSDestLongitude, + GPSDestBearingRef, + GPSDestBearing, + GPSDestDistanceRef, + GPSDestDistance, + GPSProcessingMehotd, + GPSAreaInformation, + GPSDateStamp, + GPSDifferential, +}; + +// ------------------------------------------------------------ +// Casio tag +typedef enum tagCasioTag2 { + PreviewThumbnailDimensions = 0x0002,//Numeric 2 values - x,y dimensions in pixels + PreviewThumbnailSize = 0x0003,//Numeric Size in bytes + PreviewThumbnailOffset = 0x0004,//Numeric Offset of Preview Thumbnail + CSQualityMode = 0x0008,//Numeric Lookup 1 = Fine 2 = Super Fine + CsImageSize = 0x0009,//Numeric Lookup 0 = 640 x 480 pixels 4 = 1600 x 1200 pixels 5 = 2048 x 1536 pixels 20 = 2288 x 1712 pixels 21 = 2592 x 1944 pixels 22 = 2304 x 1728 pixels 36 = 3008 x 2008 pixels + CSFocusMode = 0x000D,//Numeric Lookup 0 = Normal 1 = Macro + CsIsoSensitivity = 0x0014,//Numeric Lookup 3 = 50 4 = 64 6 = 100 9 = 200 + CsWhiteBalance = 0x0019,//Numeric Lookup 0 = Auto 1 = Daylight 2 = Shade 3 = Tungsten 4 = Fluorescent 5 = Manual + CsFocalLength = 0x001D,//Numeric Units are tenths of a millimetre + CsSaturation = 0x001F,//Numeric Lookup 0 = -1 1 = Normal 2 = +1 + CsContrast = 0x0020,//Numeric Lookup 0 = -1 1 = Normal 2 = +1 + CsSharpness = 0x0021,//Numeric Lookup 0 = -1 1 = Normal 2 = +1 + CsPrintImageMatchingInfo = 0x0E00,//PIM See Print Image Matching for specification + CasioPreviewThumbnail = 0x2000,//Numeric Alternate thumbnail offset + CsWhiteBalanceBias = 0x2011,//Numeric + CsFlashMode = 0x2012,//Numeric Lookup 12 = Flash 0 = Manual 1 = Auto? 4 = Flash? + CsObjectDistance = 0x2022,//Numeric Units are millimetres + CsFlashDistance = 0x2034,//Numeric 0 = Off + CsRecordMode = 0x3000,//Numeric Lookup 2 = Normal Mode + CsSelfTimer = 0x3001,//Numeric Lookup 1 = Off? + CsQuality = 0x3002,//Numeric Lookup 3 = Fine + CsMeteringMode2 = 0x3003,//Numeric Lookup 1 = Fixation 6 = Multi-Area Auto Focus + CsTimeZone = 0x3006,//String + CsBestshotMode = 0x3007,//Numeric Lookup 0 = Off 1 = On? + CsCCDISOSensitivity = 0x3014,//Numeric + CsColourMode = 0x3015,//Numeric Lookup 0 = Off + CsEnhancement = 0x3016,//Numeric Lookup 0 = Off + CsFilter = 0x3017,//Numeric Lookup 0 = Off +} CasioTag2; + + +// ------------------------------------------------------------ +// Canon CIFF +typedef uint32 DC_UINT32; +typedef int32 DC_SINT32; +typedef float DC_FLOAT32; + +typedef struct tgCifDirEntry { + uint16 storage_method : 2; // 00 in heap, 01 in entry + uint16 data_type : 3; + uint16 id_code : 11 ; + if (storage_method == kStg_InHeapSpace) { + DWORD sData; // Data Size (Bytes) + DWORD oData; // Data Offset + } else { + switch (data_type << 11 | id_code) { + case kTC_ImageFormat: + DC_UINT32 fileFormat; + DC_FLOAT32 targetCompressionRatio; + break; + default: + byte data[8]; + break; + } + } +} CifDirEntry ; + +enum CIFFTagStg { + kStg_InHeapSpace, + kStg_InRecordEntry, + kStg_reversed2, + kStg_reversed3, +}; + +enum CIFFTagDataType { + kDT_BYTE = 0x0000, + kDT_ASCII = 0x0800, + kDT_WORD = 0x1000, + kDT_DWORD = 0x1800, + kDT_BYTE2 = 0x2000, + kDT_HeapTypeProperty1 = 0x2800, + kDT_HeapTypeProperty2 = 0x3000, +}; + +enum CIFFTagType { + kTC_Null = 0, + kTC_Free, + kTC_ExFree, + + kTC_Description = 0x0805,//kDT_ASCII | 0x0005, + kTC_ModelName = 0x080a,//kDT_ASCII | 0x000a, + kTC_FirmwareVersion = 0x080b,//kDT_ASCII | 0x000b, + kTC_ComponentVersion = 0x080c,//kDT_ASCII | 0x000c, + kTC_ROMOperationMode = 0x080d,//kDT_ASCII | 0x000d, + kTC_OwnerName = 0x0810,//kDT_ASCII | 0x0010, + kTC_ImageFileName = 0x0816,//kDT_ASCII | 0x0016, + kTC_ThumbnailFileName = 0x0817,//kDT_ASCII | 0x0017, + + kTC_TargetImageType = 0x100a,//kDT_WORD | 0x000a, + kTC_SR_ReleaseMethod = 0x1010,//kDT_WORD | 0x0010, + kTC_SR_ReleaseTiming = 0x1011,//kDT_WORD | 0x0011, + kTC_ReleaseSetting = 0x1016,//kDT_WORD | 0x0016, + kTC_BodySensitivity = 0x101c,//kDT_WORD | 0x001c, + + kTC_ImageFormat = 0x1803,//kDT_DWORD | 0x0003, + kTC_RecordID = 0x1804,//kDT_DWORD | 0x0004, + kTC_SelfTimerTime = 0x1806,//kDT_DWORD | 0x0006, + kTC_SR_TargetDistanceSetting = 0x1807,//kDT_DWORD | 0x0007, + kTC_BodyID = 0x180b,//kDT_DWORD | 0x000b, + kTC_CapturedTime = 0x180e,//kDT_DWORD | 0x000e, + kTC_ImageSpec = 0x1810,//kDT_DWORD | 0x0010, + kTC_SR_EF = 0x1813,//kDT_DWORD | 0x0013, + kTC_MI_EV = 0x1814,//kDT_DWORD | 0x0014, + kTC_SerialNumber = 0x1817,//kDT_DWORD | 0x0017, + + kTC_CameraObject = 0x2807,//0x0007 | kDT_HeapTypeProperty1, + kTC_ShootingRecord = 0x3002,//0x0002 | kDT_HeapTypeProperty2, + kTC_MeasuredInfo = 0x3003,//0x0003 | kDT_HeapTypeProperty2, + kTC_CameraSpecification = 0x3004,//0x0004 | kDT_HeapTypeProperty2, +}; + +string ReadCifDirEntry(CifDirEntry &e) +{ + local string s; + local uint16 tc = e.data_type << 11 | e.id_code; + local CIFFTagType x = (CIFFTagType) tc; + local CIFFTagStg stg = (CIFFTagStg)e.storage_method; + local CIFFTagDataType dt = (CIFFTagDataType)(e.data_type << 11); + if (EnumToString(x) != "") { + SPrintf(s, "%s, %s", + EnumToString(stg), + EnumToString(x)); + } else { + SPrintf(s, "%s, %s, 0x%x", + EnumToString(stg), + EnumToString(dt), + e.id_code); + } + + return s; +} + +typedef struct tgCDir { + ChangeColor(0); + //Printf("off %#Lx doff %#Lx dsz %#Lx\n",cifOffset , cDirOffset ,cDirSize); + local quad myOffset = cDirOffset; + local DWORD S = ReadInt(myOffset + cDirSize - 4); + FSeek(cDirOffset + S); + //Printf("S @ %#x = %#x FTell %#Lx",S,myOffset + cDirSize - 4,FTell()); + WORD nDirEntry; + //Printf(" nEntry %#x\n",nDirEntry); + ChangeColor(0); + CifDirEntry dirEntries[nDirEntry]; + DWORD szValues; // = S + local int i; + for(i=0;i>1]; + } str2Bytes; + break; + case kDT_DWORD: + union { + DWORD dwData[dirEntries[i].sData>>2]; + DWORD flData[dirEntries[i].sData>>2]; + } str4Bytes; + break; + case kDT_HeapTypeProperty1: + case kDT_HeapTypeProperty2: + cDirOffset = dirEntries[i].oData + myOffset; + cDirSize = dirEntries[i].sData; + struct CDIR subDir; + break; + default: + struct { + char uData[dirEntries[i].sData]; + } strUnknown; + break; + } + break; + } + } + //else value is samaller than 8 byte so it is stored in sData and oData of CifDirEntry struct + } + +} CDIR; + +// ------------------------------------------------------------ +// JPEG APPx segments +const local int dataFormatLength[13] = {0,1,1,2,4,8,1,1,2,4,8,4,8}; + +typedef enum tagDataFormat { + uByte = 1, + ascString, + uShort, + uLong, + uRatio, + sByte, + undefined = 7, + sShort, + sLong = 9, + sRatio, + sFloat, + dFloat, +} DataFormat; + + +typedef struct tgDIRENTRY { + ChangeColor(0); + switch (Stack_top(stack_IFD_dirtype)) { + case IFD_TYPE_EXIF: + ExifTag tagNumber; + break; + case IFD_TYPE_GEOTAG: + GeoTag tagNumber; + break; + case IFD_TYPE_CASIO_QV_R62: + CasioTag2 tagNumber; + break; + } + DataFormat dataFormat; + DWORD nComponent; + local int j = 0; + local int length = -1; + + if (1 <= dataFormat && dataFormat < 13) + length = dataFormatLength[dataFormat] * nComponent; + else { + //Warning("unknown dataFormat = %x", dataFormat); + } + + if (1 <= dataFormat && dataFormat < 13 && 0 <= length && length <= 4) { + switch (tagNumber) { + case ExposureProgram: + enum { + EP_Not_defined, + EP_Manual, + EP_Normal_program, + EP_Aperture_priority, + EP_Shutter_priority, + EP_Creative_program, + EP_Action_program, + EP_Portrait_mode, + EP_Landscape_mode, + } ExposureProgram; + break; + case MeteringMode: + enum { + MM_unknown, + MM_Average, + MM_CenterWeightedAverage, + MM_Spot, + MM_MultiSpot, + MM_Pattern, + MM_Partial, + MM_other = 255, + } MeteringMode; + break; + case LightSource: + enum { + LS_unknown, + LS_Daylight, + LS_Fluorescent, + LS_Tungsten, + LS_Flash, + LS_Fine_weather = 9, + LS_Cloudy_weather, + LS_Shade, + LS_Daylight_fluorescent, + LS_Day_white_fluorescent, + LS_Cool_white_fluorescent, + LS_White_fluorescent, + LS_Standard_light_A, + LS_Standard_light_B, + LS_Standard_light_C, + LS_D55, + LS_D65, + LS_D75, + LS_D50, + LS_ISO_studio_tungsten, + LS_other_light_scoure = 255, + } LightSource; + break; + case Flash: + short unused : 9; + short red_eye_mode : 1; + short flash_function : 1; + short flash_mode : 2; + short flash_return : 2; + short flash_fired : 1; + break; + case ExposureMode: + enum { + EM_Auto_exposure, + EM_Manual_exposure, + EM_Auto_bracket, + } ExposureMode; + break; + case WhiteBalance: + enum { + WB_Auto_white_balance, + WB_Manual_white_balance, + } WhiteBalance; + break; + case SceneCaptureType: + enum { + SCT_Standard, + SCT_Landscape, + SCT_Portrait, + SCT_Night_scene, + } SceneCaptureType; + break; + case SubjectDistanceRange: + enum { + SDR_unknown, + SDR_Macro, + SDR_Close_view, + SDR_Distant_view, + } SubjectDistanceRange; + break; + default: + switch (dataFormat) { + case uByte: + struct { + uchar oneByteData[nComponent]; + } strAscii; + break; + case ascString: + struct StrAscii1 { + char oneByteData[nComponent]; + } strAscii ; + break; + case undefined: + struct { + uchar oneByteData[nComponent]; + } strAscii; + break; + case uShort: + for (j = 0; j < nComponent; j++) + ushort usValue; + break; + case uLong: + if (nComponent == 1) + ulong ulValue; + break; + case sByte: + struct { + char sBValue[nComponent]; + } strSByte; + break; + case sShort: + struct { + short sisValue[nComponent]; + } strSShort; + break; + case sLong: + if (nComponent == 1) + ulong siLValue; + break; + case sFloat: + if (nComponent == 1) + float flValue; + break; + } + break; + } + if (length != 4) + uchar padding[4 - length]; + } else { + DWORD offsetData; + } +} DIRENTRY; + +string ReadDirEntry(DIRENTRY &entry) { + local char no[50]; + SPrintf(no,"Tag# = 0x%x (%s)",entry.tagNumber, EnumToString(entry.tagNumber)); + return no; +} + + +typedef struct tgIFD { + WORD nDirEntry; + DIRENTRY dirEntry[nDirEntry]; + DWORD nextIFDoffset; + local int i = 0; + for(i=0;i; + break; + case undefined: + struct { + uchar oneByteData[dirEntry[i].nComponent]; + } strAscii; + break; + case uShort: + struct { + ushort usValue[dirEntry[i].nComponent]; + } strUShort; + break; + case uLong: + struct { + ulong ulValue[dirEntry[i].nComponent]; + } strULong; + break; + case uRatio: + struct URatio { + struct { + DWORD num; + DWORD den; + } uRValue[dirEntry[i].nComponent]; + } strURatio ; + break; + case sByte: + struct { + char sBValue[dirEntry[i].nComponent]; + } strSByte; + break; + case sShort: + struct { + short sisValue[dirEntry[i].nComponent]; + } strSShort; + break; + case sLong: + struct { + ulong siLValue[dirEntry[i].nComponent]; + } strSLong; + break; + case sRatio: + struct { + struct { + int num; + int den; + } siRValue[dirEntry[i].nComponent]; + } strSRatio; + break; + case sFloat: + struct { + float flValue[dirEntry[i].nComponent]; + } strsFloat; + break; + case dFloat: + struct { + double dFValue[dirEntry[i].nComponent]; + } strdFloat; + break; + } + } + } + + for(i=0;i; + switch (extension_code) { + case 0x10: + local quad JpegFileEnd2 = JpegFileEnd; + JpegFileEnd = FTell() + szSection - 8; + struct JPGFILE thumbnail; + JpegFileEnd = JpegFileEnd2; + break; + case 0x11: + ubyte xThumbnail; + ubyte yThumbnail; + struct { + uchar r, g, b; + } palette[256]; + uchar pixel[szSection - 8]; + break; + case 0x13: + ubyte xThumbnail; + ubyte yThumbnail; + struct { + uchar r, g, b; + } pixel[(ushort)xThumbnail * yThumbnail]; + break; + default: + //Warning("Unknown JFXX"); + char unknown[szSection - 8]; + } + } else if((ReadStringN(FTell(), 2) == "II" || ReadStringN(FTell(), 2) == "MM") + && ReadStringN(FTell() + 6, 8) == "HEAPJPGM") { + // Canon CIFF + local quad cDirSize = 0; + local quad cDirOffset = 0; + local quad cifOffset = FTell(); + //CIFF Header + char ByteOrder[2]; + if(!Strncmp(ByteOrder,"II",2)) LittleEndian(); + DWORD HeaderLength; + char type[4]; // "HEAP" + char subtype[4]; // "JPGM" + + //Ciff Directory + cDirOffset = HeaderLength + cifOffset; + cDirSize = szSection - 2 - HeaderLength; + CDIR APP0_Ciff; + BigEndian(); + FSeek(cifOffset + szSection - 2); + } + else { + //Warning("Unknown APP0"); + char unknown[szSection - 2]; + } +} APP0; + +typedef struct tgAPP1 { + M_ID marker; + WORD szSection; + + if (ReadStringN(FTell(), 5) == "Exif") { + char EXIF[6]; + local quad offset = FTell(); + byte align[2]; + if(align[0]=='I') { LittleEndian(); } + WORD tagMark; // 0x002a + DWORD offsetFirstIFD; + if(offsetFirstIFD!=8) + FSeek(offset + offsetFirstIFD); + ChangeColor(0); + Stack_push(stack_IFD_dirtype, IFD_TYPE_EXIF); + IFD ifdMainImage; + Stack_pop(stack_IFD_dirtype); + if(ifdMainImage.nextIFDoffset) { + FSeek(offset + ifdMainImage.nextIFDoffset); + ChangeColor(0); + Stack_push(stack_IFD_dirtype, IFD_TYPE_EXIF); + IFD ifdThumbnailImage; + Stack_pop(stack_IFD_dirtype); + local int i = 0; + local int thumbOffset = 0; + local int thumbLength = 0; + local int compression = 10; + for(i;i 0) { + struct { + enum { + DK_End, + DK_Quality, + DK_Comment, + DK_Copyright, + } tag; + if (tag == DK_End) + break; + + uint16 len; + + switch (tag) { + case DK_End: + break; + case DK_Quality: + uint32 value; + break; + case DK_Comment: + uint32 count; + char comment[len - 4]; + break; + case DK_Copyright: + uint32 count; + char comment[len - 4]; + break; + default: + char unknown[len]; + break; + } + } entry; + if (entry.tag == DK_End) + break; + s -= sizeof(entry); + } + } else { + //Warning("Unknown APP12"); + char unknown[szSection - 2]; + } +} APP12; + +typedef struct tagAPP13 { + M_ID marker; + WORD szSection; + + if (ReadStringN(FTell(), 14) == "Photoshop 3.0") { + // refer to ExifTool Photoshop.pm + char photoshop30[14]; + local int remainsize = szSection - 16; + while (remainsize > 0) { + struct { + char type[4]; + if (type == "8BIM") { + } else if (type == "PHUT" || type == "DCSR" || type == "AgHg") { + } else { + char unknown[remainsize - 4]; + break; + } + enum { + PS_IPTCData = 0x0404, + PS_JPEG_Quality = 0x0406, + PS_PhotoshopBGRThumbnail = 0x0409, + PS_CopyrightFlag = 0x040a, + PS_URL = 0x040b, + PS_PhotoshopThumbnail = 0x040c, + PS_ICC_Profile = 0x040f, + PS_GlobalAltitude = 0x0419, + PS_EXIFInfo = 0x0422, + PS_XMP = 0x0424, + PS_IPTCDigest = 0x0425, + PS_ClippingPathName = 0x0bb7, + } tag; + uchar namelen; + if (namelen) + char name[namelen]; + if (namelen % 2 != 1) + char padding; + uint32 size; + if (size) + char data[size]; + if (size % 2 != 0) + char padding; + } block; + remainsize -= sizeof(block); + } + } else if (ReadStringN(FTell(), 9) == "Adobe_CM") { + char adobe_cm[9]; + uchar AdobeCMType; + if (szSection != 12) + char unknown[szSection - 12]; + } else { + //Warning("Unknown APP13"); + char unknown[szSection - 2]; + } +} APP13; + +typedef struct tagAPP14 { + M_ID marker; + WORD szSection; + + if (ReadStringN(FTell(), 5) == "Adobe") { + // http://partners.adobe.com/public/developer/en/ps/sdk/5116.DCT_Filter.pdf + char adobe[5]; + uint16 version; + uint16 flag0; + uint16 flag1; + uchar color_transform_code; + if (FTell() < szSection + startof(szSection)) char unknown[szSection + startof(szSection) - FTell()]; + } else { + //Warning("Unknown APP14"); + char unknown[szSection - 2]; + } +} APP14; + +// ------------------------------------------------------------ +// JPEG segments +typedef struct tagSOS { + M_ID marker; + WORD szSection; + ubyte nr_comp; + ChangeColor(0); + struct COMPSOS { + ubyte AC:4; + ubyte DC:4; + } comp[nr_comp]; + uchar Ss; + uchar Se; + uchar Ah : 4; + uchar Al : 4; +} SOS; + +typedef struct tagUNK { + M_ID UnknownMarker; + //Warning("Unknown Section 0x%08x %s", UnknownMarker, EnumToString(UnknownMarker)); + WORD szSection; + if (FTell() + szSection - 2 >= JpegFileEnd) { + Warning("unknown section length pass the end of jpeg file"); + ubyte unknown[JpegFileEnd - FTell()]; + } else { + ubyte unknown[szSection-2]; + } +} UNKNOWN; + +typedef struct tagDHT { + M_ID marker; + WORD szSection; + local WORD huffsz = szSection - 2; + while(huffsz > 0) { + ChangeColor(0); + struct Huffmann_Table { + ubyte htInfo; + ubyte length[16]; + local int sumLen = 0; + local int i = 0; + for(i;i<16;i++) { + sumLen += length[i]; + } + ubyte HTV[sumLen]; + } huff_table; + huffsz -= sizeof(huff_table); + } +} DHT; + +typedef struct tagDQT { + M_ID marker; + WORD szSection; + local WORD qtsz = szSection - 2; + while(qtsz > 0) { + ChangeColor(0); + struct QuanTable { + uchar Pq : 4; + uchar Tq : 4; + if (Pq == 0) + byte qTable[64]; + else + uint16 qTable[64]; + } qtable; + qtsz -= sizeof(qtable); + } +} DQT; + +typedef struct tagDRI { + M_ID marker; + WORD szSection; + WORD Ri; +} DRI; + +typedef struct tagDHP { + M_ID marker; + WORD szSection; + uchar P; + uint16 Y; + uint16 X; + uchar Nf; + struct { + uchar id; + uchar h_factor : 4; + uchar v_factor : 4; + uchar Tq; + } component_param[Nf]; +} DHP; + +typedef struct tgSOFx { + M_ID marker; + WORD szSection; + ubyte precision; + WORD Y_image; + WORD X_image; + ubyte nr_comp; + ChangeColor(0); + struct COMPS { + ubyte compId; + ubyte Horz:4; + ubyte Vert:4; + ubyte compNr; + } comp[nr_comp]; +} SOFx; + +typedef struct tagCOMMENT { + M_ID CommentMarker; + WORD szSection; + char comment[szSection-2]; + + + local char comments[szSection-1] = {0}; + local int i = 0; + Memcpy(comments,comment,szSection-2); + for(i=0;i; + +typedef struct tagJPGLS { + M_ID marker; + WORD szSection; + + uchar precision ; + WORD Y_numlines; + WORD X_numcols; + uchar Nf ; + uchar C_compID; + uchar sub_sampling; + uchar Tq ; + + if (11 < szSection) + uchar uknown[szSection - 11]; +} JPGLS; + +string ReadComment( COMMENT &com ) +{ + return com.comment; +} + +JpegFileEnd = FileSize(); + +// ------------------------------------------------------------ +// JPEG file + +SetBackColor(jetMap[0]); +typedef struct tgJPGFile { + local int was_bigendian = IsBigEndian(); + BigEndian(); + local WORD NextMarker; + local quad fpos2; + local byte bEOI = 0; + while(FTell() < JpegFileEnd && !bEOI) { + // skip optional 0xff before marker + while (ReadUShort(FTell()) == 0xffff) FSkip(1); + + NextMarker = ReadUShort(FTell()); + switch(NextMarker) { + case M_SOI: + M_ID SOIMarker; + Printf("Start of Image Marker\n"); + break; + case M_SOS: + SOS scanStart; + Printf("Start of Scan Marker\n"); + NextMarker = ReadUShort(JpegFileEnd - 2); + fpos2 = 0; + while(NextMarker != M_EOI) { + NextMarker = ReadUShort(JpegFileEnd - 2 - (++fpos2)); + } + char scanData[JpegFileEnd - FTell() - 2 - fpos2]; + ChangeColor(1); + M_ID EOIMarker; + Printf("End of File Image\n"); + if(fpos2) char unknownPadding[fpos2]; + bEOI = 1; + break; + case M_APP0: + APP0 app0; + break; + case M_DHT: + DHT dht; + break; + case M_DQT: + DQT dqt; + break; + case M_DRI: + DRI dri; + break; + case M_DHP: + DHP dhp; + break; + case M_SOF0: + SOFx sof0; + break; + case M_SOF1: + SOFx sof1; + break; + case M_SOF2: + SOFx sof2; + break; + case M_APP1: + APP1 app1; + break; + case M_APP2: + APP2 app2; + break; + case M_APP12: + APP12 app12; + break; + case M_APP13: + APP13 app13; + break; + case M_APP14: + APP14 app14; + break; + case M_COMM: + COMMENT comment; + break; + case M_JPGLS: + JPGLS jpgls; + break; + default: + UNKNOWN unknownSection; + break; + } + ChangeColor(!bEOI); + } + if (!was_bigendian) + LittleEndian(); +} JPGFILE; + +JPGFILE jpgfile; diff --git a/cparser/LNKTemplate.bt b/cparser/LNKTemplate.bt new file mode 100644 index 0000000..33e7022 --- /dev/null +++ b/cparser/LNKTemplate.bt @@ -0,0 +1,424 @@ +//--------------------------------------------------------------------------- +/* + 010 Editor Template for LNK file format + 2010/08/11 v0.0.4 + + http://msdn.microsoft.com/en-us/library/dd871305%28PROT.10%29.aspx + + Source code put in public domain by Didier Stevens, no Copyright + https://DidierStevens.com + Use at your own risk + + History: + 2010/07/23: start development with 010 Editor v3.0.6 + 2010/07/27: continue + 2010/07/30: added CommonNetworkRelativeLink + 2010/08/11: v0.0.4 added GUID processing to IDList + + Todo: + Read functions for HotKeyFlags and NetworkProviderType + ExtraData structures for: + ConsoleDataBlock structure (section 2.5.1). + ConsoleFEDataBlock structure (section 2.5.2). + DarwinDataBlock structure (section 2.5.3). + EnvironmentVariableDataBlock structure (section 2.5.4). + IconEnvironmentDataBlock structure (section 2.5.5). + KnownFolderDataBlock structure (section 2.5.6). + PropertyStoreDataBlock structure (section 2.5.7). + ShimDataBlock structure (section 2.5.8). + SpecialFolderDataBlock structure (section 2.5.9). + VistaAndAboveIDListDataBlock structure (section 2.5.11). + +*/ +//--------------------------------------------------------------------------- + +local int iCOLOR = 0x95E8FF; + +local int iToggleColor = iCOLOR; + +void ToggleBackColor() +{ + if (iToggleColor == iCOLOR) + iToggleColor = cNone; + else + iToggleColor = iCOLOR; + SetBackColor(iToggleColor); +} + +typedef struct +{ + int HasLinkTargetIDList : 1; + int HasLinkInfo : 1; + int HasName : 1; + int HasRelativePath : 1; + int HasWorkingDir : 1; + int HasArguments : 1; + int HasIconLocation : 1; + int IsUnicode : 1; + int ForceNoLinkInfo : 1; + int HasExpString : 1; + int RunInSeparateProcess : 1; + int Unused1 : 1; + int HasDarwinID : 1; + int RunAsUser : 1; + int HasExpIcon : 1; + int NoPidlAlias : 1; + int Unused2 : 1; + int RunWithShimLayer : 1; + int ForceNoLinkTrack : 1; + int EnableTargetMetadata : 1; + int DisableLinkPathTracking : 1; + int DisableKnownFolderTracking : 1; + int DisableKnownFolderAlias : 1; + int AllowLinkToLink : 1; + int UnaliasOnSave : 1; + int PreferEnvironmentPath : 1; + int KeepLocalIDListForUNCTarget : 1; + int Unused3 : 5; +} LinkFlags; + +typedef struct +{ + int FILE_ATTRIBUTE_READONLY : 1; + int FILE_ATTRIBUTE_HIDDEN : 1; + int FILE_ATTRIBUTE_SYSTEM : 1; + int Reserved1 : 1; + int FILE_ATTRIBUTE_DIRECTORY : 1; + int FILE_ATTRIBUTE_ARCHIVE : 1; + int FILE_ATTRIBUTE_NORMAL : 1; + int FILE_ATTRIBUTE_TEMPORARY : 1; + int FILE_ATTRIBUTE_SPARSE_FILE : 1; + int FILE_ATTRIBUTE_REPARSE_POINT : 1; + int FILE_ATTRIBUTE_COMPRESSED : 1; + int FILE_ATTRIBUTE_OFFLINE : 1; + int FILE_ATTRIBUTE_NOT_CONTENT_INDEXED : 1; + int FILE_ATTRIBUTE_ENCRYPTED : 1; + int Unused1 : 18; +} FileAttributes; + +typedef struct +{ + DWORD HeaderSize ; /* Must be 0x0000004C */ + BYTE LinkCLSID[16]; /* This value MUST be 00021401-0000-0000-C000-000000000046. */ + LinkFlags sLinkFlags; + FileAttributes sFileAttributes; + FILETIME CreationTime; + FILETIME AccessTime; + FILETIME WriteTime; + DWORD FileSize; + DWORD IconIndex; + DWORD ShowCommand ; + WORD HotKey; + WORD Reserved1; + DWORD Reserved2; + DWORD Reserved3; +} ShellLinkHeader; + +string ReadCheckHeaderSize(DWORD data) +{ + string result; + + switch (data) + { + case 0x0000004C: + result = "76"; + break; + + default: + SPrintf(result, "Unexpected headersize: 0x%08X", data); + } + + return result; +} + +string ReadShowCommand(DWORD function) +{ + string result; + + switch (function) + { + case 0x00000001: + result = "SW_SHOWNORMAL"; + break; + + case 0x00000003: + result = "SW_SHOWMAXIMIZED"; + break; + + case 0x00000007: + result = "SW_SHOWMINNOACTIVE"; + break; + + default: + SPrintf(result, "0x%08X", function); + } + + return result; +} + +// http://msdn.microsoft.com/en-us/library/cc144089%28VS.85%29.aspx#unknown_74413 +typedef struct +{ + WORD ItemIDSize; + if (ItemIDSize == 0x14) + { + BYTE Type; + BYTE Unknown; + BYTE GUID[ItemIDSize - 4]; + } + else + BYTE Data[ItemIDSize - 2]; +} IDList ; + +string ReadIDList(IDList &sIDList) +{ + string sGUID; + + if (sIDList.ItemIDSize == 0x14) + { + SPrintf(sGUID, "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", sIDList.GUID[3], sIDList.GUID[2], sIDList.GUID[1], sIDList.GUID[0], sIDList.GUID[5], sIDList.GUID[4], sIDList.GUID[7], sIDList.GUID[6], sIDList.GUID[8], sIDList.GUID[9], sIDList.GUID[10], sIDList.GUID[11], sIDList.GUID[12], sIDList.GUID[13], sIDList.GUID[14], sIDList.GUID[15]); + return LookupGUID(sGUID); + } + else + return ""; +} + +// GUIDs found in shlguid.h +string LookupGUID(string sGUID) +{ + if (!Stricmp(sGUID, "{208D2C60-3AEA-1069-A2D7-08002B30309D}")) + return "CLSID_NetworkPlaces"; + else if (!Stricmp(sGUID, "{46e06680-4bf0-11d1-83ee-00a0c90dc849}")) + return "CLSID_NetworkDomain"; + else if (!Stricmp(sGUID, "{c0542a90-4bf0-11d1-83ee-00a0c90dc849}")) + return "CLSID_NetworkServer"; + else if (!Stricmp(sGUID, "{54a754c0-4bf1-11d1-83ee-00a0c90dc849}")) + return "CLSID_NetworkShare"; + else if (!Stricmp(sGUID, "{20D04FE0-3AEA-1069-A2D8-08002B30309D}")) + return "CLSID_MyComputer"; + else if (!Stricmp(sGUID, "{871C5380-42A0-1069-A2EA-08002B30309D}")) + return "CLSID_Internet"; + else if (!Stricmp(sGUID, "{F3364BA0-65B9-11CE-A9BA-00AA004AE837}")) + return "CLSID_ShellFSFolder"; + else if (!Stricmp(sGUID, "{645FF040-5081-101B-9F08-00AA002F954E}")) + return "CLSID_RecycleBin"; + else if (!Stricmp(sGUID, "{21EC2020-3AEA-1069-A2DD-08002B30309D}")) + return "CLSID_ControlPanel"; + else if (!Stricmp(sGUID, "{450D8FBA-AD25-11D0-98A8-0800361B1103}")) + return "CLSID_MyDocuments"; + else + return sGUID; +} + +typedef struct +{ + WORD IDListSize; + + while(ReadUShort(FTell()) != 0x0000) + { + IDList sIDList; + } + WORD TerminalID; +} LinkTargetIDList; + +typedef struct +{ + int VolumeIDAndLocalBasePath : 1; + int CommonNetworkRelativeLinkAndPathSuffix : 1; + int Unused1 : 30; +} LinkInfoFlags; + +typedef struct +{ + DWORD VolumeIDSize; + DWORD DriveType ;; + DWORD DriveSerialNumber; + DWORD VolumeLabelOffset; + if (VolumeLabelOffset == 0x00000014) + { + DWORD VolumeLabelOffsetUnicode; + } + string Data; +} VolumeID; + +typedef struct +{ + DWORD CommonNetworkRelativeLinkSize; + DWORD CommonNetworkRelativeLinkFlags; + DWORD NetNameOffset; + DWORD DeviceNameOffset; + DWORD NetworkProviderType; + if (NetNameOffset > 0x14) + { + DWORD NetNameOffsetUnicode; + DWORD DeviceNameOffsetUnicode; + } + string NetName; + string DeviceName; + if (NetNameOffset > 0x14) + { + string NetNameUnicode; // Must be UNICODE + string DeviceNameUnicode; // Must be UNICODE + } +} CommonNetworkRelativeLink; + +string ReadDriveType(DWORD function) +{ + string result; + + switch (function) + { + case 0x00000000: + result = "DRIVE_UNKNOWN"; + break; + + case 0x00000001: + result = "DRIVE_NO_ROOT_DIR"; + break; + + case 0x00000002: + result = "DRIVE_REMOVABLE"; + break; + + case 0x00000003: + result = "DRIVE_FIXED"; + break; + + case 0x00000004: + result = "DRIVE_REMOTE"; + break; + + case 0x00000005: + result = "DRIVE_CDROM"; + break; + + case 0x00000006: + result = "DRIVE_RAMDISK"; + break; + + default: + SPrintf(result, "0x%08X", function); + } + + return result; +} + +typedef struct +{ + DWORD LinkInfoSize; + DWORD LinkInfoHeaderSize; + LinkInfoFlags sLinkInfoFlags; + DWORD VolumeIDOffset; + DWORD LocalBasePathOffset; + DWORD CommonNetworkRelativeLinkOffset; + DWORD CommonPathSuffixOffset; + if (LinkInfoHeaderSize >= 0x00000024 ) + { + DWORD LocalBasePathOffsetUnicode; + DWORD CommonPathSuffixOffsetUnicode; + } + if (sLinkInfoFlags.VolumeIDAndLocalBasePath == 1) + { + VolumeID sVolumeID; + string LocalBasePath; + string CommonPathSuffix; + } + if (sLinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix == 1) + { + CommonNetworkRelativeLink sCommonNetworkRelativeLink; + } +} LinkInfo; + +typedef struct +{ + WORD CountCharacters; + BYTE String[CountCharacters * 2]; +} StringData; + +typedef struct +{ + DWORD BlockSize; + DWORD BlockSignature; + BYTE BlockData[BlockSize - 8]; +} ExtraDataBlock; + +typedef struct +{ + DWORD BlockSize; + DWORD BlockSignature; + DWORD Length; + DWORD Version; + BYTE MachineID[16]; + BYTE Droid[32]; + BYTE DroidBirth[32]; +} TrackerDataBlock; + +typedef struct +{ + while(ReadUInt(FTell()) >= 0x00000004) + { + switch (ReadUInt(FTell() + 4)) + { + case 0xA0000003: + TrackerDataBlock sTrackerDataBlock; + break; + + default: + ExtraDataBlock sExtraDataBlock; + } + } + DWORD TerminalBlock; +} ExtraData; + +// Start +LittleEndian(); + +SetBackColor(iToggleColor); +ShellLinkHeader sShellLinkHeader; + +if (sShellLinkHeader.sLinkFlags.HasLinkTargetIDList == 1) +{ + ToggleBackColor(); + LinkTargetIDList sLinkTargetIDList; +} + +if (sShellLinkHeader.sLinkFlags.HasLinkInfo == 1) +{ + ToggleBackColor(); + LinkInfo sLinkInfo; +} + +if (sShellLinkHeader.sLinkFlags.HasName == 1) +{ + ToggleBackColor(); + StringData NAME_STRING; +} + +if (sShellLinkHeader.sLinkFlags.HasRelativePath == 1) +{ + ToggleBackColor(); + StringData RELATIVE_PATH; +} + +if (sShellLinkHeader.sLinkFlags.HasWorkingDir == 1) +{ + ToggleBackColor(); + StringData WORKING_DIR; +} + +if (sShellLinkHeader.sLinkFlags.HasArguments == 1) +{ + ToggleBackColor(); + StringData COMMAND_LINE_ARGUMENTS; +} + +if (sShellLinkHeader.sLinkFlags.HasIconLocation == 1) +{ + ToggleBackColor(); + StringData ICON_LOCATION; +} + +ToggleBackColor(); +ExtraData sExtraData; + +SetBackColor(cNone); diff --git a/cparser/LUKSTemplate.bt b/cparser/LUKSTemplate.bt new file mode 100644 index 0000000..127cffa --- /dev/null +++ b/cparser/LUKSTemplate.bt @@ -0,0 +1,75 @@ +//-------------------------------------- +//--- 010 Editor v4.0.1 Binary Template +// +// File: LUKS.bt +// Author: Daniel Correa +// URL: http://www.sinfocol.org/ +// Revision: 1.0 +// Purpose: Template for LUKS +//-------------------------------------- + +#define LUKS_CIPHERNAME_L 32 +#define LUKS_CIPHERMODE_L 32 +#define LUKS_HASHSPEC_L 32 +#define LUKS_DIGESTSIZE 20 +#define LUKS_HMACSIZE 32 +#define LUKS_SALTSIZE 32 +#define LUKS_NUMKEYS 8 + +#define LUKS_MKD_ITERATIONS_MIN 1000 +#define LUKS_SLOT_ITERATIONS_MIN 1000 + +#define LUKS_KEY_DISABLED_OLD 0 +#define LUKS_KEY_ENABLED_OLD 0xCAFE + +#define LUKS_KEY_DISABLED 0x0000DEAD +#define LUKS_KEY_ENABLED 0x00AC71F3 + +#define LUKS_STRIPES 4000 + +#define LUKS_MAGIC "LUKS\xBA\xBE" +#define LUKS_MAGIC_L 6 + +#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1) + +#define UUID_STRING_L 40 + +#define LUKS_ALIGN_KEYSLOTS 4096 + + +typedef struct luks_phdr { + char magic[LUKS_MAGIC_L] ; + + if (magic != LUKS_MAGIC) { + SetBackColor(0x0000ff); + Warning("File is not a LUKS disk. Bad signature."); + return -1; + } + + uint16 version ; + char cipherName[LUKS_CIPHERNAME_L] ; + char cipherMode[LUKS_CIPHERMODE_L] ; + char hashSpec[LUKS_HASHSPEC_L] ; + uint32 payloadOffset ; + uint32 keyBytes ; + char mkDigest[LUKS_DIGESTSIZE] ; + char mkDigestSalt[LUKS_SALTSIZE] ; + uint32 mkDigestIterations ; + char uuid[UUID_STRING_L] ; + + struct { + uint32 active ; + + uint32 passwordIterations ; + char passwordSalt[LUKS_SALTSIZE] ; + + uint32 keyMaterialOffset ; + uint32 stripes ; + } keyblock[LUKS_NUMKEYS]; + + char _padding[432]; +}; + +FSeek(0); +BigEndian(); +luks_phdr LUKS; \ No newline at end of file diff --git a/cparser/MBRTemplate.bt b/cparser/MBRTemplate.bt new file mode 100644 index 0000000..87532e0 --- /dev/null +++ b/cparser/MBRTemplate.bt @@ -0,0 +1,460 @@ +//------------------------------------ +//--- 010 Editor v2.01 Binary Template +// +// Name: MBRTemplate.bt +// Author: Christian Schaffalitzky +// Revision: 1.3 +// Purpose: Parse a Master Boot Record on a Harddisk +// Changes: +// 1.3 (insomniac@slackware.it) +// - Added partition ID and type comments +// 1.2 (A.Babecki): +// - Added BitfieldDisablePadding +// - Added unsigned for relsect/numsect +// +//------------------------------------ + +BitfieldRightToLeft(); +BitfieldDisablePadding(); + +string BootID(unsigned char boot_id) { + string ret; + + if (boot_id & 0x80) + Strcat(ret, "Bootable"); + else + Strcat(ret, "Not bootable"); + + return ret; +} + +/* Generated with partlist */ +/* Original data source: http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */ +string PartitionID(unsigned char ptype) { + switch (ptype) { + case 0: + return "Empty"; + case 1: + return "DOS 12-bit FAT"; + case 2: + return "XENIX root"; + case 3: + return "XENIX /usr"; + case 4: + return "DOS 3.0+ 16-bit FAT (up to 32M)"; + case 5: + return "DOS 3.3+ Extended Partition"; + case 6: + return "DOS 3.31+ 16-bit FAT (over 32M)"; + case 7: + return "OS/2 IFS (e.g., HPFS), Windows NT NTFS, exFAT, Advanced Unix, QNX2.x pre-1988 (see below under IDs 4d-4f)"; + case 8: + return "OS/2 (v1.0-1.3 only), AIX boot partition, SplitDrive, Commodore DOS, DELL partition spanning multiple drives, QNX 1.x and 2.x (\"qny\")"; + case 9: + return "AIX data partition, Coherent filesystem, QNX 1.x and 2.x (\"qnz\")"; + case 10: + return "OS/2 Boot Manager, Coherent swap partition, OPUS"; + case 11: + return "WIN95 OSR2 FAT32"; + case 12: + return "WIN95 OSR2 FAT32, LBA-mapped"; + case 13: + return "SILICON SAFE"; + case 14: + return "WIN95: DOS 16-bit FAT, LBA-mapped"; + case 15: + return "WIN95: Extended partition, LBA-mapped"; + case 16: + return "OPUS (?)"; + case 17: + return "Hidden DOS 12-bit FAT"; + case 18: + return "Configuration/diagnostics partition"; + case 20: + return "Hidden DOS 16-bit FAT <32M"; + case 22: + return "Hidden DOS 16-bit FAT >=32M"; + case 23: + return "Hidden IFS (e.g., HPFS)"; + case 24: + return "AST SmartSleep Partition"; + case 25: + return "Unused"; + case 27: + return "Hidden WIN95 OSR2 FAT32"; + case 28: + return "Hidden WIN95 OSR2 FAT32, LBA-mapped"; + case 30: + return "Hidden WIN95 16-bit FAT, LBA-mapped"; + case 32: + return "Unused"; + case 33: + return "Reserved, Unused"; + case 34: + return "Unused"; + case 35: + return "Reserved"; + case 36: + return "NEC DOS 3.x"; + case 38: + return "Reserved"; + case 39: + return "PQservice, Windows RE hidden partition, MirOS partition, RouterBOOT kernel partition"; + case 42: + return "AtheOS File System (AFS)"; + case 49: + return "Reserved"; + case 50: + return "NOS"; + case 51: + return "Reserved"; + case 52: + return "Reserved"; + case 53: + return "JFS on OS/2 or eCS "; + case 54: + return "Reserved"; + case 56: + return "THEOS ver 3.2 2gb partition"; + case 57: + return "Plan 9 partition, THEOS ver 4 spanned partition"; + case 58: + return "THEOS ver 4 4gb partition"; + case 59: + return "THEOS ver 4 extended partition"; + case 60: + return "PartitionMagic recovery partition"; + case 61: + return "Hidden NetWare"; + case 64: + return "Venix 80286, PICK"; + case 65: + return "Linux/MINIX (sharing disk with DRDOS), Personal RISC Boot, PPC PReP (Power PC Reference Platform) Boot"; + case 66: + return "Linux swap (sharing disk with DRDOS), SFS (Secure Filesystem), Windows 2000 dynamic extended partition marker"; + case 67: + return "Linux native (sharing disk with DRDOS)"; + case 68: + return "GoBack partition"; + case 69: + return "Boot-US boot manager, Priam, EUMEL/Elan "; + case 70: + return "EUMEL/Elan "; + case 71: + return "EUMEL/Elan "; + case 72: + return "EUMEL/Elan "; + case 74: + return "Mark Aitchison\'s ALFS/THIN lightweight filesystem for DOS, AdaOS Aquila (Withdrawn)"; + case 76: + return "Oberon partition"; + case 77: + return "QNX4.x"; + case 78: + return "QNX4.x 2nd part"; + case 79: + return "QNX4.x 3rd part, Oberon partition"; + case 80: + return "OnTrack Disk Manager (older versions) RO, Lynx RTOS, Native Oberon (alt)"; + case 81: + return "OnTrack Disk Manager RW (DM6 Aux1), Novell"; + case 82: + return "CP/M, Microport SysV/AT"; + case 83: + return "Disk Manager 6.0 Aux3"; + case 84: + return "Disk Manager 6.0 Dynamic Drive Overlay (DDO)"; + case 85: + return "EZ-Drive"; + case 86: + return "Golden Bow VFeature Partitioned Volume., DM converted to EZ-BIOS"; + case 87: + return "DrivePro, VNDI Partition"; + case 92: + return "Priam EDisk"; + case 97: + return "SpeedStor"; + case 99: + return "Unix System V (SCO, ISC Unix, UnixWare, ...), Mach, GNU Hurd"; + case 100: + return "PC-ARMOUR protected partition, Novell Netware 286, 2.xx"; + case 101: + return "Novell Netware 386, 3.xx or 4.xx"; + case 102: + return "Novell Netware SMS Partition"; + case 103: + return "Novell"; + case 104: + return "Novell"; + case 105: + return "Novell Netware 5+, Novell Netware NSS Partition"; + case 110: + return "??"; + case 112: + return "DiskSecure Multi-Boot"; + case 113: + return "Reserved"; + case 114: + return "V7/x86"; + case 115: + return "Reserved"; + case 116: + return "Reserved, Scramdisk partition"; + case 117: + return "IBM PC/IX"; + case 118: + return "Reserved"; + case 119: + return "M2FS/M2CS partition, VNDI Partition"; + case 120: + return "XOSL FS"; + case 126: + return "Unused"; + case 127: + return "Unused"; + case 128: + return "MINIX until 1.4a"; + case 129: + return "MINIX since 1.4b, early Linux, Mitac disk manager"; + case 130: + return "Prime, Solaris x86, Linux swap"; + case 131: + return "Linux native partition"; + case 132: + return "OS/2 hidden C: drive, Hibernation partition"; + case 133: + return "Linux extended partition"; + case 134: + return "Old Linux RAID partition superblock, FAT16 volume set"; + case 135: + return "NTFS volume set"; + case 136: + return "Linux plaintext partition table"; + case 138: + return "Linux Kernel Partition (used by AiR-BOOT)"; + case 139: + return "Legacy Fault Tolerant FAT32 volume"; + case 140: + return "Legacy Fault Tolerant FAT32 volume using BIOS extd INT 13h"; + case 141: + return "Free FDISK 0.96+ hidden Primary DOS FAT12 partitition"; + case 142: + return "Linux Logical Volume Manager partition"; + case 144: + return "Free FDISK 0.96+ hidden Primary DOS FAT16 partitition"; + case 145: + return "Free FDISK 0.96+ hidden DOS extended partitition"; + case 146: + return "Free FDISK 0.96+ hidden Primary DOS large FAT16 partitition"; + case 147: + return "Hidden Linux native partition, Amoeba"; + case 148: + return "Amoeba bad block table"; + case 149: + return "MIT EXOPC native partitions"; + case 150: + return "CHRP ISO-9660 filesystem"; + case 151: + return "Free FDISK 0.96+ hidden Primary DOS FAT32 partitition"; + case 152: + return "Free FDISK 0.96+ hidden Primary DOS FAT32 partitition (LBA), Datalight ROM-DOS Super-Boot Partition"; + case 153: + return "DCE376 logical drive"; + case 154: + return "Free FDISK 0.96+ hidden Primary DOS FAT16 partitition (LBA)"; + case 155: + return "Free FDISK 0.96+ hidden DOS extended partitition (LBA)"; + case 158: + return "ForthOS partition"; + case 159: + return "BSD/OS"; + case 160: + return "Laptop hibernation partition"; + case 161: + return "Laptop hibernation partition, HP Volume Expansion (SpeedStor variant)"; + case 163: + return "HP Volume Expansion (SpeedStor variant)"; + case 164: + return "HP Volume Expansion (SpeedStor variant)"; + case 165: + return "BSD/386, 386BSD, NetBSD, FreeBSD"; + case 166: + return "OpenBSD, HP Volume Expansion (SpeedStor variant)"; + case 167: + return "NeXTStep"; + case 168: + return "Mac OS-X"; + case 169: + return "NetBSD"; + case 170: + return "Olivetti Fat 12 1.44MB Service Partition"; + case 171: + return "Mac OS-X Boot partition, GO! partition"; + case 173: + return "RISC OS ADFS"; + case 174: + return "ShagOS filesystem"; + case 175: + return "ShagOS swap partition, MacOS X HFS"; + case 176: + return "BootStar Dummy"; + case 177: + return "HP Volume Expansion (SpeedStor variant), QNX Neutrino Power-Safe filesystem"; + case 178: + return "QNX Neutrino Power-Safe filesystem"; + case 179: + return "HP Volume Expansion (SpeedStor variant), QNX Neutrino Power-Safe filesystem"; + case 180: + return "HP Volume Expansion (SpeedStor variant)"; + case 182: + return "HP Volume Expansion (SpeedStor variant), Corrupted Windows NT mirror set (master), FAT16 file system"; + case 183: + return "Corrupted Windows NT mirror set (master), NTFS file system, BSDI BSD/386 filesystem"; + case 184: + return "BSDI BSD/386 swap partition"; + case 187: + return "Boot Wizard hidden"; + case 188: + return "Acronis backup partition"; + case 189: + return "BonnyDOS/286"; + case 190: + return "Solaris 8 boot partition"; + case 191: + return "New Solaris x86 partition"; + case 192: + return "CTOS, REAL/32 secure small partition, NTFT Partition, DR-DOS/Novell DOS secured partition"; + case 193: + return "DRDOS/secured (FAT-12)"; + case 194: + return "Unused, Hidden Linux"; + case 195: + return "Hidden Linux swap"; + case 196: + return "DRDOS/secured (FAT-16, < 32M)"; + case 197: + return "DRDOS/secured (extended)"; + case 198: + return "DRDOS/secured (FAT-16, >= 32M), Windows NT corrupted FAT16 volume/stripe set"; + case 199: + return "Windows NT corrupted NTFS volume/stripe set, Syrinx boot"; + case 200: + return "Reserved for DR-DOS 8.0+"; + case 201: + return "Reserved for DR-DOS 8.0+"; + case 202: + return "Reserved for DR-DOS 8.0+"; + case 203: + return "DR-DOS 7.04+ secured FAT32 (CHS)/"; + case 204: + return "DR-DOS 7.04+ secured FAT32 (LBA)/"; + case 205: + return "CTOS Memdump? "; + case 206: + return "DR-DOS 7.04+ FAT16X (LBA)/"; + case 207: + return "DR-DOS 7.04+ secured EXT DOS (LBA)/"; + case 208: + return "REAL/32 secure big partition, Multiuser DOS secured partition"; + case 209: + return "Old Multiuser DOS secured FAT12"; + case 212: + return "Old Multiuser DOS secured FAT16 <32M"; + case 213: + return "Old Multiuser DOS secured extended partition"; + case 214: + return "Old Multiuser DOS secured FAT16 >=32M"; + case 216: + return "CP/M-86"; + case 218: + return "Non-FS Data, Powercopy Backup"; + case 219: + return "Digital Research CP/M, Concurrent CP/M, Concurrent DOS, CTOS (Convergent Technologies OS -Unisys), KDG Telemetry SCPU boot"; + case 221: + return "Hidden CTOS Memdump? "; + case 222: + return "Dell PowerEdge Server utilities (FAT fs)"; + case 223: + return "DG/UX virtual disk manager partition, BootIt EMBRM"; + case 225: + return "DOS access or SpeedStor 12-bit FAT extended partition"; + case 227: + return "DOS R/O or SpeedStor"; + case 228: + return "SpeedStor 16-bit FAT extended partition < 1024 cyl."; + case 230: + return "Storage Dimensions SpeedStor"; + case 232: + return "LUKS"; + case 234: + return "Rufus extra partition, Freedesktop boot"; + case 235: + return "BeOS BFS"; + case 236: + return "SkyOS SkyFS"; + case 237: + return "Unused"; + case 238: + return "Indication that this legacy MBR is followed by an EFI header"; + case 239: + return "Partition that contains an EFI file system"; + case 240: + return "Linux/PA-RISC boot loader"; + case 241: + return "Storage Dimensions SpeedStor"; + case 242: + return "DOS 3.3+ secondary partition"; + case 243: + return "Reserved"; + case 244: + return "SpeedStor large partition, Prologue single-volume partition"; + case 245: + return "Prologue multi-volume partition"; + case 246: + return "Storage Dimensions SpeedStor"; + case 247: + return "DDRdrive Solid State File System"; + case 249: + return "pCache"; + case 250: + return "Bochs"; + case 251: + return "VMware File System partition"; + case 252: + return "VMware Swap partition"; + case 253: + return "Linux raid partition with autodetect using persistent superblock"; + case 254: + return "SpeedStor > 1024 cyl., LANstep, Windows NT Disk Administrator hidden partition, Linux Logical Volume Manager partition (old)"; + case 255: + return "Xenix Bad Block Table"; + default: + return "Unknown partition type"; + } +} + + +typedef struct fdisk_partition { + unsigned char bootid ; /* bootable? 0=no, 128=yes */ + unsigned short beghead : 8; /* beginning head number */ + unsigned short begsect : 6; /* beginning sector number */ + unsigned short begcyl : 10; /* 10 bit nmbr */ + unsigned char systid ; /* Operating System type indicator code */ + unsigned short endhead : 8; /* ending head number */ + unsigned short endsect : 6; /* ending sector number */ + unsigned short endcyl : 10; /* also a 10 bit nmbr */ + unsigned int relsect; /* first sector relative to start of disk */ + unsigned int numsect; /* number of sectors in partition */ +}; + + +typedef struct master_boot_record { + char bootinst[446]; /* space to hold actual boot code */ + fdisk_partition partitions[4]; + ushort signature; /* set to 0xAA55 to indicate PC MBR format */ +}; + +LittleEndian(); + +FSeek(0); +master_boot_record MBR; diff --git a/cparser/MBRTemplateFAT.bt b/cparser/MBRTemplateFAT.bt new file mode 100644 index 0000000..8856709 --- /dev/null +++ b/cparser/MBRTemplateFAT.bt @@ -0,0 +1,887 @@ +//---------------------------------------- +//--- 010 Editor v4.0 Binary Template +// +// File: MBR_FAT16_FAT32_NTFS.bt +// Author: Benjamin Vernoux (bvernoux@gmail.com) +// Revision: 0.1 Beta 14 January 2013 +// Purpose: Defines a template for +// FAT16 or FAT32 drive with support of MBR +//---------------------------------------- +LittleEndian(); + +typedef char BOOL; +typedef char BYTE; +typedef unsigned char UBYTE; +typedef short SHORT; +typedef unsigned short USHORT; +typedef long LONG; +typedef unsigned long ULONG; + +// Global Shared Variable +local quad DataAreaSector; +local quad DataAreaFilePos; + +local quad CurrentPosSector; + +local unsigned char SizeOfEach_ClusterEntry_InBytes; + +//############################## +// MBR +//############################## +// Partition Types +typedef enum tagSYSTEMID +{ + EMPTY = 0, + FAT_12 = 1, + XENIX_ROOT = 2, + XENIX_USR = 3, + FAT_16_INF32MB = 4, + EXTENDED = 5, + FAT_16 = 6, + NTFS_HPFS = 7, + AIX = 8, + AIX_BOOT = 9, + OS2_BOOT_MGR = 10, + PRI_FAT32_INT13 = 11, + EXT_FAT32_INT13 = 12, + EXT_FAT16_INT13 = 14, + WIN95_EXT = 15, + OPUS = 16, + FAT_12_HIDDEN = 17, + COMPAQ_DIAG = 18, + FAT_16_HIDDEN_INF32MB = 20, + FAT_16_HIDDEN = 22, + NTFS_HPFS_HIDDEN = 23, + VENIX = 64, + NOVEL0 = 81, + MICROPORT = 82, + GNU_HURD = 99, + NOVEL1 = 100, + PC_IX = 117, + MINUX_OLD = 128, + MINUX_LINUX = 129, + LINUX_SWAP = 130, + LINUX_NATIVE = 131, + AMOEBA = 147, + AMOEBA_BBT = 148, + BSD_386 = 165, + BSDI_FS = 183, + BSDI_SWAP = 184, + SYRINX = 199, + CP_M = 219, + ACCESS_DOS = 225, + DOS_R_O = 227, + DOS_SECONDARY = 242, + BBT = 255 +} SYSTEMID; + +// Boot Indicator Values +typedef enum tagBOOTINDICATOR +{ + NOBOOT = 0, + SYSTEM_PARTITION = 128, +} BOOTINDICATOR; + +// Partition Entry +typedef struct PART_ENTRY +{ + BOOTINDICATOR BootIndicator; + UBYTE StartingHead; + WORD StartingSectCylinder; // Need Bit fields + SYSTEMID SystemID; + UBYTE EndingHead; + WORD EndingSectCylinder; // Need Bit fields + DWORD RelativeSector; + DWORD TotalSectors; +} PART_ENTRY; + +// MBR +struct MASTER_BOOT_RECORD +{ + UBYTE BootCode[446]; + PART_ENTRY partitions[4]; + WORD EndOfSectorMarker ; +}; + +//############################## +// FAT16 Boot Sector +//############################## +struct BOOTSECTOR_FAT16 +{ + UBYTE jmp[3]; + CHAR OemName[8]; + + typedef struct BPB_FAT16 + { + USHORT BytesPerSector; + UBYTE SectorsPerCluster; + USHORT ReservedSectors; + UBYTE NumberOfCopiesOfFats; + USHORT MaxRootDirEntries; + USHORT NumberOfSectors; + UBYTE MediaDescriptor; + USHORT SectorsPerFAT; + USHORT SectorsPerTrack; + USHORT NumHeadsPerCylinder; + ULONG NumHiddenSectors; + ULONG NumSectorInPartition; + }; + BPB_FAT16 bpb_fat16; + USHORT LogicDriveNumber; + UBYTE extBootSignature ; + ULONG SerialNumber; + CHAR VolumeLabel[11]; + CHAR FileSystem[8]; + UBYTE ExecutableCode[448]; + WORD EndOfSectorMarker ; +}; + +//############################## +// FAT16 FAT Table +//############################## +typedef enum tagMEDIATYPE +{ + HARD_DISK = 0xfff8, + FLOPPY_DISK = 0xfff0 +} MEDIATYPE; + +typedef enum tagPARTITIONSTATE +{ + PARTITION_NOT_IN_USE = 0xffff, + PARTITION_IN_USE = 0xfff7 +} PARTITIONSTATE; + +typedef enum tagCLUSTERINFO +{ + FREE_CLUSTER = 0x0000, + RESERVED_0001 = 0x0001, + RESERVED_FFF0 = 0xFFF0, + RESERVED_FFF1 = 0xFFF1, + RESERVED_FFF2 = 0xFFF2, + RESERVED_FFF3 = 0xFFF3, + RESERVED_FFF4 = 0xFFF4, + RESERVED_FFF5 = 0xFFF5, + RESERVED_FFF6 = 0xFFF6, + BAD_CLUSTER = 0xFFF7, + USED_LAST_CLUSTER_FFF8 = 0xFFF8, + USED_LAST_CLUSTER_FFF9 = 0xFFF9, + USED_LAST_CLUSTER_FFFA = 0xFFFA, + USED_LAST_CLUSTER_FFFB = 0xFFFB, + USED_LAST_CLUSTER_FFFC = 0xFFFC, + USED_LAST_CLUSTER_FFFD = 0xFFFD, + USED_LAST_CLUSTER_FFFE = 0xFFFE, + USED_LAST_CLUSTER_FFFF = 0xFFFF +} CLUSTERINFO; + +void FAT16_FAT_Table(quad FilePosStartFatTable,quad SizeOfFatTableInSectors, UBYTE NumberOfCopiesOfFats) +{ + SizeOfEach_ClusterEntry_InBytes=2; + + FSeek(FilePosStartFatTable); + + if(NumberOfCopiesOfFats==1) + { + MEDIATYPE FAT16_MediaType; + PARTITIONSTATE FAT16_PartitionState; + CLUSTERINFO FAT16_Cluster[ (((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes) ]; + }else if(NumberOfCopiesOfFats==2) + { + + MEDIATYPE FAT16_MediaType_FAT1; + PARTITIONSTATE FAT16_PartitionState_FAT1; + CLUSTERINFO FAT16_Cluster_FAT1[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-1 ]; + + MEDIATYPE FAT16_MediaType_FAT2; + PARTITIONSTATE FAT16_PartitionState_FAT2; + CLUSTERINFO FAT16_Cluster_FAT2[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-1 ]; + } +} + +//############################## +// FAT16 Directory Entry +//############################## + +typedef enum tagAttribute +{ + NoneOrFile = 0, + ReadOnly = 1, // bit0 + Hidden = 2, // bit1 + ReadOnlyHidden = 3, + System = 4, // bit2 + ReadOnlySystem = 5, + HiddenSystem0 = 6, + ReadOnlyHiddenSystem= 7, + VolumeID = 8, // bit3 + ReadOnlyVolume = 9, + HiddenSystem1 = 10, + ReadOnlySystemVolume0 = 11, + SystemVolume = 12, + ReadOnlySystemVolume1 = 13, + HiddenSystemVolume = 14, + LFN_Entry = 15, + Directory = 16, // bit4 + Archive = 32, // bit5 + ArchiveReadOnly = 33, + ArchiveHidden = 34 +}ATTR; + +typedef struct tagTime +{ + USHORT Sec : 5; // bit0-4 need to be multiplied by 2 + USHORT Min : 6; // bit5-10 + USHORT Hour : 5; // bit11-15 +}tTIME; + +typedef struct tagDate +{ + USHORT Day : 5; // bit0-4 + USHORT Month : 4; // bit5-8 + USHORT YearSince1980 : 7; // bit9-15 +}tDATE; + +typedef struct ShortEntry // Normal-Short structure +{ + CHAR Name[8]; // Blank-padded name + CHAR Extension[3]; //Blank-padded extension + ATTR Attribute; // See tagAttribute enum only 5 valid bit (from 0 to 4) + UBYTE Reserved; + UBYTE CreateTime10ms; //10-ms unit’s "Create Time" refinement + tTIME CreateTime; + tDATE CreateDate; + tDATE AccessDate; + USHORT HCluster; // Used on FAT32 only + tTIME UpdateTime; + tDATE UpdateDate; + USHORT Cluster; + ULONG FileSizeInBytes; //File size in bytes (always zero for directories). +} SHORTENTRY ; + +unsigned char FAT16_Attribute(ATTR Attribute, string &stmp) +{ + unsigned char volume=0; + + switch(Attribute) + { + case NoneOrFile: + stmp="NoneOrFile"; + break; + + case ReadOnly: + stmp="ReadOnly"; + break; + + case Hidden: + stmp="Hidden"; + break; + + case ReadOnlyHidden: + stmp="ReadOnlyHidden"; + break; + + case System: + stmp="System"; + volume=1; + break; + + case ReadOnlySystem: + stmp="ReadOnlySystem"; + volume=1; + break; + + case HiddenSystem0: + stmp="HiddenSystem0"; + volume=1; + break; + + case ReadOnlyHiddenSystem: + stmp="ReadOnlyHiddenSystem"; + volume=1; + break; + + case VolumeID: + stmp="VolumeID"; + volume=1; + break; + + case ReadOnlyVolume: + stmp="ReadOnlyVolume"; + volume=1; + break; + + case HiddenSystem1: + stmp="HiddenSystem1"; + break; + + case ReadOnlySystemVolume0: + stmp="ReadOnlySystemVolume0"; + break; + + case SystemVolume: + stmp="SystemVolume"; + volume=1; + break; + + case ReadOnlySystemVolume1: + stmp="ReadOnlySystemVolume1"; + volume=1; + break; + + case HiddenSystemVolume: + stmp="HiddenSystemVolume"; + volume=1; + break; + + case LFN_Entry: + stmp="LFN_Entry"; + break; + + case Directory: + stmp="Directory"; + volume=1; + break; + + case Archive: + stmp="Archive"; + break; + + case ArchiveReadOnly: + stmp="ArchiveReadOnly"; + break; + + case ArchiveHidden: + stmp="ArchiveHidden"; + break; + + default: + stmp="Unknown"; + volume=1; + break; + } + return volume; +} + +string Read_SHORT_DIR_ENTRY( SHORTENTRY &f ) +{ + string s; + string stmp; + unsigned char volume=0; + + s=""; + if(f.Name[0]==0) + { + return "Last Dir Entry Empty"; + } + + // Short Entry + volume=FAT16_Attribute(f.Attribute, stmp); + s+=stmp; + + if(volume) + { + SPrintf(stmp, "=%08s%03s",f.Name,f.Extension); + s+=stmp; + }else + { + SPrintf(stmp, "=%08s.%03s",f.Name,f.Extension); + s+=stmp; + } + return s; +} + +typedef struct tagLFN_RecordSeqNum +{ + UBYTE LFN_RecSeqNum : 6; // bit0-5 LFN sequence number (1..63) + UBYTE Last_LFN_record : 1; // bit6 Last LFN record in the sequence + UBYTE LFN_Erased : 1; // bit7 LFN record is an erased long name entry or maybe if it is part of an erased long name? +}tLFN_RecordSeqNum; + +local string sconv; +local unsigned short iconv; +string Conv_UnicodeToASCII(char data[], unsigned short totalsize_inbyte) +{ + sconv=""; + for(iconv=0;iconv; + +string Read_LONG_DIR_ENTRY( LONGENTRY &f ) +{ + local unsigned short i; + local unsigned short NumberOfLFNEntry; + local string str; + + str=""; + + if(f.long_entry[0].LFN.LFN_RecordSeqNum.LFN_Erased==1) + { + // Entry deleted + str+="Erased name:"; + // Count number of erased entry + for(i=0;i<63;i++) + { + if(exists(f.long_entry[i].LFN.char0)) + { + if(f.long_entry[i].LFN.char0!=0xE5) + { + break; + } + }else + { + break; + } + } + NumberOfLFNEntry=i-1; + }else + { + // Long Entry + str+="Name:"; + NumberOfLFNEntry=f.long_entry[0].LFN.LFN_RecordSeqNum.LFN_RecSeqNum-1; + } + for(i=NumberOfLFNEntry;i>0;i--) + { + str+=Conv_UnicodeToASCII(f.long_entry[i].UnicodeChar1,10); + str+=Conv_UnicodeToASCII(f.long_entry[i].UnicodeChar2,12); + str+=Conv_UnicodeToASCII(f.long_entry[i].UnicodeChar3,4); + } + str+=Conv_UnicodeToASCII(f.long_entry[0].UnicodeChar1,10); + str+=Conv_UnicodeToASCII(f.long_entry[0].UnicodeChar2,12); + str+=Conv_UnicodeToASCII(f.long_entry[0].UnicodeChar3,4); + return str; +} + +/* +typedef union FAT16_DirEntry +{ + struct ShortEntry shortEntry; + struct LongEntry longEntry; +}; +*/ + +/* +void FAT16_DIR_ENTRYWrite( FAT16_DIR_ENTRY &f, string s ) +{ + SScanf( s, "%d-%d-%d %d:%d:%d", f[0], f[1], f[2], f[3], f[4], f[5] ); +} +*/ + +void FAT16_Directory_Entry(quad FilePosStartDirectoryEntry) +{ + FSeek(FilePosStartDirectoryEntry); + i=0; + while(1) + { + if(ReadByte(FTell()+11)==0x0f) // LFN Entry + { + LONGENTRY fat16_long_direntry; + }else + { + SHORTENTRY fat16_short_direntry; + if(fat16_short_direntry.Name[0]==0 && fat16_short_direntry.Name[1]==0) // End of Directory Entry + { + break; + } + } + } +} + +//############################## +// FAT32 Boot Sector +//############################## +struct BOOTSECTOR_FAT32 +{ + BYTE jmp[3]; + CHAR OemName[8]; + + typedef struct BPB_FAT32 + { + WORD BytesPerSector; + BYTE SectorsPerCluster; + WORD ReservedSectors; + BYTE NumberOfFATs; + WORD RootEntries; + WORD TotalSectors; + BYTE Media; + WORD SectorsPerFAT; + WORD SectorsPerTrack; + WORD HeadsPerCylinder; + DWORD HiddenSectors; + DWORD TotalSectorsBig; + DWORD SectorsPerFAT; + WORD Flags; + WORD Version; + DWORD RootCluster; + WORD InfoSector; + WORD BootBackupStart; + BYTE Reserved[12]; + }; + + BPB_FAT32 bpb_fat32; + + BYTE DriveNumber; + BYTE Unused; + BYTE ExtBootSignature ; + DWORD SerialNumber; + CHAR VolumeLabel[11]; + CHAR FileSystem[8]; + CHAR BootCode[420]; + WORD EndOfSectorMarker ; +}; + +//############################## +// FAT32 FAT Table +//############################## + +// Warning on FAT32 only 28bit contain value +// 4 high bit (MSB) are reserved for future use. +// It is why following FAT32 enum could be wrong if 4 high bit reserved are different from 0x0 or 0xf + +typedef enum tagMEDIATYPE_FAT32 +{ + HARD_DISK_FAT32 = 0x0ffffff8, + FLOPPY_DISK_FAT32 = 0x0ffffff0 +} MEDIATYPE_FAT32; + +typedef enum tagPARTITIONSTATE_FAT32 +{ + PARTITION_NOT_IN_USE_FAT32 = 0xffffffff, + PARTITION_IN_USE_FAT32 = 0xfffffff7 +} PARTITIONSTATE_FAT32; + +typedef enum tagCLUSTERINFO_FAT32 +{ + FREE_CLUSTER_FAT32 = 0x00000000, + RESERVED_0001_FAT32 = 0x00000001, + RESERVED_FFF0_FAT32 = 0x0FFFFFF0, + RESERVED_FFF1_FAT32 = 0x0FFFFFF1, + RESERVED_FFF2_FAT32 = 0x0FFFFFF2, + RESERVED_FFF3_FAT32 = 0x0FFFFFF3, + RESERVED_FFF4_FAT32 = 0x0FFFFFF4, + RESERVED_FFF5_FAT32 = 0x0FFFFFF5, + RESERVED_FFF6_FAT32 = 0x0FFFFFF6, + BAD_CLUSTER_FAT32 = 0x0FFFFFF7, + USED_LAST_CLUSTER_FFF8_FAT32 = 0x0FFFFFF8, + USED_LAST_CLUSTER_FFF9_FAT32 = 0x0FFFFFF9, + USED_LAST_CLUSTER_FFFA_FAT32 = 0x0FFFFFFA, + USED_LAST_CLUSTER_FFFB_FAT32 = 0x0FFFFFFB, + USED_LAST_CLUSTER_FFFC_FAT32 = 0x0FFFFFFC, + USED_LAST_CLUSTER_FFFD_FAT32 = 0x0FFFFFFD, + USED_LAST_CLUSTER_FFFE_FAT32 = 0x0FFFFFFE, + USED_LAST_CLUSTER_FFFF_FAT32 = 0x0FFFFFFF +} CLUSTERINFO_FAT32; + +void FAT32_FAT_Table(quad FilePosStartFatTable,quad SizeOfFatTableInSectors, UBYTE NumberOfCopiesOfFats) +{ + local unsigned char SizeOfEach_ClusterEntry_InBytes; + SizeOfEach_ClusterEntry_InBytes=4; + + FSeek(FilePosStartFatTable); + + if(NumberOfCopiesOfFats==1) + { + MEDIATYPE_FAT32 FAT32_MediaType; + PARTITIONSTATE_FAT32 FAT32_PartitionState; + CLUSTERINFO_FAT32 FAT32_Cluster[ (((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes) ]; + + }else if(NumberOfCopiesOfFats==2) + { + MEDIATYPE_FAT32 FAT32_MediaType_FAT1; + PARTITIONSTATE_FAT32 FAT32_PartitionState_FAT1; + CLUSTERINFO_FAT32 FAT32_Cluster_FAT1[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-0 ]; + + MEDIATYPE_FAT32 FAT32_MediaType_FAT2; + PARTITIONSTATE_FAT32 FAT32_PartitionState_FAT2; + CLUSTERINFO_FAT32 FAT32_Cluster_FAT2[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-0 ]; + } +} + +void FAT32_Directory_Entry(quad FilePosStartDirectoryEntry) +{ + FSeek(FilePosStartDirectoryEntry); + i=0; + while(1) + { + if(ReadByte(FTell()+11)==0x0f) // LFN Entry + { + LONGENTRY fat32_long_direntry; + }else + { + SHORTENTRY fat32_short_direntry; + if(fat32_short_direntry.Name[0]==0 && fat32_short_direntry.Name[1]==0) // End of Directory Entry + { + break; + } + } + } +} + + +//############################## +// NTFS Boot Sector +//############################## +struct BOOTSECTOR_NTFS +{ + BYTE jmp[3]; // Jump Instruction + CHAR OEMName[8]; // OEM Identifier + + typedef struct BPB_NTFS + { + WORD BytesPerSector; + BYTE SectorsPerCluster; + WORD ReservedSectors; + BYTE Zero[3]; + WORD NotUsed; + BYTE MediaDescriptor; + WORD Zero; + WORD SectorsPerTrack; + WORD HeadsPerCylinder; + DWORD HiddenSectors; + DWORD NotUsed; + DWORD NotUsed; + UQUAD TotalSectors; + UQUAD LogicalClusterMFT; + UQUAD LogicalClusterMFTMiror; + DWORD ClustersPerFileRecSegment; + DWORD ClustersPerIndexBlock; + UQUAD SerialNumber; + DWORD Checksum; + }; + + BPB_NTFS bpb_ntfs; + BYTE BootCode[426]; + WORD EndOfSectorMarker ; +}; + +typedef union boot +{ + struct MASTER_BOOT_RECORD mbr; + struct BOOTSECTOR_FAT16 boot_fat16; + struct BOOTSECTOR_FAT32 boot_fat32; + struct BOOTSECTOR_NTFS boot_ntfs; +}; + + +void FAT16CheckInit(SYSTEMID SystemID) +{ + if( SystemID==FAT_16_INF32MB || + SystemID==FAT_16 || + SystemID==EXT_FAT16_INT13 + ) + { + CurrentPosSector=FTell()/512; + + BOOTSECTOR_FAT16 detected_fat16; + + FATTableSector=CurrentPosSector+detected_fat16.bpb_fat16.ReservedSectors; + + RootDirEntrySector=CurrentPosSector+detected_fat16.bpb_fat16.ReservedSectors+ + (detected_fat16.bpb_fat16.SectorsPerFAT*2); + RootDirEntryFilePos=RootDirEntrySector*512; + + FATTableFilePos=FATTableSector*512; + FATTableSizeInSectors=RootDirEntrySector-FATTableSector; + + // FAT16 FAT Table + FAT16_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat16.bpb_fat16.NumberOfCopiesOfFats); + + // FAT16 Directory Entry + FAT16_Directory_Entry(RootDirEntryFilePos); + + DataAreaSector=CurrentPosSector+detected_fat16.bpb_fat16.ReservedSectors+ + (detected_fat16.bpb_fat16.SectorsPerFAT*2)+ + ((detected_fat16.bpb_fat16.MaxRootDirEntries*32)/detected_fat16.bpb_fat16.BytesPerSector); + DataAreaFilePos=DataAreaSector*512; + //FSeek(DataAreaSector*512); + //unsigned char DataArea[4096]; + } +} + +void FAT32CheckInit(SYSTEMID SystemID) +{ + if( SystemID==PRI_FAT32_INT13 || + SystemID==EXT_FAT32_INT13 + ) + { + CurrentPosSector=FTell()/512; + + struct BOOTSECTOR_FAT32 detected_fat32; + + FATTableSector=CurrentPosSector+detected_fat32.bpb_fat32.ReservedSectors; + + RootDirEntrySector=CurrentPosSector+detected_fat32.bpb_fat32.ReservedSectors+ + (detected_fat32.bpb_fat32.SectorsPerFAT*2); + RootDirEntryFilePos=RootDirEntrySector*512; + + FATTableFilePos=FATTableSector*512; + FATTableSizeInSectors=RootDirEntrySector-FATTableSector; + + // FAT32 FAT Table + FAT32_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat32.bpb_fat32.NumberOfFATs); + + // FAT32 Directory Entry + FAT32_Directory_Entry(RootDirEntryFilePos); + } +} + +//###################################### +// Check if it's a drive access on FAT +//###################################### +typedef struct _FATStruct +{ + local unsigned short mbr_boot_ok=0; + local quad FATTableSector; + local quad FATTableFilePos; + local quad FATTableSizeInSectors; + + local quad RootDirEntrySector; + local quad RootDirEntryFilePos; + + // Check EndOfSectorMarker (present on MBR/FAT16/FAT32/NTFS + if(ReadUShort(510)==0xAA55) + { + boot boot_sect; + local unsigned short i; + // Check if MBR (check BootIndicator) + for(i=0;i<4;i++) + { + if( (boot_sect.mbr.partitions[i].BootIndicator==SYSTEM_PARTITION || + boot_sect.mbr.partitions[i].BootIndicator==NOBOOT) && + boot_sect.mbr.partitions[i].SystemID!=EMPTY + ) + { + if(mbr_boot_ok==0) + { + FSeek(0); + MASTER_BOOT_RECORD detected_mbr; + mbr_boot_ok=1; + } + // Jump to Partition + FSeek(boot_sect.mbr.partitions[i].RelativeSector*512); + // Check type of filesystem and add it if found + FAT16CheckInit(boot_sect.mbr.partitions[i].SystemID); + FAT32CheckInit(boot_sect.mbr.partitions[i].SystemID); + } + } + // Check if FAT16 + if(boot_sect.boot_fat16.FileSystem=="FAT16 ") + { + FSeek(0); + BOOTSECTOR_FAT16 detected_fat16; + + FATTableSector=0+detected_fat16.bpb_fat16.ReservedSectors; + + RootDirEntrySector=0+detected_fat16.bpb_fat16.ReservedSectors+ + (detected_fat16.bpb_fat16.SectorsPerFAT*2); + RootDirEntryFilePos=RootDirEntrySector*512; + + FATTableFilePos=FATTableSector*512; + FATTableSizeInSectors=RootDirEntrySector-FATTableSector; + + // FAT16 FAT Table + FAT16_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat16.bpb_fat16.NumberOfCopiesOfFats); + + // FAT16 Directory Entry + FAT16_Directory_Entry(RootDirEntryFilePos); + + DataAreaSector=0+detected_fat16.bpb_fat16.ReservedSectors+ + (detected_fat16.bpb_fat16.SectorsPerFAT*2)+ + ((detected_fat16.bpb_fat16.MaxRootDirEntries*32)/detected_fat16.bpb_fat16.BytesPerSector); + DataAreaFilePos=DataAreaSector*512; + //FSeek(DataAreaSector*512); + //unsigned char DataArea[4096]; + } + // Check if FAT32 + if(boot_sect.boot_fat32.FileSystem=="FAT32 ") + { + FSeek(0); + struct BOOTSECTOR_FAT32 detected_fat32; + + FATTableSector=0+detected_fat32.bpb_fat32.ReservedSectors; + + RootDirEntrySector=0+detected_fat32.bpb_fat32.ReservedSectors+ + (detected_fat32.bpb_fat32.SectorsPerFAT*2); + RootDirEntryFilePos=RootDirEntrySector*512; + + FATTableFilePos=FATTableSector*512; + FATTableSizeInSectors=RootDirEntrySector-FATTableSector; + + // FAT32 FAT Table + FAT32_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat32.bpb_fat32.NumberOfFATs); + + // FAT32 Directory Entry + FAT32_Directory_Entry(RootDirEntryFilePos); + + } + // Check if NTFS + //FSeek(0); + //struct BOOTSECTOR_NTFS detected_ntfs; + }else + { + /* + Warning( "File/Disk is not a valid MBR/FAT16/FAT32/NTFS (wrong BootIndicator). Template stopped." ); + return -1; + */ + } +}MBR_FAT; + +MBR_FAT mbr_fat; +// Shared DataAreaSector && DataAreaFilePos diff --git a/cparser/MFTRecord.bt b/cparser/MFTRecord.bt new file mode 100644 index 0000000..139b535 --- /dev/null +++ b/cparser/MFTRecord.bt @@ -0,0 +1,309 @@ +//-------------------------------------- +//--- 010 Editor v6.0.3 Binary Template +// +// File: MFTRecord.bt +// Author: Andrea Barberio +// Revision: 1 +// Purpose: Parsing of MFT records in NTFS file systems +//-------------------------------------- + +string getMFTNameFromRecurdNumber(UINT32 record_number) { + // Return the name of well-known record numbers + switch (record_number) { + case 0: + return "$MFT"; + case 1: + return "$MFTMirr"; + case 2: + return "$LogFile"; + case 3: + return "$Volume"; + case 4: + return "$AttrDef"; + case 5: + return "$. (root dir)"; + case 6: + return "$Bitmap"; + case 7: + return "$Boot"; + case 8: + return "$BadClus"; + case 9: + return "$Secure"; + case 10: + return "$UpCase"; + case 11: + return "$Extend"; + default: + return ""; + } +} + +string GetMFTRecordComment(struct MFTRecord &record) { + string ret; + + SPrintf(ret, "Record # %u %s (%s)", + record.mftheader.mft_rec_number, + getMFTNameFromRecurdNumber(record.mftheader.mft_rec_number), + HeaderFlagsToString(record.mftheader.flags) + ); + return ret; +} + + +wstring GetMFTNameFromAttribute(struct Attributes &attrs) { + // TODO handle differences between NT and 2k fields + switch (attrs.attribute.fixed_header.type) { + case STANDARD_INFORMATION: + return "$STANDARD_INFORMATION"; + case ATTRIBUTE_LIST: + return "$ATTRIBUTE_LIST"; + case FILE_NAME: + string ret; + SPrintf(ret, "$FILE_NAME (%s)", + attrs.attribute.resident_attribute_content.file_name); + return ret; + case OBJECT_ID: + return "$OBJECT_ID"; + case SECURITY_DESCRIPTOR: + return "$SECURITY_DESCRIPTOR"; + case VOLUME_NAME: + return "$VOLUME_NAME"; + case VOLUME_INFORMATION: + return "$VOLUME_INFORMATION"; + case DATA: + string ret; + if (attrs.attribute.fixed_header.non_res_flag) + return "$DATA (Non resident)"; + else + return "$DATA (Resident)"; + case INDEX_ROOT: + return "$INDEX_ROOT"; + case INDEX_ALLOCATION: + return "$INDEX_ALLOCATION"; + case BITMAP: + string ret; + SPrintf(ret, + "$BITMAP (map of bits telling for each record if they are in use or not)"); + return ret; + case REPARSE_POINT: + return "$REPARSE_POINT"; + case EA_INFORMATION: + return "$EA_INFORMATION"; + case EA: + return "$EA"; + case LOGGED_UTILITY_STREAM: + return "$LOGGED_UTILITY_STREAM"; + default: + return ""; + } +} + + +string HeaderFlagsToString(UINT16 flags) { + string ret; + + if (flags & 0x02) + Strcat(ret, "Directory, "); + else + Strcat(ret, "File, "); + if (flags & 0x01) + Strcat(ret, "In use"); + else + Strcat(ret, "Not in use"); + return ret; +} + + +string AttributeFlagsToString(UINT16 flags) { + string ret; + + if (flags & 0x01) + Strcat(ret, "Compressed, "); + else + Strcat(ret, "Not Compressed, "); + if (flags & 0x4000) + Strcat(ret, "Encrypted, "); + else + Strcat(ret, "Not Encrypted, "); + if (flags & 0x8000) + Strcat(ret, "Sparse"); + else + Strcat(ret, "Not Sparse"); + return ret; +} + + +string GetParentDirComment(uint64 ref_to_parent_dir) { + string ret, + details; + + // FIXME for some reason the input number is truncated, hence the seq_num is + // wrong + UINT16 seq_num = ref_to_parent_dir >> 24; + UQUAD mft_entry = ref_to_parent_dir & 0x0000ffffffffffff; + if (mft_entry == 0x05) { + // record 0x05 is the root directory ($.) + Strcat(ret, "Root dir, "); + } + SPrintf(details, "Seq num = %04xh [!!] , MFT entry = %012xh", seq_num, mft_entry); + Strcat(ret, details); + return ret; +} + + +string GetAllocSize(UQUAD alloc_size) { + // assuming 4096-byte cluster size + string ret; + UQUAD num_clusters = alloc_size / 4096 + (alloc_size % 4096 ? 1 : 0); + SPrintf(ret, "%lu clusters (each cluster 4096 bytes)", num_clusters); + return ret; +} + + +string GetDataRunStart(UINT16 data_run_info) { + string ret; + SPrintf(ret, "Starting at 0x%x (assuming cluster size = 4096)", data_run_info * 4096); + return ret; +} + +typedef struct MFTAttribute { + local int64 mftattribute_start = FTell(); + struct FixedHeader { + enum { + STANDARD_INFORMATION = 0x10, + ATTRIBUTE_LIST = 0x20, + FILE_NAME = 0x30, + OBJECT_ID = 0x40, // on NT it's VOLUME_VERSION, on 2k it's OBJECT_ID + SECURITY_DESCRIPTOR = 0x50, + VOLUME_NAME = 0x60, + VOLUME_INFORMATION = 0x70, + DATA = 0x80, + INDEX_ROOT = 0x90, + INDEX_ALLOCATION = 0xa0, + BITMAP = 0xb0, + REPARSE_POINT = 0xc0, // on NT it's SYMBOLIC_LINK, on 2k it's REPARSE_POINT + EA_INFORMATION = 0xd0, + EA = 0xe0, + LOGGED_UTILITY_STREAM = 0x100 // on NT it's PROPERTY_SET, on 2k it's LOGGED_UTILITY_STREAM + } type; // Attribute type identifier + UINT32 attr_length; // length of attribute + enum { + RESIDENT = 0, + NON_RESIDENT = 1 + } non_res_flag ; // resident flag + UBYTE name_length; // length of name + UINT16 name_offset; // offset to name + UINT16 flags ; // flags + UINT16 attribute_id; // attribute identifier + } fixed_header; + if (fixed_header.non_res_flag) { + struct NonResidentAttributeHeader { + UQUAD start_vcn; // starting Virtual Cluster Number of the runlist + UQUAD end_vcn; // ending Virtual Cluster Number of the runlist + UINT16 datarun_offset; // offset to the runlist + UINT16 compression_size ; // compression unit size + UINT32 padding; // unused + UQUAD alloc_size ; // allocated size of attribute content + UQUAD real_size ; // actual size of attribute content + UQUAD stream_size ; // initialized size of attribute content + } non_resident_attribute_header; + if (fixed_header.type == DATA) { + struct AttributeContentNonResidentData { + UBYTE unknown; + UBYTE num_of_clusters; + UINT16 data_run_start ; + char padding[3]; + } attribute_content_non_resident_data; + } else if (fixed_header.type == BITMAP) { + struct AttributeContentNonResidentBitmap { + char bitmap[fixed_header.attr_length - non_resident_attribute_header.datarun_offset]; + } attribute_content_non_resident_bitmap; + } else { + // TODO define other data types + } + } else { + struct ResidentAttributeHeader { + UINT32 content_size; + UINT16 content_offset; + UINT16 indexed_tag; + } resident_attribute_header; + struct ResidentAttributeContent { + if (fixed_header.type == STANDARD_INFORMATION) { + struct AttributeContentStandardInformation { + FILETIME creation_time; + FILETIME alteration_time; + FILETIME mft_changed_time; + FILETIME read_time; + UINT32 dos_permissions; + UINT32 max_num_of_versions; + UINT32 version_number; + UINT32 class_id; + } attribute_content_standard_information; + if (resident_attribute_header.content_size != 48) { + UINT32 owner_id; + UINT32 security_id; + UQUAD quota_charged; + UQUAD update_sequence_number; + } + } else if (fixed_header.type == FILE_NAME) { + struct AttributeContentFileName { + UQUAD file_ref_to_parent_dir ; + FILETIME file_creation_time; + FILETIME file_modification_time; + FILETIME mft_modification_time; + FILETIME file_access_time; + UQUAD allocated_size; + UQUAD real_size; + UINT32 flags; + UINT32 used_by_eas_and_reparse; + UBYTE filename_length_unicode; + UBYTE filename_namespace; + } attribute_content_file_name; + // variable, file name in Unicode + wchar_t file_name[attribute_content_file_name.filename_length_unicode]; + } else { + UCHAR data[resident_attribute_header.content_size]; + // TODO define other data types + } + } resident_attribute_content; + } + UCHAR padding[fixed_header.attr_length - (FTell() - mftattribute_start)]; +} mftattribute; + +struct MFTRecord { + struct MFTHeader { + char file_signature[4] ; // magic number, "FILE" + UINT16 fixup_offset; // offset to the update sequence + UINT16 fixup_size; // number of entries in the fixup array + UQUAD log_seq_number; // $LogFile Sequence Number (LSN) + UINT16 sequence; // Sequence Number + UINT16 hard_links ; // Hard link count + UINT16 attrib_offset; // Offset to first attribute + UINT16 flags ; // Flags: 0x01: record in use, 0x02: directory + UINT32 rec_length ; // Used size of MFT entry + UINT32 all_length ; // Allocated size of MFT entry + UQUAD base_mft_rec; // File reference to the base FILE record + UINT16 next_attr_id; // Next attribute ID + UINT16 fixup_pattern; // Align to 4 bytes boundary + UINT32 mft_rec_number ; // Number of this MFT record + } mftheader; + UQUAD fixup; // is this correct? + local int i; + local int64 pos; + local UINT32 terminator; + for (i = 0; i == i ; i++) { + pos = FTell(); + terminator = ReadUInt(); + if (terminator == 0xffffffff) { + struct Terminator { + UINT32 terminator ; + } terminator ; + break; + } else { + struct Attributes { + mftattribute attribute; + } attributes ; + } + } +} mftrecord ; diff --git a/cparser/MIDITemplate.bt b/cparser/MIDITemplate.bt new file mode 100644 index 0000000..931921f --- /dev/null +++ b/cparser/MIDITemplate.bt @@ -0,0 +1,241 @@ +/* General-MIDI Parser + * By Jack Andersen + */ + +BigEndian(); + +struct MidiHeader +{ + char m_magic[4] ; + uint m_seclen; + enum + { + MIDI_SINGLE = 0, + MIDI_MULTIPLE = 1, + MIDI_PATTERN = 2 + } m_format; + short m_ntracks; + short m_tickdiv; +}; + +struct DeltaTime +{ + local uint total = 0; + char t0; + total += t0 & 0x7f; + if (!(t0 & 0x80)) + break; + + total <<= 7; + char t1; + total += t1 & 0x7f; + if (!(t1 & 0x80)) + break; + + total <<= 7; + char t2; + total += t2 & 0x7f; + if (!(t2 & 0x80)) + break; + + total <<= 7; + char t3; + total += t3 & 0x7f; + if (!(t3 & 0x80)) + break; +}; + +struct MidiMessage +{ + DeltaTime m_dtime; + char m_status; + local char m_channel = m_status & 0xf; + if ((m_status & 0xf0) == 0x80) + { + struct + { + char m_note; + char m_velocity; + } note_off_event; + } + else if ((m_status & 0xf0) == 0x90) + { + struct + { + char m_note; + char m_velocity; + } note_on_event; + } + else if ((m_status & 0xf0) == 0xA0) + { + struct + { + char m_note; + char m_pressure; + } note_pressure_event; + } + else if ((m_status & 0xf0) == 0xB0) + { + struct + { + char m_controller; + char m_value; + } controller_event; + } + else if ((m_status & 0xf0) == 0xC0) + { + struct + { + char m_program; + } program_event; + } + else if ((m_status & 0xf0) == 0xD0) + { + struct + { + char m_pressure; + } channel_pressure_event; + } + else if ((m_status & 0xf0) == 0xE0) + { + struct + { + char m_lsb; + char m_msb; + } pitch_bend_event; + } + else if (m_status == -1) + { + struct + { + enum + { + META_SEQUENCE_NUM = 0, + META_TEXT = 1, + META_COPYRIGHT = 2, + META_SEQUENCE_NAME = 3, + META_INSTRUMENT_NAME = 4, + META_LYRIC = 5, + META_MARKER = 6, + META_CUE_POINT = 7, + META_PROGRAM_NAME = 8, + META_DEVICE_NAME = 9, + META_MIDI_CHANNEL_PREFIX = 0x20, + META_MIDI_PORT = 0x21, + META_END_OF_TRACK = 0x2f, + META_TEMPO = 0x51, + META_SMPTE_OFFSET = 0x54, + META_TIME_SIGNATURE = 0x58, + META_KEY_SIGNATURE = 0x59, + META_SEQUENCER_EVENT = 0x7f + } m_type; + DeltaTime m_length; + if (m_type == META_SEQUENCE_NUM) + { + short m_seqNum; + } + else if (m_type == META_TEXT) + { + char m_text[m_length.total]; + } + else if (m_type == META_COPYRIGHT) + { + char m_copyright[m_length.total]; + } + else if (m_type == META_SEQUENCE_NAME) + { + char m_name[m_length.total]; + } + else if (m_type == META_INSTRUMENT_NAME) + { + char m_name[m_length.total]; + } + else if (m_type == META_LYRIC) + { + char m_lyric[m_length.total]; + } + else if (m_type == META_MARKER) + { + char m_marker[m_length.total]; + } + else if (m_type == META_CUE_POINT) + { + char m_cuePoint[m_length.total]; + } + else if (m_type == META_PROGRAM_NAME) + { + char m_programName[m_length.total]; + } + else if (m_type == META_DEVICE_NAME) + { + char m_deviceName[m_length.total]; + } + else if (m_type == META_MIDI_CHANNEL_PREFIX) + { + char m_channelPrefix; + } + else if (m_type == META_MIDI_PORT) + { + char m_port; + } + else if (m_type == META_END_OF_TRACK) + { + } + else if (m_type == META_TEMPO) + { + uint m_usecPerQuarterNote : 24; + local uint m_bpm = 60000000 / m_usecPerQuarterNote; + FSeek(FTell() - 1); + } + else if (m_type == META_SMPTE_OFFSET) + { + char m_hours; + char m_mins; + char m_secs; + char m_fps; + char m_fracFrames; + } + else if (m_type == META_TIME_SIGNATURE) + { + char m_numerator; + char m_denominator; + char m_clocksPerClick; + char m_32ndPer4th; + } + else if (m_type == META_KEY_SIGNATURE) + { + char m_flatsSharps; + char m_majorMinor; + } + else + { + char m_data[m_length.total]; + } + } meta_event; + } + else if ((m_status & 0xf0) == 0xF0) + { + struct + { + DeltaTime m_length; + char m_message[m_length.total]; + } sysex_event; + } +}; + +struct MidiTrack +{ + char m_magic[4] ; + uint m_seclen; + local uint remaining = m_seclen; + while (remaining) { + MidiMessage message; + remaining -= sizeof(message); + } +}; + +struct +{ + MidiHeader header; + MidiTrack tracks[header.m_ntracks] ; +} file; diff --git a/cparser/MOBITemplate.bt b/cparser/MOBITemplate.bt new file mode 100644 index 0000000..174d283 --- /dev/null +++ b/cparser/MOBITemplate.bt @@ -0,0 +1,714 @@ +//----------------------------------- +//--- 010 Editor v4.0 Binary Template +// +// File: MOBITemplate.bt +// Author: David W. Deley +// Revision: 2.2 +// Purpose: Defines a template for +// parsing MOBI ebook files. +//----------------------------------- + +// Define structures used in MOBI files + +typedef struct { // Record Info ri + DWORD dataOffset; + UBYTE attributeBits; + UBYTE uid1; + WORD uid2; +} ri; + +void checkpdfheader() +{ + // Check for correct header + if ( ( type != "BOOK" || creator != "MOBI") + &&( type != "TEXt" || creator != "REAd") ) + { + Warning( "File is not BOOKMOBI or TEXtREAd. Template stopped." ); + return -1; + } +} + +typedef struct { // Palm Database Format header pdf + CHAR name[32]; + WORD attributeBits; + WORD version; + DWORD creationDate; + DWORD modificationDate; + DWORD lastBackupDate; + DWORD modificationNumber; + DWORD appInfoID; + DWORD sortInfoID; + CHAR type[4]; + CHAR creator[4]; + checkpdfheader(); + DWORD uniqueIDseed; + DWORD nextRecordListID; + WORD numberOfRecords; + //read record pointers + SetBackColor( cWhite ); + struct { // Record Pointer + DWORD dataOffset; + UBYTE attributeBits; + UBYTE uid1; + WORD uid2; + } recptr[pdf.numberOfRecords]; +} PalmDatabaseFormat; + +enum eCompression { + NoCompression = 1, + PalmDOC = 2, + HUFFCDIC = 17480 +}; + +enum encryptionType { + NoEncryption = 0, + OldMobipocketEncryption = 1, + MobipocketEncryption = 2 +}; + +enum TextEncoding { + CP1252_WinLatin1 = 1252, + UTF8 = 65001 +}; + +enum MobiType { + MobipocketBook = 2, + PalmDOCbook= 3, + Audio= 4, + News= 257, + NewsFeed= 258, + NewsMagazine= 259, + PICS= 513, + Word= 514, + XLS= 515, + PPT= 516, + TEXT= 517, + HTML= 518 +}; + + +typedef struct { // PalmDOC Header pdh + eCompression compression; + WORD unused; + DWORD textLength; + WORD numPDBrecords; + WORD recMaxSize; + encryptionType encryption; + Assert( encryption == 0, "File encrypted. Abort." ); + WORD unknown1; +} PalmDOCheader; + +typedef enum eMBHflags { + multibyte = 0x0001, // Declared public; may be accessed from outside its package. + trailers = 0x0002 +} MBHflags ; + +string readMBHflags (local MBHflags &flags) { + local string s = ""; + local int commaNeeded = 0; + local MBHflags i = 1; + + SPrintf (s, "%x: ", flags); + + // Iterate over all possible values the flags + // if the given bit is set, add it's text representation to the + // return string. + // NOTE: There's probably a better way to do this. (More portable?) + while (i <= 2) { + if (flags && i) { + if (commaNeeded) { s += ", "; } + s += EnumToString(i); + commaNeeded = 1; + } + i = i << 1; + } + return s; +} + +//MOBI Header +typedef struct { + CHAR identifier[4] ; //MOBI + DWORD headerLength; + MobiType mobiType; + WORD cryptoType; + TextEncoding textEncoding ; + DWORD uniqueID; + DWORD MOBIversion; + DWORD orthographicIndex ; + DWORD inflectionIndex ; + DWORD indexNames ; + DWORD indexKeys ; + DWORD extraIndex0 ; + DWORD extraIndex1 ; + DWORD extraIndex2 ; + DWORD extraIndex3 ; + DWORD extraIndex4 ; + DWORD extraIndex5 ; + DWORD firstNonBookIndex ; //? + DWORD fullNameOffset ; + DWORD fullNameLength ; + DWORD locale; + DWORD inputLanguage; + DWORD outputLanguage; + DWORD minVersion; + DWORD firstImageIndex; + DWORD huffmanRecordOffset; + DWORD huffmanRecordCount; + DWORD huffmanTableOffset; + DWORD huffmanTableLength; + DWORD EXTHflags; + CHAR unknown2[32]; + DWORD DRMoffset; + DWORD DRMcount; + DWORD DRMsize; + DWORD DRMflags; + CHAR unknown3[12]; + WORD FirstContentRecNo; + WORD LastContentRecNo; + DWORD unknown4; + DWORD FCISrecNo; + DWORD unknown5; + DWORD FLISrecNo; + DWORD unknown6; + QWORD unknown7; + DWORD unknown8; + DWORD unknown9; + DWORD unknown10; + DWORD unknown11; + MBHflags mbhflags; //A set of binary flags, some of which indicate extra data at the end of each text block. This only seems to be valid for Mobipocket format version 5 and 6 (and higher?), when the header length is 228 (0xE4) or 232 (0xE8). + DWORD INDXrecordOffset; +} MobiHeader; + + +enum TextToSpeach { + TextToSpeechEnabled = 0, + TextToSpeechDisabled = 1 +}; + +enum CreatorSoftware { + mobigen = 1, + MobipocketCreator = 2, + kindlegen_Windows = 200, + kindlegen_Linux = 201, + kindlegen_Mac = 202 +}; + +typedef struct { + enum EXTHrecordType { + Drm_Server_Id = 1, + Drm_Commerce_Id = 2, + Drm_Ebookbase_Book_Id = 3, + Creator = 100, + Publisher = 101, + Imprint = 102, + Description = 103, + ISBN = 104, + Subject = 105, + Published = 106, + Review = 107, + Contributor = 108, + Rights = 109, + SubjectCode = 110, + Type = 111, + Source = 112, + ASIN = 113, + VersionNumber = 114, + Sample = 115, + StartReading = 116, + Adult = 117, + Price = 118, + Currency = 119, + K8_Boundary_Section = 121, + fixed_layout = 122, + book_type = 123, + orientation_lock = 124, + K8_Count_of_Resources_Fonts_Images = 125, + original_resolution = 126, + K8_Cover_Image = 129, + K8_Unidentified_Count = 131, + RegionMagnification = 132, + DictShortName = 200, + CoverOffset = 201, + ThumbOffset = 202, + HasFakeCover = 203, + CreatorSoftwareRecord = 204, + CreatorMajorVersion = 205, + CreatorMinorVersion = 206, + CreatorBuildNumber = 207, + Watermark = 208, + Tamper_proof_keys = 209, + FontSignature = 300, + ClippingLimit = 401, + PublisherLimit = 402, + TextToSpeachFlag = 404, + CDE_Type = 501, + last_update_time = 502, + Updated_Title = 503 + /* Long Title + // # Amazon seems to regard this as the definitive book title + # rather than the title from the PDB header. In fact when + # sending MOBI files through Amazon's email service if the + # title contains non ASCII chars or non filename safe chars + # they are messed up in the PDB header + */ + } recordType; + DWORD recordLength; + switch (recordType) { + case 1 : //Drm_Server_Id : + UBYTE Drm_Server_Id[recordLength-8]; + break; + case 2 : //Drm_Commerce_Id : + UBYTE Drm_Commerce_Id[recordLength-8]; + break; + case 3 : //Drm_Ebookbase_Book_Id : + UBYTE Drm_Ebookbase_Book_Id[recordLength-8]; + break; + case 100 : //Creator (author) : + UBYTE creator[recordLength-8]; + break; + case 101 : //Publisher : + UBYTE publisher[recordLength-8]; + break; + case 102 : //Imprint : + UBYTE imprint[recordLength-8]; + break; + case 103 : //Description : + UBYTE description[recordLength-8]; + break; + case 104 : //ISBN : + UBYTE ISBN[recordLength-8]; + break; + case 105 : //Subject : + UBYTE subject[recordLength-8]; + break; + case 106 : //PublishingDate : + UBYTE publishingDate[recordLength-8]; + break; + case 107 : //Review : + UBYTE review[recordLength-8]; + break; + case 108 : //Contributor : + UBYTE contributor[recordLength-8]; + break; + case 109 : //Rights : + UBYTE rights[recordLength-8]; + break; + case 110 : //SubjectCode : + UBYTE subjectCode[recordLength-8]; + break; + case 111 : //Type : + UBYTE type[recordLength-8]; + break; + case 112 : //Source : + UBYTE source[recordLength-8]; + break; + case 113 : //ASIN : + UBYTE ASIN[recordLength-8]; + break; + case 114 : //'versionnumber', + UBYTE versionNumber[recordLength-8]; + break; + case 115 : //'sample'. 0x0001 if the book content is only a sample of the full book + Assert( recordLength == 12, "sample recordLength-8 != 4 (DWORD)." ); + DWORD sample; + break; + case 116 : //'startreading', 'StartOffset' Position (4-byte offset) in file at which to open when first opened + UBYTE startReading[recordLength-8]; + break; + case 117 : //Adult : + UBYTE adult[recordLength-8]; + break; + case 118 : //Price 'retailprice': + UBYTE price[recordLength-8]; + break; + case 119 : //Currency 'retailPriceCurrency': + UBYTE currency[recordLength-8]; + break; + case 121 : //K8_Boundary_Section = 121, + case 122 : // fixed_layout = 122, + case 123 : // book_type = 123, + case 124 : // orientation_lock = 124, + case 125 : // K8_Count_of_Resources_Fonts_Images = 125, + case 126 : // original_resolution = 126, + case 129 : // K8_Cover_Image = 129, + case 131 : // K8_Unidentified_Count = 131, + case 132 : // RegionMagnification = 132, + UBYTE unknown[recordLength-8]; + break; + + case 200 : //DictShortName : + UBYTE dictShortName[recordLength-8]; + break; + case 201 : //'coveroffset', . Add to first image field in Mobi Header to find PDB record containing the cover image + Assert( recordLength == 12, "coverOffset recordLength-8 != 4 (DWORD)." ); + DWORD coverOffset; + break; + case 202 : //'thumboffset', + Assert( recordLength == 12, "thumbOffset recordLength-8 != 4 (DWORD)." ); + DWORD thumbOffset; + break; + case 203 : //'hasfakecover', + UBYTE hasFakeCover[recordLength-8]; + break; + case 204 : //'Creator Software'. Known Values: 1=mobigen, 2=Mobipocket Creator, 200=kindlegen (Windows), 201=kindlegen (Linux), 202=kindlegen (Mac). + Assert( recordLength == 12, "creatorSoftware recordLength-8 != 4 (DWORD)." ); + CreatorSoftware creatorSoftware; + break; + case 205 : //'Creator Major Version', # '>I' + Assert( recordLength == 12, "creatorMajorVersion recordLength-8 != 4 (DWORD)." ); + DWORD creatorMajorVersion; + break; + case 206 : //'Creator Minor Version', # '>I' + Assert( recordLength == 12, "creatorMinorVersion recordLength-8 != 4 (DWORD)." ); + DWORD creatorMinorVersion; + break; + case 207 : //'Creator Build Number', # '>I' + Assert( recordLength == 12, "creatorBuildNumber recordLength-8 != 4. (DWORD)" ); + DWORD creatorBuildNumber; + break; + case 208 : //Watermark : + UBYTE watermark[recordLength-8]; + break; + case 209 : //'tamper_proof_keys'. Used by the Kindle (and Android app) for generating book-specific PIDs. + UBYTE tamper_proof_keys[recordLength-8]; + break; + case 300 : //'fontsignature', + UBYTE fontSignature[recordLength-8]; + break; + case 301 : //'clippinglimit', # percentage '>B' Integer percentage of the text allowed to be clipped. Usually 10. + UBYTE clippingLimit[recordLength-8]; + break; + case 402 : //'publisherlimit', + UBYTE publisherLimit[recordLength-8]; + break; + case 404 : //'TTS flag', # '>B' 1 - TTS disabled 0 - TTS enabled 1 - Text to Speech disabled; 0 - Text to Speech enabled + Assert( recordLength == 9, "TextToSpeach recordLength-8 != 1 (BYTE)." ); + TextToSpeach textToSpeach; + break; + case 501 : //CDE Type : PDOC - Personal Doc; EBOK - ebook; EBSP - ebook sample; + Assert( recordLength == 12, "CDEtype recordLength-8 != 1. (DWORD)" ); + CHAR CDEtype[4]; + break; + case 502 : //'lastupdatetime', + UBYTE lastUpdateTime[recordLength-8]; + break; + case 503 : //Updated Title : + UBYTE updatedTitle[recordLength-8]; + break; + case 504 : //ASIN (copy)? + UBYTE ASINcopy[recordLength-8]; + break; + case 524 : //language from + UBYTE dclanguage[recordLength-8]; + break; + default : + UBYTE unknown[recordLength-8]; + break; + } +} EXTHrecord; + +typedef struct { //EXTH Header + CHAR identifier[4]; //EXTH + DWORD headerLength; + UINT recordCount; + local int i = 0; + for ( i = 0; i < recordCount; i++) { + EXTHrecord exthrecord; + } +} ExthHeader; + +typedef struct { // FLIS RECORD + UINT ID ; + UINT fixed1 ; + USHORT fixed2 ; + USHORT fixed3 ; + UINT fixed4 ; + UINT fixed5 ; + USHORT fixed6 ; + USHORT fixed7 ; + UINT fixed8 ; + UINT fixed9 ; + UINT fixed10 ; +} FLISRECORD; + + +typedef struct { // FDST RECORD for (KF8) format + UINT ID ; + UINT FDSTstart ; + UINT fdstcnt ; + struct { + UBYTE record[ reclen - 12]; + } fdst; +} FDSTkf8RECORD; + +typedef struct { // FCIS RECORD + UINT ID ; + UINT fixed1 ; + UINT fixed2 ; + UINT fixed3 ; + UINT fixed4 ; + UINT fixed5 ; + UINT fixed6 ; + UINT fixed7 ; + UINT fixed8 ; + USHORT fixed9 ; + USHORT fixed10 ; + UINT fixed11 ; +} FCISRECORD; + +typedef struct { // SRCS RECORD + UINT ID ; + struct { + UBYTE record[ reclen - 4]; + } srcs; +} SRCSRECORD; + +typedef struct { // DATP RECORD + UINT ID ; + struct { + UBYTE record[ reclen - 4]; + } datp; +} DATPRECORD; + +typedef struct { + QUAD ID ; +} BOUNDARYRECORD; + +typedef struct { // HTML RECORD + struct { + UBYTE b[ reclen ]; + } html; +} HTML; + +typedef struct { // INDX RECORD + UINT ID ; + UINT headerLength ; + UINT indexType ; + UINT unknown1 ; + UINT unknown2 ; + UINT idxtStart ; + UINT indexEncoding ; + UINT indexLanguage ; + UINT totalIndexCount ; + UINT ordtStart ; + UINT ligtStart ; + UINT unknown3; + UINT unknown4; +} INDXRECORD; + +typedef struct { // end-of-file + UBYTE fixed1 ; + UBYTE fixed2 ; + UBYTE fixed3 ; + UBYTE fixed4 ; +} ENDRECORD; + + +//--------------------------------------------- + +// Define the headers +BigEndian(); +SetBackColor( cLtGray ); +PalmDatabaseFormat pdf; + +//record 0 is PalmDOC Header +FSeek(pdf.recptr[0].dataOffset); +SetBackColor( cLtGray ); +PalmDOCheader pdh; +MobiHeader mbh; +local char fullName[255]; +local char KF8fullName[255]; +//local int outFile = FileNew(); +local int reclen; +local int i, n; +local int endrec; +local char tag[9]; + +if (mbh.fullNameOffset != 0) +{ + //get full name + FSeek(pdf.recptr[0].dataOffset + mbh.fullNameOffset); + ReadBytes(fullName, FTell(), mbh.fullNameLength); + fullName[mbh.fullNameLength] = '\0'; +// FPrintf(outFile, "fullName=%s\n", fullName); +} + +if (mbh.EXTHflags & 0x40) +{ + //find EXTH record + FSeek(pdf.recptr[0].dataOffset + 16 + mbh.headerLength); //16 for the PalmDOCheader + SetBackColor( cYellow ); + ExthHeader exth; +} + +local uint multibyte = 0; +local uint trailers = 0; +if ( pdf.type == "BOOK" && pdf.creator == "MOBI") +{ + if ((mbh.headerLength >= 0xE4) && (pdf.version >= 5)) + { + multibyte = flags & 1; + while (flags > 1) + { + if (flags & 2) + { + ++trailers; + flags = flags >> 1; + } + } + } +} + + +for( i = 0; i < pdf.numberOfRecords - 1; i++ ) +{ + FSeek(pdf.recptr[i].dataOffset); + reclen = ( pdf.recptr[i+1].dataOffset - pdf.recptr[i].dataOffset ); +// FPrintf(outFile, "i=%d, reclen=%d\n", i, reclen); + ReadBytes(tag, FTell(), 8); + tag[8] = '\0'; + +// FPrintf(outFile, "tag=%s\n", tag ); + // Parse data depending upon tag + if( Memcmp(tag,"FLIS",4) == 0) //FLIS + { + SetBackColor( cLtGray ); + FLISRECORD data; + } + else if( Memcmp(tag,"FDST",4) == 0) //FDST + { + SetBackColor( cLtGray ); + FDSTkf8RECORD data; + } + else if( Memcmp(tag,"FCIS",4) == 0 ) //FCIS + { + SetBackColor( cLtGreen ); + FCISRECORD data; + if (data.fixed1 < 0x10) + { +// FPrintf(outFile, "0"); + } +// FPrintf(outFile, "%X ", data.fixed1); +// FPrintf(outFile, "\n"); + } + else if( Memcmp(tag,"SRCS",4) == 0 ) //SRCS + { + SetBackColor( cLtRed ); + SRCSRECORD data; + } + else if( Memcmp(tag,"DATP",4) == 0 ) //DATP + { + SetBackColor( cLtBlue ); + DATPRECORD data; + for (n = 0; n < reclen-4; n++) + { + if (data.datp.record[n] < 0x10) + { +// FPrintf(outFile, "0"); + } +// FPrintf(outFile, "%X ", data.datp.record[n]); + } +// FPrintf(outFile, "\n"); + } + else if( Memcmp(tag,"INDX",4) == 0 ) //INDX + { + SetBackColor( cSilver ); + INDXRECORD data; + } + else if(Memcmp(tag,"BOUNDARY",8) == 0 ) //BOUNDARY (check record length is 8 bytes) + { + SetBackColor( cYellow ); + BOUNDARYRECORD data; + //record following BOUNDARY is another PalmDOC Header for KF8 + SetBackColor( cLtGray ); + i++; + PalmDOCheader data; + MobiHeader KF8mbh; + if (KF8mbh.fullNameOffset != 0) + { + //get full name + FSeek(pdf.recptr[i].dataOffset + KF8mbh.fullNameOffset); + ReadBytes(KF8fullName, FTell(), KF8mbh.fullNameLength); + fullName[KF8mbh.fullNameLength] = '\0'; +// FPrintf(outFile, "KF8fullName=%s\n", fullName); + } + if (KF8mbh.EXTHflags & 0x40) + { + //find EXTH record +// FPrintf(outFile, "KF8EXTH present\n"); + FSeek(pdf.recptr[i].dataOffset + 16 + KF8mbh.headerLength); //16 for the PalmDOCheader + SetBackColor( cYellow ); + ExthHeader KF8exth; + } + } + else if( Memcmp(tag,"",6) == 0 ) + { + SetBackColor( cLtGreen ); + HTML data; + } + else if( Memcmp(tag,"; +string ReadPDFrec( PDFREC &a ) +{ + local uint reclen; + reclen = ( pdf.recptr[1].dataOffset - pdf.recptr[0].dataOffset ); + string s; + s = "Hello"; + return s; +} + // Define each line of the image + struct PDFREC { + UBYTE Data[ 4096 ]; + } record[ pdf.numberOfRecords ]; + + + + +RGBQUAD aColors[ bmih.biClrUsed ]; + +typedef struct +{ + char record[]; +} +MATRIX[pdf.numberOfRecords]; + +MATRIX pdfrec; + +local uint reclen; +reclen = ( pdf.recptr[1].dataOffset - pdf.recptr[0].dataOffset ); +FSeek(pdf.recptr[0].dataOffset); +pdfrec[0].record[reclen]; + +reclen = ( pdf.recptr[2].dataOffset - pdf.recptr[1].dataOffset ); +FSeek(pdf.recptr[1].dataOffset); +pdfrec[1].record[reclen]; +*/ +return; \ No newline at end of file diff --git a/cparser/MP3Template.bt b/cparser/MP3Template.bt new file mode 100644 index 0000000..0239616 --- /dev/null +++ b/cparser/MP3Template.bt @@ -0,0 +1,498 @@ +//-------------------------------------- +//--- 010 Editor v1.3.2 Binary Template +// +// File: MP3Template.bt +// Author: Ivan Getta (ivanitto@ukr.net) +// Purpose: MP3 files analysis and smart editing +// +// Template version: 1.0 +// Release date: 2005 Feb 18 +// Licence: free +// +//--- Template features ---------------- +// +// 1) MPEG frames support: +// * MPEG-1, MPEG-2 +// * Layer 1,2,3 +// 2) ID3v1 tags support +// 3) ID3v1.1 tags support +// 4) ID3v2.3 tags support +// +//--- Notes ---------------------------- +// +// TODO: +// 1) MPEG 2.5 support +// 2) Resolve known bugs (see below) +// +// KNOWN BUGS (STILL PRESENT): +// 1) Incorrect frame size detection for MPEG 1.0 layer 3 +// mono files with low bitrate (for example 56k, 64k). +// Frame size must be detected twice long. +// 2) Mp3pro files have some problems +// +//--- References ----------------------- +// +// 1. "010 Editor templates" +// http://www.sweetscape.com/010editor/templates.html +// +// 2. "The private life of MP3 frames" +// http://www.id3.org/mp3frame.html +// +// 3. "ID3 made easy (ID3v1 & ID3v1.1)" +// http://www.id3.org/id3v1.html +// +// 4. "ID3 tag version 2.3.0 (Informal standard)" +// http://www.id3.org/id3v2.3.0.html +// +//-------------------------------------- + + +local uint32 bitrate, frame_size, sampling_freq, frames_count = 0; +local quad frame_header_offset, seek_pos, sum_bitrate = 0; +local short data; +local byte was_bad_sync, id3v1_tag_found = 0; +local ubyte buf[3]; + + +enum ID3_GENRES +{ + Blues, Classic_Rock, Country, Dance, Disco, Funk, Grunge, Hip_Hop, // 7 + Jazz, Metal, New_Age, Oldies, Other, Pop, R_and_B, Rap, // 15 + Reggae, Rock, Techno, Industrial, Alternative, Ska, Death_Metal, Pranks, // 23 + Soundtrack, Euro_Techno, Ambient, Trip_Hop, Vocal, Jazz_Funk, Fusion, Trance, // 31 + Classical, Instrumental, Acid, House, Game, Sound_Clip, Gospel, Noise, // 39 + AlternRock, Bass, Soul, Punk, Space, Meditative, Instrumental_Pop, Instrumental_Rock, // 47 + Ethnic, Gothic, Darkwave, Techno_Industrial, Electronic, Pop_Folk, Eurodance, Dream, // 55 + Southern_Rock, Comedy, Cult, Gangsta, Top_40, Christian_Rap, Pop_Funk, Jungle, // 63 + Native_American, Cabaret, New_Wave, Psychadelic, Rave, Showtunes, Trailer, Lo_Fi, // 71 + Tribal, Acid_Punk, Acid_Jazz, Polka, Retro, Musical, Rock_n_Roll, Hard_Rock, // 79 + Folk, Folk_Rock, National_Folk, Swing, Fast_Fusion, Bebob, Latin, Revival, // 87 + Celtic, Bluegrass, Avantgarde, Gothic_Rock, + Progressive_Rock, Psychedelic_Rock, Symphonic_Rock, Slow_Rock, // 95 + Big_Band, Chorus, Easy_Listening, Acoustic, Humour, Speech, Chanson, Opera, // 103 + Chamber_Music, Sonata, Symphony, Booty_Bass, Primus, Porn_Groove, Satire, Slow_Jam, // 111 + Club, Tango, Samba, Folklore, Ballad, Power_Ballad, Rhythmic_Soul, Freestyle, // 119 + Duet, Punk_Rock, Drum_Solo, A_capella, Euro_House, Dance_Hall, Goa, Drum_and_Bass, // 127 + Club_House, Hardcore, Terror, Indie, BritPop, Negerpunk, Polsk_Punk, Beat, // 135 + Christian, Heavy_Metal, Black_Metal, Crossover, + Contemporary, Christian_Rock, Merengue, Salsa, Thrash_Metal, Anime, JPop, Synthpop // 147 +}; + + +struct ID3v1_TAG +{ + DisplayFormatDecimal(); + + SetBackColor(0x33BC55); + char id[3]; // always must be "TAG" + + SetBackColor(0x48E048); + char title[30]; + + SetBackColor(0x5DE45D); + char artist[30]; + + SetBackColor(0x72E872); + char album[30]; + + SetBackColor(0x87EC87); + char year[4]; + + if ( ReadByte(FTell()+28) == 0 && ReadByte(FTell()+29) != 0 ) + { + // We have ID3v1.1 tag + + SetBackColor(0x9CF09C); + char comment[28]; + + SetBackColor(0xB1F4B1); + byte zero; + + SetBackColor(0xC6F8C6); + ubyte track; + } + else + { + // We have ID3v1.0 tag + + SetBackColor(0x9CF09C); + char comment[30]; + } + + SetBackColor(0xDBFCDB); + ID3_GENRES genre; +}; + + +struct ID3v2_HEADER +{ + SetBackColor(0x91C4FF); + + char head[3]; // always must be "ID3" ($49 44 33) + + DisplayFormatDecimal(); + + ubyte ver_major; // this byte will never be $FF + ubyte ver_revision; // this byte will never be $FF + + struct FLAGS { + ubyte UNSYNCHRONISATION_USED : 1; + ubyte EXTENDED_HEADER_PRESENT : 1; + ubyte EXPERIMENTAL_TAG : 1; + ubyte : 5; + } flags; + + DisplayFormatHex(); + + ubyte size[4]; // Is the size of the complete tag after unsynchronisation, + // including padding, excluding the header but not excluding + // the extended header (total tag size - 10). Most + // significant bit (bit 7) of each byte is set to zero +}; + + +struct ID3v2_EXTENDED_HEADER +{ + SetBackColor(0xA1D4FF); + + DisplayFormatDecimal(); + + uint32 size; // extended header size, excluding this 'size' field + + uint16 FLAG_CRC_PRESENT : 1; // extended header flags + uint16 : 15; // + + uint32 padding_sz; + + if (FLAG_CRC_PRESENT) + { + DisplayFormatHex(); + uint32 crc; + } +}; + + +struct ID3v2_FRAME +{ + char id[4]; // four alpha chars + + DisplayFormatDecimal(); + + uint32 size; // frame size without frame header + + struct FRAME_FLAGS { + uint16 TAG_ALTER_PRESERV : 1; + uint16 FILE_ALTER_PRESERV : 1; + uint16 READ_ONLY_FRAME : 1; + uint16 : 5; + uint16 COMPRESSED_FRAME : 1; + uint16 ENCRYPTED_FRAME : 1; + uint16 GROUP_MEMBER_FRAME : 1; + uint16 : 5; + } flags; + + if (id[0] == 'T') + { + // frame contains text related data + if ( ReadByte(FTell()) == 0 && size > 1) + { + byte id_asciiz_str; + char frame_data [size - 1]; + } + else + char frame_data [size]; + } + else + { + DisplayFormatHex(); + ubyte frame_data [size]; + } +}; + + +struct ID3v2_TAG +{ + ID3v2_HEADER hdr; + + // calculating real size of the ID3v2 tag + local uint32 tag_sz = hdr.size[0]; + tag_sz <<= 7; + tag_sz |= hdr.size[1]; + tag_sz <<= 7; + tag_sz |= hdr.size[2]; + tag_sz <<= 7; + tag_sz |= hdr.size[3]; + + // + // An ID3v2 tag header can be detected with the following pattern: + // $49 44 33 yy yy xx zz zz zz zz + // Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80. + // + if (hdr.ver_major == 0xFF || hdr.ver_revision == 0xFF || + hdr.size[0] >= 0x80 || hdr.size[1] >= 0x80 || + hdr.size[2] >= 0x80 || hdr.size[3] >= 0x80) + { + Printf("MP3: warning: invalid ID3v2 tag header\n"); + } + else + { + if (hdr.ver_major != 3 || hdr.flags.UNSYNCHRONISATION_USED || hdr.flags.EXPERIMENTAL_TAG) + { + Printf("MP3: warning: skipping unsupported ID3v2.%d tag\n", hdr.ver_major); + SetBackColor(0xA9DCFF); + DisplayFormatHex(); + ubyte id3v2_data[tag_sz]; + } + else + { + if ( hdr.flags.EXTENDED_HEADER_PRESENT ) + ID3v2_EXTENDED_HEADER ext_hdr; + + // Now reading ID3v2 frames + // A tag must contain at least one frame. A frame must be + // at least 1 byte big, excluding the header. + // + local uint32 frame_color = 0xC9FCFF; + do + { + SetBackColor(frame_color); + ID3v2_FRAME tf; + frame_color -= 0x020200; + } + while ( FTell() < tag_sz + sizeof(hdr) && ReadByte(FTell()) != 0 ); + + SetBackColor(0x99CCFF); + ubyte id3v2_padding [ tag_sz + sizeof(hdr) - FTell() ]; + } + } +}; + + +// 32-bit MPEG frame header octets: +// AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM +// +struct MPEG_HEADER +{ + SetBackColor(0xCC99FF); + + DisplayFormatHex(); + + uint32 frame_sync : 12; // A + + DisplayFormatDecimal(); + + uint32 mpeg_id : 1; // B + uint32 layer_id : 2; // C + uint32 protection_bit : 1; // D + uint32 bitrate_index : 4; // E + uint32 frequency_index : 2; // F + uint32 padding_bit : 1; // G + uint32 private_bit : 1; // H + uint32 channel_mode : 2; // I + uint32 mode_extension : 2; // J + uint32 copyright : 1; // K + uint32 original : 1; // L + uint32 emphasis : 2; // M + + if (protection_bit == 0) + { + DisplayFormatHex(); + uint16 checksum; + } +}; + + +struct MPEG_FRAME +{ + MPEG_HEADER mpeg_hdr; + + // define frame bitrate + bitrate = 0; + + // header sanity check + if (mpeg_hdr.frame_sync < 0xFFE || mpeg_hdr.layer_id == 0 || + mpeg_hdr.bitrate_index == 0 || mpeg_hdr.bitrate_index == 15 || + mpeg_hdr.frequency_index == 3) + { + Printf("MP3: warning: invalid MPEG header in frame at offset 0x%X\n", + FTell() - 4 - (mpeg_hdr.protection_bit==0 ? 2:0) ); + + // Try to find MPEG header starting from offset (current - 2) + FSeek( FTell() - 2 ); + } + else + { + if (mpeg_hdr.layer_id == 3) // MPEG-1,2 Layer 1 + { + bitrate = (uint32)mpeg_hdr.bitrate_index<<5; + } + else + { + if (mpeg_hdr.layer_id == 2) // MPEG-1,2 Layer 2 + { + bitrate = (uint32)mpeg_hdr.bitrate_index==1 ? 32 : + (1 << 5+(uint32)mpeg_hdr.bitrate_index/4) + + ( ((uint32)mpeg_hdr.bitrate_index&3) << + 3+(uint32)mpeg_hdr.bitrate_index/4 ); + } + else + { + if (mpeg_hdr.mpeg_id == 1) // MPEG-1 (Layer 3) + { + bitrate = (1 << 5+((uint32)mpeg_hdr.bitrate_index-1)/4) + + ( ((uint32)mpeg_hdr.bitrate_index-1&3) << + 3+((uint32)mpeg_hdr.bitrate_index-1)/4); + } + else // (MPEG-2) (Layer 3) + { + bitrate = (uint32)mpeg_hdr.bitrate_index<4 ? + + 8*(uint32)mpeg_hdr.bitrate_index : + + (1<<4+(uint32)mpeg_hdr.bitrate_index/4) + + ( + ((uint32)mpeg_hdr.bitrate_index&3)==0 ? 0 : + + ((uint32)mpeg_hdr.bitrate_index&3)==1 ? + (1<<4+(uint32)mpeg_hdr.bitrate_index/4) : + + ((uint32)mpeg_hdr.bitrate_index&3)==2 ? + (1<<4+(uint32)mpeg_hdr.bitrate_index/4) + + ((1<<4+(uint32)mpeg_hdr.bitrate_index/4)>>1) : + + (1<<4+(uint32)mpeg_hdr.bitrate_index/4) - + ((1<<4+(uint32)mpeg_hdr.bitrate_index/4)>>2) + ); + } + } + } + } + + if (bitrate != 0) + { + local uint16 freq[3]; + freq[0] = 2205; + freq[1] = 2400; + freq[2] = 1600; + + sampling_freq = freq[mpeg_hdr.frequency_index]; + + if (mpeg_hdr.mpeg_id == 1) // if MPEG-1 + sampling_freq <<= 1; + + frame_size = (bitrate * 14400) / sampling_freq; + + if (mpeg_hdr.channel_mode == 3) + frame_size >>= 1; + + frame_size -= 4 + (mpeg_hdr.protection_bit==0 ? 2:0) - mpeg_hdr.padding_bit; + + frame_header_offset = FTell() - 4 - (mpeg_hdr.protection_bit==0 ? 2:0); + + // read frame data + if ( FTell() + frame_size > FileSize() ) + { + Printf("MP3: warning: cut MPEG frame at end of file (frame header offset = 0x%LX, data length = %u)\n", + frame_header_offset, frame_size); + + Printf("MP3: file parsing completed!\nMP3: valid MPEG frames found: %d\n", frames_count); + + if (frames_count != 0) + Printf("MP3: average frame bitrate: %d kbit\n", sum_bitrate / frames_count); + + return; + } + else + { + DisplayFormatHex(); + SetBackColor(0xCCCCFF); + ubyte mpeg_frame_data [ frame_size ]; + } + + sum_bitrate += bitrate; + + frames_count++; + } +}; + + +//-------------------------------------------------------------- + + +BigEndian(); + +ReadBytes(buf, 0, 3); + +if ( ! Strcmp(buf, "ID3") ) +{ + Printf("MP3: ID3v2 tag found\n"); + ID3v2_TAG id3v2_tag; +} + +while ( !FEof() && !id3v1_tag_found ) +{ + // Reading file, until find frame synchronization + seek_pos = FTell(); + was_bad_sync = 0; + do + { + data = ReadShort( seek_pos ); + + if ( (uint16)data == 0x5441 && (uchar)ReadByte(seek_pos+2) == 0x47 ) + id3v1_tag_found = 1; // we found "TAG" identifier + + if ( !was_bad_sync && (uint16)data < 0xFFE0 && !id3v1_tag_found ) + { + Printf("MP3: warning: invalid MPEG frame synchronization at offset 0x%LX\n", seek_pos); + was_bad_sync = 1; + } + + seek_pos++; + } + while ( (uint16)data < 0xFFE0 && seek_pos < (FileSize()-1) && !id3v1_tag_found ); + + if ( (uint16)data >= 0xFFE0 || id3v1_tag_found ) + { + FSeek(seek_pos - 1); + } + else + { + Printf("MP3: file parsing completed!\nMP3: valid MPEG frames found: %d\n", frames_count); + + if (frames_count != 0) + Printf("MP3: average frame bitrate: %d kbit\n", sum_bitrate / frames_count); + + return; + } + + if ( !id3v1_tag_found ) + { + MPEG_FRAME mf; + + if (frames_count == 1 && bitrate) + Printf("MP3: first found MPEG frame parameters:\nMP3:\t- header ofsset: 0x%LX\nMP3:\t- bitrate: %d kbit\nMP3:\t- MPEG-%d layer %d\nMP3:\t- sampling frequency: %d Hz\nMP3:\t- channel mode: %s\nMP3:\t- CRC protected: %s\n", + frame_header_offset, + bitrate, + mf.mpeg_hdr.mpeg_id==1 ? 1:2, + mf.mpeg_hdr.layer_id==1 ? 3 : mf.mpeg_hdr.layer_id==2 ? 2:1, + sampling_freq*10, + mf.mpeg_hdr.channel_mode==3 ? "mono" : + mf.mpeg_hdr.channel_mode==0 ? "stereo" : + mf.mpeg_hdr.channel_mode==1 ? "joint stereo" : "dual channel", + mf.mpeg_hdr.protection_bit==0 ? "Yes" : "No"); + } +} + +if (id3v1_tag_found) +{ + Printf("MP3: ID3v1 tag found\n"); + ID3v1_TAG id3v1_tag; +} + +if ( !FEof() ) + Printf("MP3: warning: there is some unknown extra-data after ID3v1 tag at end of file\n"); + +Printf("MP3: file parsing completed!\nMP3: valid MPEG frames found: %d\n", frames_count); + +if (frames_count != 0) + Printf("MP3: average frame bitrate: %d kbit\n", sum_bitrate / frames_count); diff --git a/cparser/MP4Template.bt b/cparser/MP4Template.bt new file mode 100644 index 0000000..a0cacfb --- /dev/null +++ b/cparser/MP4Template.bt @@ -0,0 +1,163 @@ +//------------------------------------------------------------- +//--- 010 Editor v6.0.2 Binary Template +// +// File: MP4.bt +// Author: Marian Denes +// Revision: 2.1 +// Date: 2015.06.04 +// Purpose: Defines a template for parsing MP4 and MOV files. +//------------------------------------------------------------- + +BigEndian(); + +local int64 pos; +local int64 pos2; + +typedef union { + /*uint number;*/ + char text[4]; + } _typ; + +string typeFullName(_typ& type) { + if (Memcmp(type.text, "ftyp", 4) == 0) return "File type compatibility box"; + if (Memcmp(type.text, "mvhd", 4) == 0) return "Movie header box"; + if (Memcmp(type.text, "iods", 4) == 0) return "Initial object descriptor box"; + if (Memcmp(type.text, "trak", 4) == 0) return "Track box"; + if (Memcmp(type.text, "udta", 4) == 0) return "Uset data box"; + if (Memcmp(type.text, "mdat", 4) == 0) return "Movie (sample) data box"; + if (Memcmp(type.text, "moov", 4) == 0) return "Moovie box"; + if (Memcmp(type.text, "tkhd", 4) == 0) return "Track header box"; + if (Memcmp(type.text, "mdia", 4) == 0) return "Media box"; + if (Memcmp(type.text, "edts", 4) == 0) return "Edit box"; + if (Memcmp(type.text, "elst", 4) == 0) return "Edit list"; + return "I don't know the full name"; + } + +string typeString(_typ& type) { + return "Type of the box: \"" + type.text + "\""; +} + +// MessageBox(idOk, "", "GetCursorPos == %d", GetCursorPos()); + +while(FTell() < FileSize() - 1) { + struct _box { + uint size ; + _typ type ; + if (Memcmp(type.text, "ftyp", 4) == 0) { + char major_brand[4] ; + char minor_ver [4] ; + uint comp_brands[(size - sizeof(size) - sizeof(type) - sizeof(major_brand) - + sizeof(minor_ver)) / 4] ; + } else if (Memcmp(type.text, "moov", 4) == 0) { + pos = FTell(); + while(FTell() < pos + size - sizeof(size) - sizeof(type)) + struct _box2 { + uint size ; + _typ type ; + if (Memcmp(type.text, "mvhd", 4) == 0) { + char version ; + char flags[3] ; + uint crTime ; + uint mdTime ; + uint tmScale ; + uint duration ; + char rest[size - sizeof(size) - sizeof(type) - sizeof(version) - + sizeof(flags) - sizeof(crTime) - sizeof(mdTime) - + sizeof(tmScale) - sizeof(duration)]; + } else if (Memcmp(type.text, "trak", 4) == 0) { + pos2 = FTell(); + while(FTell() < pos2 + size - sizeof(size) - sizeof(type)) + struct _box3 { + uint size ; + _typ type ; + if (Memcmp(type.text, "tkhd", 4) == 0) { + char version ; + char flags[3] ; + uint crTime ; + uint mdTime ; + uint trkID < name="Track ID", open=false>; + uint reserv ; + uint duration < name="Duration", open=false>; + char rest[size - sizeof(size) - sizeof(type) - sizeof(version) - + sizeof(flags) - sizeof(crTime) - sizeof(mdTime) - + sizeof(trkID) - sizeof(reserv) - sizeof(duration)]; + } else if (Memcmp(type.text, "edts", 4) == 0) { + struct _box4 { + uint size ; + _typ type ; + char version ; + char flags[3] ; + uint entrs; + struct { + uint trDuration ; + uint mediaTime ; + uint mediaRate ; + } entry[entrs] ; + } box ; + } else + char rest[size - sizeof(size) - sizeof(type)]; + } box ; + } else + char rest[size - sizeof(size) - sizeof(type)]; + } box ; + } else + char rest[size - sizeof(size) - sizeof(type)]; + } box ; +} + +string boxName(_box& box) { + return box.type.text + " (" + typeFullName(box.type) + ")";; +} + +string boxName2(_box2& box) { + return box.type.text + " (" + typeFullName(box.type) + ")"; +} + +string boxName3(_box3& box) { + return box.type.text + " (" + typeFullName(box.type) + ")"; +} + +string boxName4(_box4& box) { + return box.type.text + " (" + typeFullName(box.type) + ")"; +} + +string brandName(uint brand) { + local char text[4]; + local int i; + + for (i = 0; i < 4; ++i) + text[i] = brand >> 8 * (3 - i) & 0xFF; + return text; +} + +// string boxName5(_box5& box) { +// return box.type.text + " (" + typeFullName(box.type) + ")"; +// } + +// local int i; + +// struct DATABLOCK { +// int dataID; +// uchar dataArray[16]; +// }; + + +// pos = FTell(); // save read position +// for( i = 0; i < 4; i++ ) { +// DATABLOCK data ; +// } +// FSeek( pos ); // restore read position +// +// // Custom read function +// string ReadDataBlock( DATABLOCK &d ) +// { +// // string str; +// // SPrintf( str, "ID = '%d'", d.dataID ); +// FTell( box[i].type] ); +// return str; +// } diff --git a/cparser/MachOTemplate.bt b/cparser/MachOTemplate.bt new file mode 100644 index 0000000..cbfc8ff --- /dev/null +++ b/cparser/MachOTemplate.bt @@ -0,0 +1,846 @@ +//-------------------------------------- +//--- 010 Editor v3.2.2 Binary Template +// +// File: MachOTemplate.bt +// Author: Tim "diff" Strazzere +// Revision: 1.1 +// Purpose: Quick template for parsing Macho-o binaries, pretty much fully working! +//-------------------------------------- +// +// Version 1.1 +// - Minimum version load command now properly outputs the format for better readability +// - Added a readvalue function for the header, helps understand headers at a glance +// +// Version 1.0 +// - Correctly parses FAT headers and will continue to parse the rest of the combined +// binary +// - Added many todo's to make the output more pretty +// - Fixed some broken LoadCommands (64bit ones mainly), will gracefully fail if unknown +// LoadCommand is hit +// - Found some bugs in 010Editor and added fixes to try to avoid those +// +// Version 0.1 +// - First stab it this, lots of issues - FAT binaries don't work at all +// +// Known issues: +// - Needs optimized structures otherwise anything of a decent size will kill it +// (Related to an 010Editor template bug) +// + +// Mach-o's should be Little Endian only -- except for the fat_header/fat_arch LittleEndian(); + +typedef enum { + MACHO_32 = 0xFEEDFACE, // 32-bit mach object file + MACHO_64 = 0xFEEDFACF, // 64-bit mach object file + MACHO_FAT = 0xCAFEBABE, // Universal object file / FAT_MAGIC + MACHO_FAT_CIGAM = 0xBEBAFECA +} Magic ; + +#define CPU_ARCH_MASK 0xff000000 +#define CPU_ARCH_ABI64 0x01000000 + +// This looks ugly due to a limitation (bug?) in 010Editor template processing, +// basically we're unable to define more constant using other constants - it doesn't +// see them as already being processed when trying to define others (though it won't +// error on this until it hits this when trying to access that constant) +#define CPU_TYPE_X86 0x7 +#define CPU_TYPE_I386 0x7 // CPU_TYPE_X86 +#define CPU_TYPE_X86_64 (0x7 | 0x01000000) // (CPU_TYPE_X86 | CPU_ARCH_ABI64) +#define CPU_TYPE_POWERPC 0x12 +#define CPU_TYPE_POWERPC64 (0x12 | 0x01000000) // (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) +#define CPU_TYPE_ARM 0xC + +typedef enum { + MACH_OBJECT = 0x1, + MACH_EXECUTE = 0x2, + MACH_FVMLIB = 0x3, + MACH_CORE = 0x4, + MACH_PRELOAD = 0x5, + MACH_DYLIB = 0x6, + MACH_DYLINKER = 0x7, + MACH_BUNDLE = 0x8, + MACH_DYLIB_STUB = 0x9, + MACH_DSYM = 0xA, + MACH_KEXT_BUNDLE = 0xB, +} FileType; + +typedef enum { + i386_THREAD_STATE = 0x1, + i386_FLOAT_STATE = 0x2, + i386_EXCEPTION_STATE = 0x3 +} i386ThreadFlavor ; + +typedef struct { + uint32 eax ; + uint32 ebx ; + uint32 ecx ; + uint32 edx ; + uint32 edi ; + uint32 esi ; + uint32 ebp ; + uint32 esp ; + uint32 ss ; + uint32 eflags ; + uint32 eip ; + uint32 cs ; + uint32 ds ; + uint32 es ; + uint32 fs ; + uint32 gs ; +} i386ThreadState; + +typedef enum { + x86_THREAD_STATE32 = 0x1, + x86_FLOAT_STATE32 = 0x2, + x86_EXCEPTION_STATE32 = 0x3, + x86_THREAD_STATE64 = 0x4, + x86_FLOAT_STATE64 = 0x5, + x86_EXCEPTION_STATE64 = 0x6, + x86_THREAD_STATE = 0x7, + x86_FLOAT_STATE = 0x8, + x86_EXCEPTION_STATE = 0x9, + x86_DEBUG_STATE32 = 0xA, + x86_DEBUG_STATE64 = 0xB, + x86_DEBUG_STATE = 0xC, + THREAD_STATE_NONE = 0xD +} x86ThreadFlavor ; + +typedef struct { + uint64 rax ; + uint64 rbx ; + uint64 rcx ; + uint64 rdx ; + uint64 rdi ; + uint64 rsi ; + uint64 rbp ; + uint64 rsp ; + uint64 r8 ; + uint64 r9 ; + uint64 r10 ; + uint64 r11 ; + uint64 r12 ; + uint64 r13 ; + uint64 r14 ; + uint64 r15 ; + uint64 rip ; + uint64 rflags ; + uint64 cs ; + uint64 fs ; + uint64 gs ; +} x86ThreadState; + +typedef enum { + PPC_THREAD_STATE = 0x1, + PPC_FLOAT_STATE = 0x2, + PPC_EXCEPTION_STATE = 0x3, + PPC_VECTOR_STATE = 0x4, + PPC_THREAD_STATE64 = 0x5, + PPC_EXCEPTION_STATE64 = 0x6 +} PPCThreadFlavor ; + +typedef struct { + uint32 r0 ; + uint32 r1 ; + uint32 r2 ; + uint32 r3 ; + uint32 r4 ; + uint32 r5 ; + uint32 r6 ; + uint32 r7 ; + uint32 r8 ; + uint32 r9 ; + uint32 r10 ; + uint32 r11 ; + uint32 r12 ; + uint32 r13 ; + uint32 r14 ; + uint32 r15 ; + uint32 r16 ; +} ARMThreadState; + +typedef struct { + uint32 __srr0 ; + uint32 __srr1 ; + uint32 __r0; + uint32 __r1; + uint32 __r2; + uint32 __r3; + uint32 __r4; + uint32 __r5; + uint32 __r6; + uint32 __r7; + uint32 __r8; + uint32 __r9; + uint32 __r10; + uint32 __r11; + uint32 __r12; + uint32 __r13; + uint32 __r14; + uint32 __r15; + uint32 __r16; + uint32 __r17; + uint32 __r18; + uint32 __r19; + uint32 __r20; + uint32 __r21; + uint32 __r22; + uint32 __r23; + uint32 __r24; + uint32 __r25; + uint32 __r26; + uint32 __r27; + uint32 __r28; + uint32 __r29; + uint32 __r30; + uint32 __r31; + + uint32 __cr ; + uint32 __xer ; + uint32 __lr ; + uint32 __ctr ; + uint32 __mq ; + + uint32 __vrsave ; +} PPCThreadState; + +typedef enum { + MACH_NOUNDEFS = 0x1, + MACH_INCRLINK = 0x2, + MACH_DYLDLINK = 0x4, + MACH_BINDATLOAD = 0x8, + MACH_PREBOUND = 0x10, + MACH_SPLIT_SEGS = 0x20, + MACH_LAZY_INIT = 0x40, + MACH_TWOLEVEL = 0x80, + MACH_FORCE_FLAT = 0x100, + MACH_NOMULTIDEFS = 0x200, + MACH_NOFIXPREBINDING = 0x400, + MACH_PREBINDABLE = 0x800, + MACH_ALLMODSBOUND = 0x1000, + MACH_SUBSECTIONS_VIA_SYMBOLS = 0x2000, + MACH_CANONICAL = 0x4000, + MACH_WEAK_DEFINES = 0x8000, + MACH_BINDS_TO_WEAK = 0x10000, + MACH_ALLOW_STACK_EXECUTION = 0x20000, + MACH_ROOT_SAFE = 0x40000, + MACH_SETUID_SAFE = 0x80000, + MACH_NO_REEXPORTED_DYLIBS = 0x100000, + MACH_PIE = 0x200000, + MACH_DEAD_STRIPPABLE_DYLIB = 0x400000, + MACH_HAS_TLV_DESCRIPTORS = 0x800000, + MACH_NO_HEAP_EXECUTION = 0x1000000 +} Flags; + +typedef struct { + uint32 cpu_type ; + // TODO : Extract out capabilities here + uint32 cpu_sub_type ; + uint32 file_offset ; + uint32 size ; + uint32 align ; +} Fat_Arch; + +typedef struct { + Magic magic ; + + if(magic == MACHO_FAT || magic == MACHO_FAT_CIGAM) { + // Need to switch to BigEndian! + BigEndian(); + uint32 fat_arch_size ; + Fat_Arch fat_arch[fat_arch_size]; + // Switch back to LittleEndian for rest of parsing + LittleEndian(); + } else { + uint32 cpu_type ; + uint32 cpu_sub_type ; + FileType file_type; + uint32 num_load_commands; + uint32 size_of_load_commands; + Flags flags; + } + if(magic == MACHO_64) { + uint32 reserved; + } +} Header ; + +string HeaderRead(Header &header) { + local string header_string; + switch(header.magic) { + case MACHO_FAT : + case MACHO_FAT_CIGAM : + header_string = "FAT header"; + break; + case MACHO_32 : + header_string = "32bit Mach-O header"; + break; + case MACHO_64 : + header_string = "64bit Mach-O header"; + break; + default : + header_string = "Unknown header!"; + } + return header_string; +} + +#define REQ_DYLD (0x80000000) + +typedef enum { + SEGMENT = 0x1, + SYM_TAB = 0x2, + SYM_SEG = 0x3, + THREAD = 0x4, + UNIX_THREAD = 0x5, + LOAD_FVM_LIB = 0x6, + ID_FVM_LIB = 0x7, + IDENT = 0x8, + FVM_FILE = 0x9, + PREPAGE = 0xA, + DY_SYM_TAB = 0xB, + LOAD_DYLIB = 0xC, + ID_DYLIB = 0xD, + LOAD_DYLINKER = 0xE, + ID_DYLINKER = 0xF, + PREBOUND_DYLIB = 0x10, + ROUTINES = 0x11, + SUB_FRAMEWORK = 0x12, + SUB_UMBRELLA = 0x13, + SUB_CLIENT = 0x14, + SUB_LIBRARY = 0x15, + TWOLEVEL_HINTS = 0x16, + PREBIND_CKSUM = 0x17, + LOAD_WEAK_DYLIB = 0x18 | REQ_DYLD, + SEGMENT_64 = 0x19, + ROUTINES_64 = 0x1A, + UUID = 0x1B, + RPATH = 0x1C | REQ_DYLD, + CODE_SIGNATURE = 0x1D, + SEGMENT_SPLIT_INFO = 0x1E, + REEXPORT_DYLIB = 0x1F | REQ_DYLD, + LAZY_LOAD_DYLIB = 0x20, + ENCRYPTION_INFO = 0x21, + DYLD_INFO = 0x22, + DYLD_INFO_ONLY = 0x22 | REQ_DYLD, + LOAD_UPWARD_DYLIB = 0x23 | REQ_DYLD, + VERSION_MIN_MAC_OSX = 0x24, + VERSION_MIN_IPHONE_OS = 0x25, + FUNCTION_STARTS = 0x26, + DYLD_ENVIRONMENT = 0x27, + MAIN = 0x28, + DATA_IN_CODE = 0x29, + SOURCE_VERSION = 0x2A, + DYLIB_CODE_SIGN_DRS = 0x2B +} LoadCommandType ; + +string LoadCommandTypeRead(LoadCommandType &loadCommandType) { + switch(loadCommandType) { + case SEGMENT : + return "SEGMENT"; + case SYM_TAB : + return "SYM_TAB"; + case SYM_SEG : + return "SYM_SEG"; + case THREAD : + return "THREAD"; + case UNIX_THREAD : + return "UNIX_THREAD"; + case LOAD_FVM_LIB : + return "LOAD_FVM_LIB"; + case ID_FVM_LIB : + return "ID_FVM_LIB"; + case IDENT : + return "IDENT"; + case FVM_FILE : + return "FVM_FILE"; + case PREPAGE : + return "PREPAGE"; + case DY_SYM_TAB : + return "DY_SYM_TAB"; + case LOAD_DYLIB : + return "LOAD_DYLIB"; + case ID_DYLIB : + return "ID_DYLIB"; + case LOAD_DYLINKER : + return "LOAD_DYLINKER"; + case ID_DYLINKER : + return "ID_DYLINKER"; + case PREBOUND_DYLIB : + return "PREBOUND_DYLIB"; + case ROUTINES : + return "ROUTINES"; + case SUB_FRAMEWORK : + return "SUB_FRAMEWORK"; + case SUB_UMBRELLA : + return "SUB_UMBRELLA"; + case SUB_CLIENT : + return "SUB_CLIENT"; + case SUB_LIBRARY : + return "SUB_LIBRARY"; + case TWOLEVEL_HINTS : + return "TWOLEVEL_HINTS"; + case PREBIND_CKSUM : + return "PREBIND_CKSUM"; + case LOAD_WEAK_DYLIB : + return "LOAD_WEAK_DYLIB"; + case SEGMENT_64 : + return "SEGMENT_64"; + case ROUTINES_64 : + return "ROUTINES_64"; + case UUID : + return "UUID"; + case RPATH : + return "RPATH"; + case CODE_SIGNATURE : + return "CODE_SIGNATURE"; + case SEGMENT_SPLIT_INFO : + return "SEGMENT_SPLIT_INFO"; + case REEXPORT_DYLIB : + return "REEXPORT_DYLIB"; + case LAZY_LOAD_DYLIB : + return "LAZY_LOAD_DYLIB"; + case ENCRYPTION_INFO : + return "ENCRYPTION_INFO"; + case DYLD_INFO : + return "DYLD_INFO"; + case DYLD_INFO_ONLY : + return "DYLD_INFO_ONLY"; + case LOAD_UPWARD_DYLIB : + return "LOAD_UPWARD_DYLIB"; + case VERSION_MIN_MAC_OSX : + return "VERSION_MIN_MAC_OSX"; + case VERSION_MIN_IPHONE_OS : + return "VERSION_MIN_IPHONE_OS"; + case FUNCTION_STARTS : + return "FUNCTION_STARTS"; + case DYLD_ENVIRONMENT : + return "DYLD_ENVIRONMENT"; + case MAIN : + return "MAIN"; + case DATA_IN_CODE : + return "DATA_IN_CODE"; + case SOURCE_VERSION : + return "SOURCE_VERSION"; + case DYLIB_CODE_SIGN_DRS : + return "DYLIB_CODE_SIGN_DRS"; + default : + return "Error"; + } +} + +typedef struct { + char section_name[16]; + char segment_name[16]; + uint32 address ; + uint32 size ; + uint32 offset; + uint32 section_alignment; + uint32 relocation_entry_offset; + uint32 number_of_relocation_entries; + uint32 flags ; + uint32 reserved1; + uint32 reserved2; +} Section ; + +typedef struct { + char section_name[16]; + char segment_name[16]; + uint64 address ; + uint64 size ; + uint64 offset; + uint32 section_alignment; + uint32 relocation_entry_offset; + uint32 number_of_relocation_entries; + uint32 flags ; + uint32 reserved1; + uint32 reserved2; +} Section64 ; + +typedef uint vm_proc; + +typedef enum { + HIGH_VM = 0x1, + FVM_LIB = 0x2, + NO_RELOC = 0x4, + PROTECTION_VERSION_1 = 0x8 +} SegmentFlags ; + +typedef struct { + uint32 load_command_string_offset ; + + local int64 pos = FTell(); + // We need to goto beginning of LoadCommand, then goto the offset + FSeek(FTell() - (sizeof(uint32) * 3) + load_command_string_offset); + + string string_data ; + + FSeek(pos); +} LoadCommandString ; + +string LoadCommandStringRead(LoadCommandString &loadCommandString) { + return loadCommandString.string_data; +}; + +typedef ubyte Uuid[16] ; + +// TODO : Clean this ugly thing up +string UuidRead(Uuid uuid) { + local string ret, tmp; + local int i; + + for(i = 0; i<4; i++) { + SPrintf(tmp, "%.2X", uuid[i]); + ret += tmp; + } + ret += "-"; + + for(i = 0; i<2; i++) { + SPrintf(tmp, "%.2X", uuid[i+4]); + ret += tmp; + } + ret += "-"; + + for(i = 0; i<2; i++) { + SPrintf(tmp, "%.2X", uuid[i+6]); + ret += tmp; + } + ret += "-"; + + for(i = 0; i<2; i++) { + SPrintf(tmp, "%.2X", uuid[i+8]); + ret += tmp; + } + ret += "-"; + + for(i = 0; i<6; i++) { + SPrintf(tmp, "%.2X", uuid[i+10]); + ret += tmp; + } + return ret; +} + +typedef struct { + uint32 version; +} Version ; + +string VersionRead(Version &version) { + local string version_string; + if(version.version & 0xFF == 0) { + SPrintf(version_string, "%u.%u", version.version >> 16, (version.version >> 8) & 0xFF); + } else { + + SPrintf(version_string, "%u.%u.%u", version.version >> 16, (version.version >> 8) & 0xFF, version.version & 0xFF); + } + return version_string; +} + +typedef struct { + //LoadCommandHead loadCommandHead ; + LoadCommandType command; + uint command_size; + + // Process rest of load command based on command type + switch(command) { + case ID_DYLIB : + case LOAD_DYLIB : + case LOAD_WEAK_DYLIB : + case REEXPORT_DYLIB : + LoadCommandString name; + // TODO : Pretty print this + uint32 timestamp; + // TODO : Pretty print this + uint32 current_version; + // TODO : Pretty print this + uint32 compatibility_version; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 6)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case SYM_TAB : + uint32 symbol_table_offset ; + uint32 number_of_symbol_table_entries ; + uint32 string_table_offset ; + uint32 string_table_size ; + break; + case DYLD_INFO : + case DYLD_INFO_ONLY : + uint32 rebase_offset; + uint32 rebase_size; + uint32 bind_offset; + uint32 bind_size; + uint32 weak_bind_offset; + uint32 weak_bind_size; + uint32 lazy_bind_offset; + uint32 lazy_bind_size; + uint32 export_offset; + uint32 export_size; + break; + case DY_SYM_TAB : + uint32 index_local_symbols; + uint32 local_symbols_size; + uint32 index_externally_defined_symbols; + uint32 externally_defined_symbols_size; + uint32 index_undefined_symbols; + uint32 undefined_symbols_size; + uint32 table_contents_offset; + uint32 enteries_toc_size; + uint32 file_offset_module_table; + uint32 module_table_entries_size; + uint32 external_references_symbol_table_offset; + uint32 external_references_symbol_table_size; + uint32 indirect_symbol_table_offset; + uint32 indirect_symbol_table_size; + uint32 external_relocation_entries_offset; + uint32 external_relocation_entries_size; + uint32 local_relocation_entries_offset; + uint32 local_relocation_entries_size; + break; + case UUID : + Uuid uuid; + break; + case VERSION_MIN_MAC_OSX : + case VERSION_MIN_IPHONE_OS : + // TODO : Pretty print this + Version version; + uint32 reserved ; + break; + case FUNCTION_STARTS : + case CODE_SIGNATURE : + case SEGMENT_SPLIT_INFO: + case DATA_IN_CODE: + uint32 data_offset; + uint32 data_size; + break; + case UNIX_THREAD : + case THREAD : + switch(cpu_typer) { + case CPU_TYPE_X86 : + case CPU_TYPE_I386 : + i386ThreadFlavor flavor; + // TODO : Pretty print this + uint32 count; + switch(flavor) { + case i386_THREAD_STATE : + i386ThreadState threadState; + // TODO : Flesh these guys out + case i386_FLOAT_STATE : + case i386_EXCEPTION_STATE : + } + break; + case CPU_TYPE_X86_64 : + x86ThreadFlavor flavor; + // TODO : Pretty print this + uint32 count; + switch(flavor) { + case x86_THREAD_STATE64 : + x86ThreadState threadState; + break; + // TODO : Flesh these guys out + case x86_FLOAT_STATE64 : + case x86_EXCEPTION_STATE64 : + case x86_DEBUG_STATE64 : + } + break; + case CPU_TYPE_POWERPC : + case CPU_TYPE_POWERPC64 : + PPCThreadFlavor flavor; + // TODO : Pretty print this + uint32 count; + switch(flavor) { + case PPC_THREAD_STATE : + PPCThreadState threadState; + break; + // TODO : Flesh these guys out + case PPC_FLOAT_STATE : + case PPC_EXCEPTION_STATE : + case PPC_VECTOR_STATE : + case PPC_THREAD_STATE64 : + case PPC_EXCEPTION_STATE64 : + } + break; + case CPU_TYPE_ARM : + // TODO: Unsure if this is correct ? +// uint32 flavor; +// uint32 count; + ARMThreadState threadState; + break; + } + break; + case FVM_LIB : + case ID_FVM_LIB : + LoadCommandString name ; + uint32 minor_version ; + uint32 header_address ; + +// Reposition(command_size, sizeof(uint32) * 5); + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 5)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case SUB_FRAMEWORK : + LoadCommandString umbrella ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 3)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case SUB_CLIENT : + LoadCommandString client ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 3)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case SUB_UMBRELLA : + LoadCommandString sub_umbrella ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 3)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case SUB_LIBRARY : + LoadCommandString sub_library ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 3)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case PREBOUND_DYLIB : + LoadCommandString name ; + uint32 modules_size ; + LoadCommandString linked_modules ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 5)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case ID_DYLINKER : + case LOAD_DYLINKER : + LoadCommandString name ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 3)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case ROUTINES_64 : + uint64 init_address ; + uint64 init_module ; + uint32 reversed_1; + uint32 reversed_2; + uint32 reversed_3; + uint32 reversed_4; + uint32 reversed_5; + uint32 reversed_6; + break; + case ROUTINES : + uint32 init_address ; + uint32 init_module ; + uint32 reversed_1; + uint32 reversed_2; + uint32 reversed_3; + uint32 reversed_4; + uint32 reversed_5; + uint32 reversed_6; + break; + case TWOLEVEL_HINTS : + uint32 offset ; + uint32 hints_size ; + break; + case PREBIND_CKSUM : + uint32 cksum ; + break; + case RPATH: + LoadCommandString path ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 3)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case ENCRYPTION_INFO : + uint32 crypt_offset ; + uint32 crypt_size ; + uint32 crypt_id ; + break; + case IDENT : + break; + case FVM_FILE : + LoadCommandString name ; + uint32 header_address ; + + // Seek to the beginning of the LoadCommand + FSeek(FTell() - (sizeof(uint32) * 4)); + // Then skip to the end of the command based on the command_size + FSkip(command_size); + break; + case SEGMENT_64 : + char segment_name[16]; + + uint64 vm_address ; + uint64 vm_size ; + uint64 file_off; + uint64 file_size; + + vm_proc maximum_protection ; + vm_proc initial_protection ; + uint32 number_of_sections; + // TODO : Fix this enum + SegmentFlags flags; + + // Having this if statement will prevent warnings in 010Editor + if(number_of_sections > 0) { + Section64 section[number_of_sections]; + } + break; + case SEGMENT : + char segment_name[16]; + + uint32 vm_address ; + uint32 vm_size ; + uint32 file_off; + uint32 file_size; + + vm_proc maximum_protection ; + vm_proc initial_protection ; + uint32 number_of_sections; + // TODO : Fix this enum + SegmentFlags flags; + + // Having this if statement will prevent warnings in 010Editor + if(number_of_sections > 0) { + Section section[number_of_sections]; + } + break; + default : + Warning("Hit an unknown or unsupported load command : [%d]", command); + Exit(-1); + } +} LoadCommand ; + +string LoadCommandReader(LoadCommand &loadCommand) { + return LoadCommandTypeRead(loadCommand.command) + " load command"; +} + +Header header ; +local uint32 cpu_typer; +if(header.magic == MACHO_32 || header.magic == MACHO_64) { + cpu_typer = header.cpu_type; + // If we didn't find a FAT header, then just process the load commands + LoadCommand loadCommand[header.num_load_commands]; +} else { + // Otherwise we need to grab the new headers again + local int i; + for(i = 0; i < header.fat_arch_size; i++) { + FSeek(header.fat_arch[i].file_offset); + Header machHeader; + cpu_typer = machHeader.cpu_type; + LoadCommand loadCommand[machHeader.num_load_commands]; + } +} \ No newline at end of file diff --git a/cparser/Mifare1kTemplate.bt b/cparser/Mifare1kTemplate.bt new file mode 100644 index 0000000..728c33a --- /dev/null +++ b/cparser/Mifare1kTemplate.bt @@ -0,0 +1,28 @@ +//----------------------------------- +// File: Mifare Classic 1k +// Author: Ruben Boonen (b33f) +// http://www.fuzzysecurity.com/ +// Purpose: Basic Structure +//----------------------------------- + +struct FILE { + struct Manufacturer_block { + char Card_UID[4] ; + char LRC[1] ; + char Internal[11] ; + char Data[32]; + char Key_A[6] ; + char Access_Bits[3] ; + char GPB[1] ; + char Key_B[6] ; + } manufacturer_block; + + struct Sec_4blk { + char Data[48]; + char Key_A[6] ; + char Access_Bits[3] ; + char GPB[1] ; + char Key_B[6] ; + } sec_4blk[ 15 ]; + + } file ; \ No newline at end of file diff --git a/cparser/Mifare4kTemplate.bt b/cparser/Mifare4kTemplate.bt new file mode 100644 index 0000000..fcbc272 --- /dev/null +++ b/cparser/Mifare4kTemplate.bt @@ -0,0 +1,36 @@ +//----------------------------------- +// File: Mifare Classic 4k +// Author: Ruben Boonen (b33f) +// http://www.fuzzysecurity.com/ +// Purpose: Basic Structure +//----------------------------------- + +struct FILE { + struct Manufacturer_block { + char Card_UID[4] ; + char LRC[1] ; + char Internal[11] ; + char Data[32]; + char Key_A[6] ; + char Access_Bits[3] ; + char GPB[1] ; + char Key_B[6] ; + } manufacturer_block; + + struct Sec_4blk { + char Data[48]; + char Key_A[6] ; + char Access_Bits[3] ; + char GPB[1] ; + char Key_B[6] ; + } sec_4blk[ 31 ]; + + struct Sec_16blk { + char Data[240]; + char Key_A[6] ; + char Access_Bits[3] ; + char GPB[1] ; + char Key_B[6] ; + } sec_16blk[ 8 ]; + + } file ; \ No newline at end of file diff --git a/cparser/NetflowVersion5.bt b/cparser/NetflowVersion5.bt new file mode 100644 index 0000000..0a2156b --- /dev/null +++ b/cparser/NetflowVersion5.bt @@ -0,0 +1,48 @@ +//-------------------------------------- +//--- 010 Editor v2.1.3 Binary Template +// +// File: Netflow Version 5 +// +// Author: Andrew Faust +// Revision: +// Purpose: Parses a Netflow Version 5 record +//-------------------------------------- + +BigEndian(); + +struct FLOW { + struct HEADER { + ushort Version; + ushort Count; + uint SysUptime; + uint EopochSeconds; + uint NanoSeconds; + uint FlowsSeen; + byte EngineType; + byte EngineID; + char filler[2]; + } header; + + struct DATA { + char SourceIP[4]; + char DestIP[4]; + char NextHopIP[4]; + ushort InSNMP; + ushort OutSNMP; + uint PacketCount; + uint ByteCount; + uint StartFlowTime; + uint EndFlowTime; + ushort SourcePort; + ushort DestPort; + char filler[1]; + byte TCPFlags; + byte Protocol; + byte TypeOfService; + ushort SourceSysID; + ushort DestSysID; + byte SourceMaskBitsCount; + byte DestMaskBitsCount; + char filler2[2]; + } data [ flow.header.Count ]; +} flow; \ No newline at end of file diff --git a/cparser/OGGTemplate.bt b/cparser/OGGTemplate.bt new file mode 100644 index 0000000..de4c10c --- /dev/null +++ b/cparser/OGGTemplate.bt @@ -0,0 +1,56 @@ +//-------------------------------------- +//--- 010 Editor v4.0.4 Binary Template +// +// File: OGGTemplate.bt +// Author: George Woods +// Revision: +// Purpose: Parses the ogg container format. +//-------------------------------------- + +// ogg files can be quite large. Don't read more the 1000 pages. +local uint MAXPAGES = 1000; + +typedef struct { // bmfh + CHAR CapturePattern[4]; + BYTE Version; + BYTE HeaderType; + QUAD GranulePosition; + DWORD BitstreamSerial; + DWORD PageSequenceNumber; + DWORD Checksum; + UBYTE PageSegments; + + // the lengths of the segments that follow + UBYTE SegmentLen[PageSegments]; + + // the segments themselves + local uint i; + for (i = 0; i < PageSegments; i++) { + struct { + BYTE Data[SegmentLen[i]] ; + } Segment; + } +} PAGE; + + +LittleEndian(); + +local uint currpage = 0; +while( !FEof() ) +{ + currpage++; + if (MAXPAGES < currpage) + { + Printf("Max Pages of %d reached!\n", maxpages); + return 0; + } + + PAGE page ; + + // Check for valid header + if( page.CapturePattern != "OggS" ) + { + Warning( "File is not a valid ogg file. Template stopped." ); + return -1; + } +} diff --git a/cparser/OrCAD3.20a_LIB.bt b/cparser/OrCAD3.20a_LIB.bt new file mode 100644 index 0000000..a16310c --- /dev/null +++ b/cparser/OrCAD3.20a_LIB.bt @@ -0,0 +1,289 @@ +//----------------------------------- +//--- 010 Editor v6.0 Binary Template +// +// File: OrCAD3.20a_LIB.bt +// Author: L. Potjewijd +// Revision: 1.21 +// Date: 20150530 +// Purpose: Parsing OrCad 3.20a library files +//----------------------------------- + +enum YesNo {No,Yes}; +enum Vtype {END,LINE,CIRCLE,TEXT,ARC,FILL}; +enum ptype {IN,I_O,OUT,OC,PAS,hiZ,OE,PWR}; +enum pquad {II,IV}; +enum pside {Left,Right,Top,Bottom}; + +typedef byte bit; // just for readability + +typedef struct sText +{ byte Length ; + if (Length > 0) char String[Length]; +}; + +typedef struct fTxt (byte fixLen) +{ byte Length ; + if (Length > 0) char String[Length]; + if ((fixLen > 0) && (fixLen > Length)) char filler[fixLen-Length]; +}; + +typedef struct Coord +{ short X; + short Y; +}; + +typedef struct idxP +{ ushort NameOffset ; + ushort DefOffset ; + BigEndian(); + WORD PrefixBitmap ; + LittleEndian(); + WORD unknown ; +}; + +typedef struct Offsets +{ ushort offsetLarge; + ushort offsetMedium; + ushort offsetSmall; +}; + +typedef struct PartDet +{ BigEndian(); /*************************/ + WORD raw ; /* this is to display */ + LittleEndian(); /* the 'raw' bits, too */ + FSkip (-2); /*************************/ + BitfieldLeftToRight(); + YesNo hasConvDef : 1; // exact meaning is uncertain + bit bitE : 1 ; + bit bitD : 1 ; + ubyte subparts : 5; // maximum = 16 + YesNo isGridArray : 1; + bit bit6 : 1 ; + bit bit5 : 1 ; + bit bit4 : 1 ; + bit bit3 : 1 ; + YesNo NormBitmap : 1; + YesNo ConvBitmap : 1; + bit bit0 : 1 ; +}; + +typedef struct PinDet +{ BigEndian(); /*************************/ + WORD raw ; /* this is to display */ + LittleEndian(); /* the 'raw' bits, too */ + FSkip (-2); /*************************/ + BitfieldLeftToRight(); + YesNo vertical : 1 ;; + byte location : 7; + ptype type : 3; + YesNo isShort : 1; + YesNo hasDOT : 1; + YesNo hasCLK : 1; + bit bit1 : 1 ; + pquad quadrant : 1 ; + local pside side = quadrant + (2 * vertical); +}; + +typedef struct DefPart +{ ushort Length ; + local ushort PartStart