analyze pe "Executable file" x32/x64

Share your advanced PureBasic knowledge/code with the community.
User avatar
CELTIC88
Enthusiast
Enthusiast
Posts: 154
Joined: Thu Sep 17, 2015 3:39 pm

analyze pe "Executable file" x32/x64

Post by CELTIC88 »

hello :D ;

Portable Executable :
https://en.wikipedia.org/wiki/Portable_Executable

This code allows you to analyze and visualize all PE structures .

Image

code

Code: Select all

EnableExplicit

;By Celtic88 ;)

#IMAGE_RESOURCE_NAME_IS_STRING     =$80000000
#IMAGE_RESOURCE_DATA_IS_DIRECTORY     =$80000000

;IMAGE_DOS_HEADER\e_magic
#IMAGE_DOS_HEADER=$5A4D;Magic number

;IMAGE_NT_HEADERS\Signature
#IMAGE_NT_SIGNATURE=$00004550;signature 

;IMAGE_FILE_HEADER\Machine
#IMAGE_FILE_MACHINE_I386=$014c;x86
#IMAGE_FILE_MACHINE_IA64=$0200;Intel Itanium
#IMAGE_FILE_MACHINE_AMD64=$8664;x64

;IMAGE_NT_HEADERS\FileHeader\Characteristics
#IMAGE_FILE_RELOCS_STRIPPED=$0001;Relocation information was stripped from the file. The file must be loaded at its preferred base address. If the base address is not available, the loader reports an error.
#IMAGE_FILE_EXECUTABLE_IMAGE=$0002;The file is executable (there are no unresolved external references).
#IMAGE_FILE_LINE_NUMS_STRIPPED=$0004;COFF line numbers were stripped from the file.
#IMAGE_FILE_LOCAL_SYMS_STRIPPED=$0008;COFF symbol table entries were stripped from file.
#IMAGE_FILE_AGGRESIVE_WS_TRIM=$0010  ;Aggressively trim the working set. This value is obsolete.
#IMAGE_FILE_LARGE_ADDRESS_AWARE=$0020;The application can handle addresses larger than 2 GB.
#IMAGE_FILE_BYTES_REVERSED_LO=$0080  ;The bytes of the word are reversed. This flag is obsolete.
#IMAGE_FILE_32BIT_MACHINE=$0100      ;The computer supports 32-bit words.
#IMAGE_FILE_DEBUG_STRIPPED=$0200     ;Debugging information was removed and stored separately in another file.
#IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP=$0400;If the image is on removable media, copy it to and run it from the swap file.
#IMAGE_FILE_NET_RUN_FROM_SWAP=$0800      ;If the image is on the network, copy it to and run it from the swap file.
#IMAGE_FILE_SYSTEM=$1000                 ;The image is a system file.
#IMAGE_FILE_DLL=$2000                    ;The image is a DLL file. While it is an executable file, it cannot be run directly.
#IMAGE_FILE_UP_SYSTEM_ONLY=$4000         ;The file should be run only on a uniprocessor computer.
#IMAGE_FILE_BYTES_REVERSED_HI=$8000      ;The bytes of the word are reversed. This flag is obsolete.

;IMAGE_NT_HEADERS\OptionalHeader\Magic
#IMAGE_NT_OPTIONAL_HDR32_MAGIC = $10B;32-bit application
#IMAGE_NT_OPTIONAL_HDR64_MAGIC = $20B;64-bit application
#IMAGE_ROM_OPTIONAL_HDR_MAGIC = $107 ;ROM image

;IMAGE_NT_HEADERS\OptionalHeader\Subsystem
#IMAGE_SUBSYSTEM_UNKNOWN = 0;Unknown subsystem.
#IMAGE_SUBSYSTEM_NATIVE = 1 ;No subsystem required (device drivers and native system processes).
#IMAGE_SUBSYSTEM_WINDOWS_GUI = 2;Windows graphical user interface (GUI) subsystem.
#IMAGE_SUBSYSTEM_WINDOWS_CUI = 3;Windows character-mode user interface (CUI) subsystem.
#IMAGE_SUBSYSTEM_OS2_CUI = 5    ;OS/2 CUI subsystem.
#IMAGE_SUBSYSTEM_POSIX_CUI = 7  ;POSIX CUI subsystem.
#IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9;Windows CE system.
#IMAGE_SUBSYSTEM_EFI_APPLICATION = 10;Extensible Firmware Interface (EFI) application.
#IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11;EFI driver with boot services.
#IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12     ;EFI driver with run-time services.
#IMAGE_SUBSYSTEM_EFI_ROM = 13                ;EFI ROM image.
#IMAGE_SUBSYSTEM_XBOX = 14                   ;Xbox system.
#IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16;Boot application.

;IMAGE_NT_HEADERS\OptionalHeader\DllCharacteristics
#IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE=$0040;The DLL can be relocated at load time.
#IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY=$0080;Code integrity checks are forced. If you set this flag and a section contains only uninitialized data, set the PointerToRawData member of #IMAGE_SECTION_HEADER for that section to zero; otherwise, the image will fail to load because the digital signature cannot be verified.
#IMAGE_DLLCHARACTERISTICS_NX_COMPAT=$0100      ;The image is compatible with data execution prevention (DEP).
#IMAGE_DLLCHARACTERISTICS_NO_ISOLATION=$0200   ;The image is isolation aware, but should not be isolated.
#IMAGE_DLLCHARACTERISTICS_NO_SEH=$0400         ;The image does not use structured exception handling (SEH). No handlers can be called in this image.
#IMAGE_DLLCHARACTERISTICS_NO_BIND=$0800        ;Do not bind the image
#IMAGE_DLLCHARACTERISTICS_WDM_DRIVER=$2000     ;A WDM driver
#IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE=$8000;The image is terminal server aware.

;IMAGE_NT_HEADERS\OptionalHeader\DllCharacteristics
#IMAGE_DIRECTORY_ENTRY_EXPORT = 0
#IMAGE_DIRECTORY_ENTRY_IMPORT = 1
#IMAGE_DIRECTORY_ENTRY_RESOURCE   = 2
#IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3
#IMAGE_DIRECTORY_ENTRY_SECURITY   = 4
#IMAGE_DIRECTORY_ENTRY_BASERELOC = 5
#IMAGE_DIRECTORY_ENTRY_DEBUG = 6
#IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7 
#IMAGE_DIRECTORY_ENTRY_ARCHITECTURE   = 7 
#IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8
#IMAGE_DIRECTORY_ENTRY_TLS = 9
#IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10
#IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   = 11
#IMAGE_DIRECTORY_ENTRY_IAT = 12
#IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   = 13
#IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14

#IMAGE_ORDINAL_FLAG = $80000000
#IMAGE_ORDINAL_FLAGx64=$8000000000000000

#IMAGE_SCN_CNT_CODE = $00000020
#IMAGE_SCN_CNT_INITIALIZED_DATA = $00000040
#IMAGE_SCN_CNT_UNINITIALIZED_DATA = $00000080
#IMAGE_SCN_MEM_SHARED = $10000000
#IMAGE_SCN_MEM_EXECUTE = $20000000
#IMAGE_SCN_MEM_READ = $40000000
#IMAGE_SCN_MEM_WRITE = $80000000

#IMAGE_REL_BASED_ABSOLUTE = 0
#IMAGE_REL_BASED_HIGH = 1
#IMAGE_REL_BASED_LOW = 2
#IMAGE_REL_BASED_HIGHLOW = 3
#IMAGE_REL_BASED_HIGHADJ = 4
#IMAGE_REL_BASED_MIPS_JMPADDR = 5
#IMAGE_REL_BASED_DIR64 = 10

Structure IMAGE_IMPORT_DESCRIPTOR ; from winnt.h
  OriginalFirstThunk.l    
  TimeDateStamp.l
  ForwarderChain.l
  Name.l
  FirstThunk.l
EndStructure

Structure IMAGE_THUNK_DATA32 ; from winnt.h
  StructureUnion
    ForwarderString.l
    Function.l
    Ordinal.l
    AddressOfData.l
  EndStructureUnion       
EndStructure

Structure IMAGE_THUNK_DATA64 ; from winnt.h
  StructureUnion
    ForwarderString.q
    Function.q
    Ordinal.q
    AddressOfData.q
  EndStructureUnion       
EndStructure

Structure IMAGE_RESOURCE_DIRECTORY
  Characteristics.l;
  TimeDateStamp.l  ;
  MajorVersion.w   ;
  MinorVersion.w   ;
  NumberOfNamedEntries.w;
  NumberOfIdEntries.w   ;
EndStructure

Structure IMAGE_RESOURCE_DIRECTORY_ENTRY
  NameOffset.l;
  OffsetToData.l;
EndStructure

Structure IMAGE_RESOURCE_DATA_ENTRY
  OffsetToData.l;
  Size.l        ;
  CodePage.l    ;
  Reserved.l    ;
EndStructure

Structure IMAGE_RESOURCE_DIRECTORY_STRING
  Length.u
  ;   NameString.a[1]
EndStructure

Structure ImportFunctionList
  IMAGE_THUNK_DATA.q
  Ordinal.q
  FunctionName.s
EndStructure

Structure IMAGE_BASE_RELOCATION ; from winnt.h
  VirtualAddress.l
  SizeOfBlock.l
EndStructure

Structure IMAGE_IMPORT_DESCRIPTORList Extends IMAGE_IMPORT_DESCRIPTOR
  LibraryName.s; name of imported dll
  List ImportFunctionList.ImportFunctionList() ;list of imported function
EndStructure

Structure IMAGE_IMPORT_DESCRIPTORInfo
  List IMAGE_IMPORT_DESCRIPTORList.IMAGE_IMPORT_DESCRIPTORList()
EndStructure

Structure ExportFunctionNameListe
  FunctionName.s ; Function Name
  FunctionAddress.l ; Function Address
  Ordinale.w ; Function Ordinale 
EndStructure

Structure IMAGE_EXPORT_DIRECTORYInfo Extends IMAGE_EXPORT_DIRECTORY
  __File_OriginalDllName.s ;original dll name
  List ExportFunctionNameListe.ExportFunctionNameListe()
EndStructure

Structure ResourceSubDirectoryList Extends IMAGE_RESOURCE_DIRECTORY
  __File_ResourceDirectoryName.s; Resource Directory Name
  __File_ResourceDirectoryID.l;Resource Directory ID
  __File_ResourceOffset.l;Resource Offset
  OffsetToData.l;
  Size.l        ;
  CodePage.l    ;
EndStructure

Structure ResourceDirectoryList Extends IMAGE_RESOURCE_DIRECTORY
  __File_ResourceDirectoryName.s
  __File_ResourceDirectoryID.l
  __File_ResourceSubDirectoryCount.l
  List ResourceSubDirectoryList.ResourceSubDirectoryList()
EndStructure

Structure IMAGE_RESOURCE_DIRECTORYInfo Extends IMAGE_RESOURCE_DIRECTORY
  __File_ResourceDirectoryCount.l; number of Resource
  List ResourceDirectoryList.ResourceDirectoryList()
EndStructure

Structure IMAGE_SECTION_HEADERInfo Extends IMAGE_SECTION_HEADER
  __File_Selction_Name.s ; pe section name
EndStructure

Structure IMAGE_BASE_RELOCATIONInfo Extends IMAGE_BASE_RELOCATION
  List RelocationTypeList.unicode() ; Relocation
EndStructure

Structure PB_PEExplorer
  __File_OffsetEntryCode.l ; start code offset
  __File_ImageSize.l
  IMAGE_DOS_HEADER.IMAGE_DOS_HEADER
  IMAGE_NT_HEADERS64.IMAGE_NT_HEADERS64
  IMAGE_NT_HEADERS32.IMAGE_NT_HEADERS32
  List IMAGE_SECTION_HEADERList.IMAGE_SECTION_HEADERInfo()
  IMAGE_IMPORT_DESCRIPTORInfo.IMAGE_IMPORT_DESCRIPTORInfo
  IMAGE_EXPORT_DIRECTORYInfo.IMAGE_EXPORT_DIRECTORYInfo
  IMAGE_RESOURCE_DIRECTORYInfo.IMAGE_RESOURCE_DIRECTORYInfo
  List IMAGE_BASE_RELOCATIONList.IMAGE_BASE_RELOCATIONInfo()
EndStructure

Macro Resource_IsNameString(NameOffset);Gets a value indicating whether the directory name is a string.
  (NameOffset & $80000000)
EndMacro

Macro Resource_NameAddress(NameOffset);Gets an offset, relative to the beginning of the resource directory of the string, which is of type
  (NameOffset & $7FFFFFFF)
EndMacro

Macro Resource_IsDirectory(OffsetToData);Gets a value indicating whether the entry is a directory.
  (OffsetToData & $80000000)
EndMacro

Macro Resource_DirectoryAddress(OffsetToData);Offset to the child <see cref="IMAGE_RESOURCE_DIRECTORY"/> or <see cref="IMAGE_RESOURCE_DATA_ENTRY"/>
  (OffsetToData & $7FFFFFFF)
EndMacro

Macro Resource_IsDataEntry(tOffset);Gets a value indicating whether the child structure is a <see cref="IMAGE_RESOURCE_DATA_ENTRY"/> structure.
  Resource_IsNameString(tOffset) And Resource_IsDirectory(tOffset)
EndMacro

Procedure Pb_PEExplorer(PeFile_ID ,*iPB_PEExplorer.PB_PEExplorer); Get Pe info
  Protected tIMAGE_DOS_HEADER.IMAGE_DOS_HEADER
  Protected tIMAGE_NT_HEADERS64.IMAGE_NT_HEADERS64
  Protected tIMAGE_NT_HEADERS32.IMAGE_NT_HEADERS32
  Protected tIMAGE_SECTION_HEADER.IMAGE_SECTION_HEADER
  Protected tIMAGE_IMPORT_DESCRIPTOR.IMAGE_IMPORT_DESCRIPTOR
  Protected tIMAGE_THUNK_DATA32.IMAGE_THUNK_DATA32
  Protected tIMAGE_THUNK_DATA64.IMAGE_THUNK_DATA64
  Protected tIMAGE_EXPORT_DIRECTORY.IMAGE_EXPORT_DIRECTORY
  Protected tIMAGE_RESOURCE_DIRECTORY.IMAGE_RESOURCE_DIRECTORY
  Protected tIMAGE_RESOURCE_DIRECTORY_ENTRY.IMAGE_RESOURCE_DIRECTORY_ENTRY
  Protected tIMAGE_RESOURCE_DIRECTORY_STRING.IMAGE_RESOURCE_DIRECTORY_STRING
  Protected tChildIMAGE_RESOURCE_DIRECTORY.IMAGE_RESOURCE_DIRECTORY
  Protected tChildIMAGE_RESOURCE_DIRECTORY_ENTRY.IMAGE_RESOURCE_DIRECTORY_ENTRY
  Protected tChildI1MAGE_RESOURCE_DIRECTORY.IMAGE_RESOURCE_DIRECTORY
  Protected tChild1IMAGE_RESOURCE_DIRECTORY_ENTRY.IMAGE_RESOURCE_DIRECTORY_ENTRY
  Protected tIMAGE_RESOURCE_DATA_ENTRY.IMAGE_RESOURCE_DATA_ENTRY
  Protected tIMAGE_BASE_RELOCATION.IMAGE_BASE_RELOCATION,offsetReloc
  Protected.l i,inct,incid,incrd,o,z,ii.w,itr
  
  FileSeek(PeFile_ID,0)  
  ReadData(PeFile_ID,@tIMAGE_DOS_HEADER,SizeOf(IMAGE_DOS_HEADER));get IMAGE_DOS_HEADER 
  If tIMAGE_DOS_HEADER\e_magic <> #IMAGE_DOS_HEADER:ProcedureReturn 0:EndIf
  CopyMemory(@tIMAGE_DOS_HEADER,@*iPB_PEExplorer\IMAGE_DOS_HEADER,SizeOf(IMAGE_DOS_HEADER))
  
  FileSeek(PeFile_ID,tIMAGE_DOS_HEADER\e_lfanew)
  ReadData(PeFile_ID,@tIMAGE_NT_HEADERS32,SizeOf(IMAGE_NT_HEADERS32));get IMAGE_NT_HEADERS 
  If tIMAGE_NT_HEADERS32\Signature <> #IMAGE_NT_SIGNATURE:ProcedureReturn 0:EndIf
  CopyMemory(@tIMAGE_NT_HEADERS32,@*iPB_PEExplorer\IMAGE_NT_HEADERS32,SizeOf(IMAGE_NT_HEADERS32))
  
  Protected ImportVirtualAddress.l=tIMAGE_NT_HEADERS32\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_IMPORT]\VirtualAddress
  Protected ExportVirtualAddress.l= tIMAGE_NT_HEADERS32\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\VirtualAddress
  Protected ResourceVirtualAddress.l= tIMAGE_NT_HEADERS32\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_RESOURCE]\VirtualAddress
  Protected RelocVirtualAddress.l= tIMAGE_NT_HEADERS32\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_BASERELOC]\VirtualAddress
  
  Protected endOfImage.l
  
  Protected IMAGE_ORDINAL_FLAG.q = #IMAGE_ORDINAL_FLAG,SizeIMAGE_NT_HEADERS.l = SizeOf(IMAGE_NT_HEADERS32),SizeIMAGE_THUNK_DATA.l=SizeOf(IMAGE_THUNK_DATA32)
  If tIMAGE_NT_HEADERS32\OptionalHeader\Magic  = #IMAGE_NT_OPTIONAL_HDR64_MAGIC
    IMAGE_ORDINAL_FLAG = #IMAGE_ORDINAL_FLAGx64
    FileSeek(PeFile_ID,tIMAGE_DOS_HEADER\e_lfanew)
    ReadData(PeFile_ID,@tIMAGE_NT_HEADERS64,SizeOf(IMAGE_NT_HEADERS64))
    CopyMemory(@tIMAGE_NT_HEADERS64,@*iPB_PEExplorer\IMAGE_NT_HEADERS64,SizeOf(IMAGE_NT_HEADERS64))
    SizeIMAGE_NT_HEADERS = SizeOf(IMAGE_NT_HEADERS64)
    SizeIMAGE_THUNK_DATA = SizeOf(IMAGE_THUNK_DATA64)
    ImportVirtualAddress = tIMAGE_NT_HEADERS64\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_IMPORT]\VirtualAddress
    ExportVirtualAddress = tIMAGE_NT_HEADERS64\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\VirtualAddress
    ResourceVirtualAddress = tIMAGE_NT_HEADERS64\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_RESOURCE]\VirtualAddress
    RelocVirtualAddress = tIMAGE_NT_HEADERS64\OptionalHeader\DataDirectory[#IMAGE_DIRECTORY_ENTRY_BASERELOC]\VirtualAddress
  EndIf
  Protected tIMAGE_THUNK_DATA.Quad,iInitialOffset.l
  
  For i=0 To (tIMAGE_NT_HEADERS32\FileHeader\NumberOfSections-1);get all pe sections
    FileSeek(PeFile_ID,tIMAGE_DOS_HEADER\e_lfanew+SizeIMAGE_NT_HEADERS+ (SizeOf(IMAGE_SECTION_HEADER)*i))
    ReadData(PeFile_ID,@tIMAGE_SECTION_HEADER,SizeOf(IMAGE_SECTION_HEADER))
    With tIMAGE_SECTION_HEADER
      If \VirtualAddress 
        AddElement(*iPB_PEExplorer\IMAGE_SECTION_HEADERList())
        CopyMemory(@tIMAGE_SECTION_HEADER,@*iPB_PEExplorer\IMAGE_SECTION_HEADERList(),SizeOf(IMAGE_SECTION_HEADER))
        *iPB_PEExplorer\IMAGE_SECTION_HEADERList()\__File_Selction_Name = PeekS(@\SecName,8,#PB_Ascii)
        
        If *iPB_PEExplorer\__File_ImageSize < \PointerToRawData+\SizeOfRawData:*iPB_PEExplorer\__File_ImageSize= \PointerToRawData+\SizeOfRawData:EndIf
        
        If tIMAGE_NT_HEADERS32\OptionalHeader\Magic  = #IMAGE_NT_OPTIONAL_HDR64_MAGIC
          If \VirtualAddress <= tIMAGE_NT_HEADERS64\OptionalHeader\AddressOfEntryPoint And tIMAGE_NT_HEADERS64\OptionalHeader\AddressOfEntryPoint < \VirtualAddress + \SizeOfRawData
            *iPB_PEExplorer\__File_OffsetEntryCode=( tIMAGE_NT_HEADERS64\OptionalHeader\AddressOfEntryPoint-\VirtualAddress)+\PointerToRawData;file offset to entry code
          EndIf            
        Else
          If \VirtualAddress <= tIMAGE_NT_HEADERS32\OptionalHeader\AddressOfEntryPoint And tIMAGE_NT_HEADERS32\OptionalHeader\AddressOfEntryPoint < \VirtualAddress + \SizeOfRawData
            *iPB_PEExplorer\__File_OffsetEntryCode=( tIMAGE_NT_HEADERS32\OptionalHeader\AddressOfEntryPoint-\VirtualAddress)+\PointerToRawData;file offset to entry code
          EndIf
        EndIf
        
        If \VirtualAddress <= ImportVirtualAddress And \VirtualAddress+ \VirtualSize > ImportVirtualAddress ;import library address
          FileSeek(PeFile_ID,( ImportVirtualAddress-\VirtualAddress)+\PointerToRawData)
          ReadData(PeFile_ID,@tIMAGE_IMPORT_DESCRIPTOR,SizeOf(IMAGE_IMPORT_DESCRIPTOR))          
          While  tIMAGE_IMPORT_DESCRIPTOR\FirstThunk 
            FileSeek(PeFile_ID,tIMAGE_IMPORT_DESCRIPTOR\Name -(\VirtualAddress - \PointerToRawData))
            AddElement(*iPB_PEExplorer\IMAGE_IMPORT_DESCRIPTORInfo\IMAGE_IMPORT_DESCRIPTORList())
            CopyMemory(@tIMAGE_IMPORT_DESCRIPTOR,@*iPB_PEExplorer\IMAGE_IMPORT_DESCRIPTORInfo\IMAGE_IMPORT_DESCRIPTORList(),SizeOf(IMAGE_IMPORT_DESCRIPTOR))
            *iPB_PEExplorer\IMAGE_IMPORT_DESCRIPTORInfo\IMAGE_IMPORT_DESCRIPTORList()\LibraryName = ReadString(PeFile_ID); set library name
            iInitialOffset=tIMAGE_IMPORT_DESCRIPTOR\FirstThunk            
            If tIMAGE_IMPORT_DESCRIPTOR\OriginalFirstThunk
              iInitialOffset=tIMAGE_IMPORT_DESCRIPTOR\OriginalFirstThunk
            EndIf
            FileSeek(PeFile_ID,iInitialOffset -(\VirtualAddress - \PointerToRawData))
            ReadData(PeFile_ID,@tIMAGE_THUNK_DATA,SizeIMAGE_THUNK_DATA)
            inct=0
            While tIMAGE_THUNK_DATA\q
              AddElement(*iPB_PEExplorer\IMAGE_IMPORT_DESCRIPTORInfo\IMAGE_IMPORT_DESCRIPTORList()\ImportFunctionList())
              If tIMAGE_THUNK_DATA\q & IMAGE_ORDINAL_FLAG
                *iPB_PEExplorer\IMAGE_IMPORT_DESCRIPTORInfo\IMAGE_IMPORT_DESCRIPTORList()\ImportFunctionList()\Ordinal = tIMAGE_THUNK_DATA\q;is a ordinal function
              Else
                FileSeek(PeFile_ID,((tIMAGE_THUNK_DATA\q +2)-(\VirtualAddress - \PointerToRawData)))
                *iPB_PEExplorer\IMAGE_IMPORT_DESCRIPTORInfo\IMAGE_IMPORT_DESCRIPTORList()\ImportFunctionList()\FunctionName = ReadString(PeFile_ID);get function name
              EndIf
              *iPB_PEExplorer\IMAGE_IMPORT_DESCRIPTORInfo\IMAGE_IMPORT_DESCRIPTORList()\ImportFunctionList()\IMAGE_THUNK_DATA=tIMAGE_THUNK_DATA\q
              inct + SizeIMAGE_THUNK_DATA
              FileSeek(PeFile_ID,(iInitialOffset -(\VirtualAddress - \PointerToRawData))+inct)
              ReadData(PeFile_ID,@tIMAGE_THUNK_DATA,SizeIMAGE_THUNK_DATA)
            Wend
            incid+ SizeOf(IMAGE_IMPORT_DESCRIPTOR)
            FileSeek(PeFile_ID,(( ImportVirtualAddress-\VirtualAddress)+\PointerToRawData)+incid)
            ReadData(PeFile_ID,@tIMAGE_IMPORT_DESCRIPTOR,SizeOf(IMAGE_IMPORT_DESCRIPTOR))
          Wend
        EndIf
        
        If \VirtualAddress <= ExportVirtualAddress And \VirtualAddress+ \VirtualSize > ExportVirtualAddress ;Export function
          FileSeek(PeFile_ID,( ExportVirtualAddress-\VirtualAddress)+\PointerToRawData)
          ReadData(PeFile_ID,@tIMAGE_EXPORT_DIRECTORY,SizeOf(IMAGE_EXPORT_DIRECTORY))
          CopyMemory(@tIMAGE_EXPORT_DIRECTORY,@*iPB_PEExplorer\IMAGE_EXPORT_DIRECTORYInfo,SizeOf(IMAGE_EXPORT_DIRECTORY))
          FileSeek(PeFile_ID, (tIMAGE_EXPORT_DIRECTORY\Name-(\VirtualAddress - \PointerToRawData)))
          *iPB_PEExplorer\IMAGE_EXPORT_DIRECTORYInfo\__File_OriginalDllName = ReadString(PeFile_ID)            
          For o = 0 To tIMAGE_EXPORT_DIRECTORY\NumberOfNames-1
            AddElement( *iPB_PEExplorer\IMAGE_EXPORT_DIRECTORYInfo\ExportFunctionNameListe())
            FileSeek(PeFile_ID, (tIMAGE_EXPORT_DIRECTORY\AddressOfNames-(\VirtualAddress - \PointerToRawData))+(o*SizeOf(long)))
            FileSeek(PeFile_ID, ReadLong(PeFile_ID)-(\VirtualAddress - \PointerToRawData))
            *iPB_PEExplorer\IMAGE_EXPORT_DIRECTORYInfo\ExportFunctionNameListe()\FunctionName  = ReadString(PeFile_ID)
            FileSeek(PeFile_ID, (tIMAGE_EXPORT_DIRECTORY\AddressOfNameOrdinals-(\VirtualAddress - \PointerToRawData))+(o*SizeOf(word)))
            *iPB_PEExplorer\IMAGE_EXPORT_DIRECTORYInfo\ExportFunctionNameListe()\Ordinale = ReadWord(PeFile_ID)
            FileSeek(PeFile_ID, (tIMAGE_EXPORT_DIRECTORY\AddressOfFunctions-(\VirtualAddress - \PointerToRawData))+
                                (*iPB_PEExplorer\IMAGE_EXPORT_DIRECTORYInfo\ExportFunctionNameListe()\Ordinale*SizeOf(long)))
            *iPB_PEExplorer\IMAGE_EXPORT_DIRECTORYInfo\ExportFunctionNameListe()\FunctionAddress=  ReadLong(PeFile_ID)
          Next
        EndIf
        
        If \VirtualAddress <= ResourceVirtualAddress And \VirtualAddress+ \VirtualSize > ResourceVirtualAddress
          FileSeek(PeFile_ID,ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)
          ReadData(PeFile_ID,@tIMAGE_RESOURCE_DIRECTORY,SizeOf(IMAGE_RESOURCE_DIRECTORY))
          CopyMemory(@tIMAGE_RESOURCE_DIRECTORY,@*iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo,SizeOf(IMAGE_RESOURCE_DIRECTORY))      
          *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\__File_ResourceDirectoryCount = (tIMAGE_RESOURCE_DIRECTORY\NumberOfIdEntries+tIMAGE_RESOURCE_DIRECTORY\NumberOfNamedEntries)-1        
          For o=0 To (tIMAGE_RESOURCE_DIRECTORY\NumberOfIdEntries+tIMAGE_RESOURCE_DIRECTORY\NumberOfNamedEntries)-1        
            FileSeek(PeFile_ID,(ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+SizeOf(IMAGE_RESOURCE_DIRECTORY)+(SizeOf(IMAGE_RESOURCE_DIRECTORY_ENTRY)*o))
            ReadData(PeFile_ID,@tIMAGE_RESOURCE_DIRECTORY_ENTRY,SizeOf(IMAGE_RESOURCE_DIRECTORY_ENTRY))
            AddElement(*iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList())
            If Resource_IsNameString(tIMAGE_RESOURCE_DIRECTORY_ENTRY\NameOffset)
              FileSeek(PeFile_ID,((ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+Resource_NameAddress(tIMAGE_RESOURCE_DIRECTORY_ENTRY\NameOffset)))
              ReadData(PeFile_ID,@tIMAGE_RESOURCE_DIRECTORY_STRING,SizeOf(IMAGE_RESOURCE_DIRECTORY_STRING))
              *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\__File_ResourceDirectoryName = ReadString(PeFile_ID,#PB_Unicode,tIMAGE_RESOURCE_DIRECTORY_STRING\Length)
            Else
              *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\__File_ResourceDirectoryID =   (tIMAGE_RESOURCE_DIRECTORY_ENTRY\NameOffset)
            EndIf
            If Resource_IsDirectory(tIMAGE_RESOURCE_DIRECTORY_ENTRY\OffsetToData)
              FileSeek(PeFile_ID,((ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+Resource_DirectoryAddress(tIMAGE_RESOURCE_DIRECTORY_ENTRY\OffsetToData)))
              ReadData(PeFile_ID,@tChildIMAGE_RESOURCE_DIRECTORY,SizeOf(IMAGE_RESOURCE_DIRECTORY))
              CopyMemory(@tChildIMAGE_RESOURCE_DIRECTORY,@*iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList(),SizeOf(IMAGE_RESOURCE_DIRECTORY))      
              *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\__File_ResourceSubDirectoryCount = tChildIMAGE_RESOURCE_DIRECTORY\NumberOfIdEntries+tChildIMAGE_RESOURCE_DIRECTORY\NumberOfNamedEntries
              For z=0 To (tChildIMAGE_RESOURCE_DIRECTORY\NumberOfIdEntries+tChildIMAGE_RESOURCE_DIRECTORY\NumberOfNamedEntries)-1        
                AddElement(*iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\ResourceSubDirectoryList())
                FileSeek(PeFile_ID,(ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+SizeOf(IMAGE_RESOURCE_DIRECTORY)+Resource_DirectoryAddress(tIMAGE_RESOURCE_DIRECTORY_ENTRY\OffsetToData) +(SizeOf(IMAGE_RESOURCE_DIRECTORY_ENTRY)*z))
                ReadData(PeFile_ID,@tChildIMAGE_RESOURCE_DIRECTORY_ENTRY,SizeOf(IMAGE_RESOURCE_DIRECTORY_ENTRY))
                If Resource_IsNameString(tChildIMAGE_RESOURCE_DIRECTORY_ENTRY\NameOffset)
                  FileSeek(PeFile_ID,((ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+Resource_NameAddress(tChildIMAGE_RESOURCE_DIRECTORY_ENTRY\NameOffset)))
                  ReadData(PeFile_ID,@tIMAGE_RESOURCE_DIRECTORY_STRING,SizeOf(IMAGE_RESOURCE_DIRECTORY_STRING))
                  *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\ResourceSubDirectoryList()\__File_ResourceDirectoryName = ReadString(PeFile_ID,#PB_Unicode,tIMAGE_RESOURCE_DIRECTORY_STRING\Length)
                Else
                  *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\ResourceSubDirectoryList()\__File_ResourceDirectoryID = ( tChildIMAGE_RESOURCE_DIRECTORY_ENTRY\NameOffset)
                EndIf           
                If Resource_IsDirectory(tChildIMAGE_RESOURCE_DIRECTORY_ENTRY\OffsetToData)
                  FileSeek(PeFile_ID,((ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+Resource_DirectoryAddress(tChildIMAGE_RESOURCE_DIRECTORY_ENTRY\OffsetToData)))
                  ReadData(PeFile_ID,@tChildI1MAGE_RESOURCE_DIRECTORY,SizeOf(IMAGE_RESOURCE_DIRECTORY))
                  CopyMemory(@tChildI1MAGE_RESOURCE_DIRECTORY,@*iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\ResourceSubDirectoryList(),SizeOf(IMAGE_RESOURCE_DIRECTORY))      
                  FileSeek(PeFile_ID,(ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+SizeOf(IMAGE_RESOURCE_DIRECTORY)+Resource_DirectoryAddress(tChildIMAGE_RESOURCE_DIRECTORY_ENTRY\OffsetToData))
                  ReadData(PeFile_ID,@tChild1IMAGE_RESOURCE_DIRECTORY_ENTRY,SizeOf(IMAGE_RESOURCE_DIRECTORY_ENTRY))
                  
                  FileSeek(PeFile_ID,((ResourceVirtualAddress-\VirtualAddress+\PointerToRawData)+Resource_DirectoryAddress(tChild1IMAGE_RESOURCE_DIRECTORY_ENTRY\OffsetToData)))
                  ReadData(PeFile_ID,@tIMAGE_RESOURCE_DATA_ENTRY,SizeOf(IMAGE_RESOURCE_DATA_ENTRY))
                  
                  *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\ResourceSubDirectoryList()\__File_ResourceOffset = (Resource_DirectoryAddress(tIMAGE_RESOURCE_DATA_ENTRY\OffsetToData)-\VirtualAddress)+\PointerToRawData ;imagebas + OffsetToData
                  *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\ResourceSubDirectoryList()\Size = tIMAGE_RESOURCE_DATA_ENTRY\Size
                  *iPB_PEExplorer\IMAGE_RESOURCE_DIRECTORYInfo\ResourceDirectoryList()\ResourceSubDirectoryList()\CodePage = tIMAGE_RESOURCE_DATA_ENTRY\CodePage
                  
                EndIf
              Next
            EndIf
          Next
        EndIf
        
        If \VirtualAddress <= RelocVirtualAddress And \VirtualAddress+ \VirtualSize > RelocVirtualAddress ;Relec section
          FileSeek(PeFile_ID,( RelocVirtualAddress-\VirtualAddress)+\PointerToRawData)
          ReadData(PeFile_ID,@tIMAGE_BASE_RELOCATION,SizeOf(IMAGE_BASE_RELOCATION))
          
          While tIMAGE_BASE_RELOCATION\VirtualAddress
            AddElement(*iPB_PEExplorer\IMAGE_BASE_RELOCATIONList())
            CopyMemory(@tIMAGE_BASE_RELOCATION,@*iPB_PEExplorer\IMAGE_BASE_RELOCATIONList(),SizeOf(IMAGE_BASE_RELOCATION))
            FileSeek(PeFile_ID,(( RelocVirtualAddress-\VirtualAddress)+\PointerToRawData)+incrd+SizeOf(IMAGE_BASE_RELOCATION))
            offsetReloc=ReadUnicodeCharacter(PeFile_ID)
            
            For itr=1 To (tIMAGE_BASE_RELOCATION\SizeOfBlock-SizeOf(IMAGE_BASE_RELOCATION))/SizeOf(Word) 
              AddElement(*iPB_PEExplorer\IMAGE_BASE_RELOCATIONList()\RelocationTypeList())
              *iPB_PEExplorer\IMAGE_BASE_RELOCATIONList()\RelocationTypeList()\u = offsetReloc
              
              FileSeek(PeFile_ID,(( RelocVirtualAddress-\VirtualAddress)+\PointerToRawData)+incrd+SizeOf(IMAGE_BASE_RELOCATION)+ (itr * SizeOf(Unicode)))
              offsetReloc=ReadUnicodeCharacter(PeFile_ID)
            Next
            
            incrd+ tIMAGE_BASE_RELOCATION\SizeOfBlock
            FileSeek(PeFile_ID,(( RelocVirtualAddress-\VirtualAddress)+\PointerToRawData)+incrd)
            ReadData(PeFile_ID,@tIMAGE_BASE_RELOCATION,SizeOf(IMAGE_BASE_RELOCATION))
          Wend
          
        EndIf
        
      EndIf
    EndWith
  Next
  
  ProcedureReturn 1
EndProcedure

DisableExplicit


full code :
https://pastebin.com/embed_iframe/RYFT6U7E

Enjoy and have fun :wink:
interested in Cybersecurity..
Denis
Enthusiast
Enthusiast
Posts: 704
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Re: analyze pe "Executable file" x32/x64

Post by Denis »

Slt CELTIC88,

nice code!
A+
Denis
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 794
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

Re: analyze pe "Executable file" x32/x64

Post by Zebuddi123 »

@Celtic88 Very nice thanks for sharing :)

Zebuddi.
malleo, caput, bang. Ego, comprehendunt in tempore
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: analyze pe "Executable file" x32/x64

Post by RSBasic »

Thanks for sharing, very good.
Image
Image
User avatar
CELTIC88
Enthusiast
Enthusiast
Posts: 154
Joined: Thu Sep 17, 2015 3:39 pm

Re: analyze pe "Executable file" x32/x64

Post by CELTIC88 »

slt Dr @Denis ,contente de te revoir ici :)

thank you for your comments :)
interested in Cybersecurity..
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: analyze pe "Executable file" x32/x64

Post by Kwai chang caine »

Very nice and always also "simple" :shock: code :lol:
Works very welle here on W10 x86 / v5.62 x86
Thanks a lot for this splendid code 8)
ImageThe happiness is a road...
Not a destination
Opcode
Enthusiast
Enthusiast
Posts: 137
Joined: Thu Jul 18, 2013 4:58 am

Re: analyze pe "Executable file" x32/x64

Post by Opcode »

Was looking for something that could extract PE header info, thanks! :D
User avatar
CELTIC88
Enthusiast
Enthusiast
Posts: 154
Joined: Thu Sep 17, 2015 3:39 pm

Re: analyze pe "Executable file" x32/x64

Post by CELTIC88 »

hi :)

example to use plugins

Code: Select all

EnableExplicit

;compile to dll and save to \Plugins\yourdll.dll

IncludeFile "Pb_PeExplorer.Pbi"

Macro HiWord(a)
  (a>>16 & $ffff)
EndMacro

Macro LowWord(a)
  (a & $ffff)
EndMacro

Global DllModuleHandle
Global *CurrentFileLocation
Global Cwhwnd
Global MenuItemName.s = "PureBasic Studio Detector" ;plugin name
Global MenuItemId.l
Global hWindowsHook

Global PbDll_signatures.s = "83 7C 24 08 01 75 ? 8B 44 24 04 A3 ? ? ? 10 E8"; signature  purebasic pe
Global PbEXE_signatures.s = "68 ? ? 00 00 68 00 00 00 00 68 ? ? ? 00 E8 ? ? ? 00 83 C4 0C 68 00 00 00 00 E8 ? ? ? 00 A3 ? ? ? 00 68 00 00 00 00 68 00 10 00 00 68 00 00 00 00 E8 ? ? ? 00 A3" ; signature de pb exe
                                                                                                                                                                                              ;Les '?' son des bytes con pas une valeur fixe

Structure Pb_DataArray
  DataArray.a[0]
EndStructure

Procedure PE_Detect_signatures(ID_File,SizeFile,OffsetFile,signatures.s,EntryPoint_only.b=1) ;get pe signature
  FileSeek(ID_File ,OffsetFile)
  Protected signature_Size = CountString(signatures," ")
  If signature_Size = 0 Or SizeFile-OffsetFile < signature_Size:ProcedureReturn 0:EndIf
  Protected Mem_tmpSize = (1024*1024) + signature_Size
  If Mem_tmpSize > SizeFile :Mem_tmpSize = SizeFile:EndIf
  Protected *Pb_DataArray.Pb_DataArray = AllocateMemory(Mem_tmpSize)
  If Not *Pb_DataArray:ProcedureReturn 0:EndIf
  ReadData(ID_File ,*Pb_DataArray,Mem_tmpSize)
  ;ShowMemoryViewer(*Pb_DataArray,signature_Size)
  Protected Sig_Ok.b = 1,p,Cpos = Mem_tmpSize
  Protected Hex.s = StringField(signatures,1," ")
  
  If EntryPoint_only
    For p = 0 To signature_Size -1
      If Hex <> "?"
        ;Debug Hex(*Pb_DataArray\DataArray[p])
        If RSet (Hex(*Pb_DataArray\DataArray[p]),2,"0") <> Hex
          Sig_Ok = 0
          Break
        EndIf
      EndIf
      Hex = StringField(signatures,p+2," ")
    Next
  Else
    
    While SizeFile > 0
      
      If Cpos + Mem_tmpSize > SizeFile :Mem_tmpSize = SizeFile - Cpos:EndIf
      FileSeek(ID_File ,Cpos - signature_Size)
      ReadData(ID_File ,*Pb_DataArray,Mem_tmpSize)
      
      Cpos + Mem_tmpSize
      SizeFile - Mem_tmpSize
    Wend
    
  EndIf
  ProcedureReturn Sig_Ok
EndProcedure

Procedure Purebasic_Detector(*pCurrentFileLocation)
  Protected PB_PEExplorer.PB_PEExplorer
  Protected ExeFile.s = PeekS(*pCurrentFileLocation)
  Protected ID_File = OpenFile(#PB_Any,ExeFile)  
  If ID_File    
    If Pb_PEExplorer(ID_File ,@PB_PEExplorer)
      
      If PB_PEExplorer\IMAGE_NT_HEADERS32\OptionalHeader\Magic  = #IMAGE_NT_OPTIONAL_HDR64_MAGIC
        
      Else
        If PB_PEExplorer\IMAGE_NT_HEADERS32\FileHeader\Characteristics &#IMAGE_FILE_DLL = #IMAGE_FILE_DLL;"Image is a DLL"
          If PE_Detect_signatures(ID_File,PB_PEExplorer\__File_ImageSize,PB_PEExplorer\__File_OffsetEntryCode,PbDll_signatures) = 1
            MessageRequester("","Is Pb Studio")
          EndIf
        ElseIf PB_PEExplorer\IMAGE_NT_HEADERS32\FileHeader\Characteristics &#IMAGE_FILE_EXECUTABLE_IMAGE = #IMAGE_FILE_EXECUTABLE_IMAGE; "Image is a EXE"
          If PE_Detect_signatures(ID_File,PB_PEExplorer\__File_ImageSize,PB_PEExplorer\__File_OffsetEntryCode,PbEXE_signatures) = 1
            MessageRequester("","Is Pb Studio")
          EndIf
        EndIf          
        
      EndIf
      
      
    EndIf
    CloseFile(ID_File)
  EndIf
EndProcedure

Procedure _HookProc(code.l, wParam.l, lParam.l)
  Protected *msg.MSG = lParam
  With *msg
    If Cwhwnd=\hwnd And 
       \message = #WM_COMMAND And 
       HiWord(\wParam)=0 And 
       LowWord(\wParam)=MenuItemId      
      
      If *CurrentFileLocation
        Purebasic_Detector(*CurrentFileLocation)
      EndIf
      
    EndIf
  EndWith
  ProcedureReturn CallNextHookEx_(@_HookProc(), code, wParam, lParam)
EndProcedure

ProcedureDLL AttachProcess(Instance)
  DllModuleHandle = Instance
EndProcedure

ProcedureDLL DetachProcess(Instance)
  UnhookWindowsHookEx_(hWindowsHook) ;free
EndProcedure

ProcedureDLL PeExplorer_Plugin_Ini(Hwindow,*pCurrentFileLocation); Hwindow = main window hwnd , *pCurrentFileLocation = point to exe full path
  *CurrentFileLocation=*pCurrentFileLocation
  Protected hm  = GetMenu_(Hwindow)
  Protected hPlug = GetSubMenu_(hm,1)
  Protected iMENUITEMINFO.MENUITEMINFO\cbSize = SizeOf(MENUITEMINFO)
  With  iMENUITEMINFO
    \hSubMenu=hPlug
    \fMask=#MIIM_ID|#MIIM_STRING;|#MIIM_SUBMENU
    \fType = #MFT_STRING
    \dwTypeData = @MenuItemName
    \wID=GetMenuItemCount_(hPlug) +999
    MenuItemId=\wID
  EndWith
  If InsertMenuItem_(hPlug,1,1,@iMENUITEMINFO)
    Cwhwnd=Hwindow
    hWindowsHook = SetWindowsHookEx_(#WH_GETMESSAGE,@_HookProc(),DllModuleHandle,GetCurrentThreadId_())
    ProcedureReturn hWindowsHook
  EndIf
EndProcedure
interested in Cybersecurity..
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: analyze pe "Executable file" x32/x64

Post by Kwai chang caine »

WAouuh !!! works like a charm your plugin detector :D
Thanks a lot for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply