//------------------------------------ //--- 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; } }