mirror of https://github.com/x64dbg/btparser
385 lines
10 KiB
Plaintext
385 lines
10 KiB
Plaintext
//------------------------------------
|
|
//--- 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<NumberOfNameEntries;j++)
|
|
{
|
|
struct
|
|
{
|
|
local int64 currentaddress;
|
|
uint32 NameRVA:31 <format=hex>;
|
|
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 <format=hex>;
|
|
int PointToChild:1;
|
|
currentaddress= FTell();
|
|
if (PointToChild==1)
|
|
{
|
|
FSeek(resource_sa+DataEntryRVA);
|
|
GetResourceDirectory();
|
|
FSeek(currentaddress);
|
|
};
|
|
} DirectoryNameEntry;
|
|
};
|
|
for( j=0;j<NumberOfIDEntries;j++)
|
|
{
|
|
struct
|
|
{
|
|
local int64 currentaddress;
|
|
//if (res_show_log==1){Printf("\nLevel %d. ",res_level);}
|
|
switch( res_level )
|
|
{
|
|
case 1:
|
|
uint32 IntegerID <comment=ShowType>;
|
|
rTypeID=IntegerID;
|
|
if (res_show_log==1){Printf("\n%s",ShowType(rTypeID));}
|
|
break;
|
|
case 2:
|
|
uint32 IntegerID <comment=ShowName>;
|
|
rNameID=IntegerID;
|
|
if (res_show_log==1){Printf("\n%s",ShowName(rNameID));}
|
|
break;
|
|
case 3:
|
|
uint32 IntegerID <comment=ShowLanguage>;
|
|
rLanguageID=IntegerID;
|
|
if (res_show_log==1){Printf("\n%s",ShowLanguage(rLanguageID));}
|
|
break;
|
|
}
|
|
uint32 DataEntryRVA:31 <format=hex>;
|
|
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 <format=hex>;
|
|
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;
|
|
}
|
|
}
|