Ermitteln, EXE-Datei 32- oder 64-Bit ist

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Sicro
Beiträge: 963
Registriert: 11.08.2005 19:08
Kontaktdaten:

Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Sicro »

Hallo zusammen,

ich suche eine Möglichkeit, wie ich ermitteln kann, ob es sich
bei einer EXE-Datei um eine 32- oder 64-Bit handelt.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von ts-soft »

Das kann man im Taskmanager sehen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von STARGÅTE »

Code: Alles auswählen

CompilerSelect #PB_Compiler_Processor
  CompilerCase #PB_Processor_x86
    MessageRequester("Prozessor", "x86 Prozessor-Architektur (auch IA-32 oder x86-32 genannt)")
  CompilerCase #PB_Processor_x64
    MessageRequester("Prozessor", "x86-64 Prozessor-Architektur (auch x64, AMD64 oder Intel64 genannt)")
  CompilerCase #PB_Processor_PowerPC
    MessageRequester("Prozessor", "PowerPC Prozessor-Architektur")
  CompilerCase #PB_Processor_mc68000
    MessageRequester("Prozessor", "Motorola 68000 Prozessor-Architektur")
CompilerEndSelect
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Sicro
Beiträge: 963
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Sicro »

Danke euch beiden. Diese Sachen sind mir jedoch bekannt.

Ich suche eine Möglichkeit, dies mit PureBasic zu ermitteln.
Dabei sollen die Informationen aus der Datei ausgelesen werden.
Sorry, das dies nicht aus meinem ersten Beitrag herauszulesen war.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Helle »

Also sowas:

Code: Alles auswählen

;- Strukturen (in PB integriert)
I_D_H.IMAGE_DOS_HEADER
I_NT_H.IMAGE_NT_HEADERS

#IMAGE_NT_SIGNATURE               = $00004550    ;"PE  "
#IMAGE_FILE_MACHINE_I386          = $014C        ;32-Bit-File
#IMAGE_FILE_MACHINE_AMD64	        = $8664        ;64-Bit-File

If OpenWindow(0, 0, 0, 500, 300, "Wähle File aus !", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
  ExplorerTreeGadget(0, 10, 10, 480, 280, "*.exe", #PB_Explorer_NoDriveRequester)
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_CloseWindow
      End
    EndIf
  Until EventType() = #PB_EventType_LeftDoubleClick And GetGadgetState(0) = #PB_Explorer_File

  File$ = GetGadgetText(0)
  OpenFile(0, File$)
  LF = Lof(0)
  ReadData(0, @I_D_H, SizeOf(I_D_H))

  New_File_Header = I_D_H\e_lfanew
  If New_File_Header - 8 > LF
    MessageRequester("Fehler !", File$ + " ist kein File im PE-File-Format !")
    End  
  EndIf   

  FileSeek(0, New_File_Header)
  ReadData(0, @I_NT_H, SizeOf(I_NT_H))
  CloseFile(0)
  If I_NT_H\Signature <> #IMAGE_NT_SIGNATURE     ;Test auf "PE  "
    MessageRequester("Error !", File$ + " ist kein File im PE-File-Format !")
    End
  EndIf

  Select (I_NT_H\FileHeader\Machine) & $FFFF
    Case #IMAGE_FILE_MACHINE_I386
      File$ + " ist ein 32-Bit-File!"
    Case #IMAGE_FILE_MACHINE_AMD64
      File$ + " ist ein 64-Bit-File!"  
    Default 
      File$ + " ist kein File im 32- oder 64-Bit-Windows-Format !"
  EndSelect
  MessageRequester("Ergebnis", File$)

EndIf
Gruß
Helle
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Thorium »

Das Machine Feld sollte dafür nicht verwendet werden. Es gibt durchaus weitere 64bit Architekturen neben AMD64, die vom PE unterstützt werden, z.b. IA64

Für eine zuverlässige Prüfung sollte die Magic des Optional Headers geprüft werden, ist das PE 64bit ist die Magic IMAGE_NT_OPTIONAL_HDR64_MAGIC.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Thorium »

Hier ist ein unfertiger alter Code von mir, der dazu gedacht war Code in ein Executable zu injizieren, welcher eine DLL beim Programmstart lädt.
Der liest eine Infos aus.

Code: Alles auswählen

;/-----------------------------------\
;| Ladon PE-Injector                 |
;| Anti-Cheating-System              |
;|                                   |
;| Version 0.01                      |
;| Stand: 07.12.2007                 |
;|                                   |
;| by Janos David Ommert aka Thorium |
;| PureBasic 4.10 Code               |
;\-----------------------------------/

EnableExplicit

#IMAGE_DOS_HEADER = $5A4D
#IMAGE_NT_SIGNATURE = $00004550

#IMAGE_FILE_EXECUTABLE_IMAGE = $2
#IMAGE_FILE_DLL = $2000

#IMAGE_FILE_MACHINE_I386 = $14C
#IMAGE_FILE_MACHINE_I486 = $14D
#IMAGE_FILE_MACHINE_I586 = $14E
#IMAGE_FILE_MACHINE_IA64 = $200
#IMAGE_FILE_MACHINE_AMD64 = $8664
#IMAGE_FILE_MACHINE_ALPHA = $184
#IMAGE_FILE_MACHINE_ARM = $1C0
#IMAGE_FILE_MACHINE_ALPHA64	= $284
#IMAGE_FILE_MACHINE_M68K = $268
#IMAGE_FILE_MACHINE_MIPS16 = $266
#IMAGE_FILE_MACHINE_MIPSFPU	= $366
#IMAGE_FILE_MACHINE_MIPSFPU16	= $466
#IMAGE_FILE_MACHINE_POWERPC	= $1F0
#IMAGE_FILE_MACHINE_R3000_BE = $160
#IMAGE_FILE_MACHINE_R3000	= $162
#IMAGE_FILE_MACHINE_R4000	= $166
#IMAGE_FILE_MACHINE_R10000	= $168
#IMAGE_FILE_MACHINE_SH3	= $1A2
#IMAGE_FILE_MACHINE_SH4	= $1A6
#IMAGE_FILE_MACHINE_THUMB	= $1C2	

#IMAGE_NT_OPTIONAL_HDR32_MAGIC = $10B
#IMAGE_NT_OPTIONAL_HDR64_MAGIC = $20B
#IMAGE_ROM_OPTIONAL_HDR_MAGIC = $107

#IMAGE_SCN_MEM_WRITE = $80000000

#IMAGE_SUBSYSTEM_NATIVE = 1
#IMAGE_SUBSYSTEM_WINDOWS_GUI = 2
#IMAGE_SUBSYSTEM_WINDOWS_CUI = 3
#IMAGE_SUBSYSTEM_OS2_CUI = 5
#IMAGE_SUBSYSTEM_POSIX_CUI = 7
#IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9
#IMAGE_SUBSYSTEM_EFI_APPLICATION = 10
#IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11
#IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12
#IMAGE_SUBSYSTEM_EFI_ROM = 13
#IMAGE_SUBSYSTEM_XBOX = 14
#IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16

#IMAGE_ORDINAL_FLAG32 = $80000000

Structure IMAGE_OPTIONAL_HEADER32
  MajorLinkerVersion.b
  MinorLinkerVersion.b
  SizeOfCode.l
  SizeOfInitializedData.l
  SizeOfUninitializedData.l
  AddressOfEntryPoint.l
  BaseOfCode.l
  BaseOfData.l
  ImageBase.l
  SectionAlignment.l
  FileAlignment.l
  MajorOperatingSystemVersion.w
  MinorOperatingSystemVersion.w
  MajorImageVersion.w
  MinorImageVersion.w
  MajorSubsystemVersion.w
  MinorSubsystemVersion.w
  Win32VersionValue.l
  SizeOfImage.l
  SizeOfHeaders.l
  CheckSum.l
  Subsystem.w
  DllCharacteristics.w
  SizeOfStackReserve.l
  SizeOfStackCommit.l
  SizeOfHeapReserve.l
  SizeOfHeapCommit.l
  LoaderFlags.l
  NumberOfRvaAndSizes.l
EndStructure

Structure IMAGE_OPTIONAL_HEADER64
  MajorLinkerVersion.b
  MinorLinkerVersion.b
  SizeOfCode.l
  SizeOfInitializedData.l
  SizeOfUninitializedData.l
  AddressOfEntryPoint.l
  BaseOfCode.l
  BaseOfData.l
  ImageBase.q
  SectionAlignment.l
  FileAlignment.l
  MajorOperatingSystemVersion.w
  MinorOperatingSystemVersion.w
  MajorImageVersion.w
  MinorImageVersion.w
  MajorSubsystemVersion.w
  MinorSubsystemVersion.w
  Win32VersionValue.l
  SizeOfImage.l
  SizeOfHeaders.l
  CheckSum.l
  Subsystem.w
  DllCharacteristics.w
  SizeOfStackReserve.q
  SizeOfStackCommit.q
  SizeOfHeapReserve.q
  SizeOfHeapCommit.q
  LoaderFlags.l
  NumberOfRvaAndSizes.l
EndStructure

Structure IMAGE_SECTION_HEADER
  Name.s{8}
  VirtualSize.l
  VirtualAddress.l
  SizeOfRawData.l
  PointerToRawData.l
  PointerToRelocations.l
  PointerToLinenumbers.l
  NumberOfRelocations.w
  NumberOfLinenumbers.w
  Characteristics.l
EndStructure

Structure IMAGE_IMPORT_DESCRIPTOR
  Characteristics.l
  TimeDateStamp.l
  ForwarderChain.l
  Name1.l
  FirstThunk.l
EndStructure

Procedure Exit()
  Define.s KeyPressed

  PrintN("")
  PrintN("Press any key to end program.")
  Repeat
    Delay(20)
    KeyPressed = Inkey()
    If KeyPressed <> Chr(0)
      End
    EndIf
  ForEver
  End

EndProcedure

Procedure NoPE()

  PrintN("")
  PrintN("Error: File is no PE (Portable Executable).")
  Exit()

EndProcedure

Define.s PEFileName,KeyPressed
Define.l FileLen,OrigFileBuffer,NewFileBuffer,NtHeaderOffset,CPU,ImageFormat,i,CodeSectionIndex,ImportSectionIndex,LoadLibraryAImportPointer,ImportRVA,CompCodeSectionBuffer,CompCodeSectionSize,LoaderCodeBuffer,Position
Define.IMAGE_FILE_HEADER NtFileHeader
Define.IMAGE_OPTIONAL_HEADER32 NtOptionalHeader32
Define.IMAGE_OPTIONAL_HEADER64 NtOptionalHeader64
Define.IMAGE_IMPORT_DESCRIPTOR ImportDescriptor

Dim NtDataDirectory.IMAGE_DATA_DIRECTORY(0)
Dim SectionHeader.IMAGE_SECTION_HEADER(0)

OpenConsole()
ConsoleTitle("Ladon PE-Injector")

PrintN("Ladon PE-Injector v0.01")
PrintN("")
PrintN("Use this tool to inject the Ladon Loader into a Portable Executable file.")
PrintN("Filesize of the target will not increase!")
PrintN("Make sure the Ladon Loader is the first PE manipulator you use on the target.")
PrintN("This is absolute necessary: After compiling the EXE, first inject the Ladon Loader and than any copyprotection, PE protector or EXE compressor.")
PrintN("")

Print("Input filename: ")
PEFileName = Input()

;LoadLibraryA für Test importieren
OpenLibrary(1,"kernel32.dll")

If ReadFile(1,PEFileName) = 0
  PrintN("Error: Can't open file.")
Else

  ;Länge der Datei prüfen
  FileLen = Lof(1)
  If FileLen < 512
    NoPE()
  EndIf
  
  ;einlesen der Datei
  PrintN("")
  PrintN("loading file...")
  OrigFileBuffer = AllocateMemory(FileLen)
  ReadData(1,OrigFileBuffer,FileLen)
  CloseFile(1)
  PrintN("done")
  
  ;analysieren der Datei
  PrintN("")
  PrintN("analysing file...")
  
  ;ist es eine DOS-EXE?
  If PeekW(OrigFileBuffer) <> #IMAGE_DOS_HEADER
    NoPE()
  EndIf
  
  ;Offset des NT-Headers auslesen
  NtHeaderOffset = PeekL(OrigFileBuffer + 60)
  If NtHeaderOffset > FileLen - 4
    NoPE()
  EndIf
  
  ;ist es eine PE-EXE?
  If PeekL(OrigFileBuffer + NtHeaderOffset) <> #IMAGE_NT_SIGNATURE
    NoPE()
  EndIf
  
  ;einlesen des NT-File-Headers
  CopyMemory(OrigFileBuffer + NtHeaderOffset + 4,NtFileHeader,SizeOf(IMAGE_FILE_HEADER))
  
  ;ist Datei eine DLL?
  If NtFileHeader\Characteristics & #IMAGE_FILE_DLL = #IMAGE_FILE_DLL
    PrintN("")
    PrintN("File is a DLL. The Ladon Loader can't be injected into DLL's.")
    Exit()
  EndIf
  
  ;ist die Datei ein stand alone executable?
  If NtFileHeader\Characteristics & #IMAGE_FILE_EXECUTABLE_IMAGE <> #IMAGE_FILE_EXECUTABLE_IMAGE
    PrintN("")
    PrintN("File is not a stand alone executable.")
    PrintN("Please link it to a stand alone executable.")
    Exit()
  EndIf  
  PrintN("File is a stand alone executable.")

  ;für welche CPU ist die Datei vorgesehen?
  Print("CPU executable was compiled for: ")
  Select $0000FFFF & NtFileHeader\Machine
    Case #IMAGE_FILE_MACHINE_I386
      CPU = 1
      PrintN("80386 (386er)")
    Case #IMAGE_FILE_MACHINE_I486
      CPU = 1
      PrintN("80486 (486er)")
    Case #IMAGE_FILE_MACHINE_I586
      CPU = 1
      PrintN("80586 (Pentium)")
    Case #IMAGE_FILE_MACHINE_IA64
      CPU = 2
      PrintN("IA64 (Intel 64bit)")
    Case #IMAGE_FILE_MACHINE_AMD64
      CPU = 2
      PrintN("AMD64 or EM64T (AMD 64bit)")
    Case #IMAGE_FILE_MACHINE_ALPHA
      PrintN("Alpha AXP")
    Case #IMAGE_FILE_MACHINE_ALPHA64
      PrintN("Alpha AXP 64bit")
    Case #IMAGE_FILE_MACHINE_ARM
      PrintN("ARM")
    Case #IMAGE_FILE_MACHINE_M68K
      PrintN("Motorola 68000 series")
    Case #IMAGE_FILE_MACHINE_MIPS16
      PrintN("MIPS16")
    Case #IMAGE_FILE_MACHINE_MIPSFPU
      PrintN("MIPS with FPU")
    Case #IMAGE_FILE_MACHINE_MIPSFPU16
      PrintN("MIPS16 with FPU")
    Case #IMAGE_FILE_MACHINE_POWERPC
      PrintN("Power PC")
    Case #IMAGE_FILE_MACHINE_R3000_BE
      PrintN("R3000 processor, big endian")
    Case #IMAGE_FILE_MACHINE_R3000
      PrintN("R3000 processor, big little")
    Case #IMAGE_FILE_MACHINE_R4000
      PrintN("R4000 processor, big little")
    Case #IMAGE_FILE_MACHINE_R10000
      PrintN("R10000 processor, big little")
    Case #IMAGE_FILE_MACHINE_SH3
      PrintN("SH3")
    Case #IMAGE_FILE_MACHINE_SH4
      PrintN("SH4")
    Case #IMAGE_FILE_MACHINE_THUMB
      PrintN("Thumb")
    Default
      PrintN("unknown")
  EndSelect
  
  ;wird die CPU von Ladon unterstützt?
  Select CPU
    Case 0
      PrintN("")
      PrintN("The CPU the executable was compiled for is not supported by Ladon!")
      Exit()
    Case 1
      PrintN("Ladon supported 32bit CPU")
    Case 2
      PrintN("Ladon supported 64bit CPU")
  EndSelect
  
  ;um was für ein Image handelt es sich?
  Select PeekW(OrigFileBuffer + NtHeaderOffset + 4 + SizeOf(IMAGE_FILE_HEADER))
    Case #IMAGE_ROM_OPTIONAL_HDR_MAGIC
      PrintN("image state: ROM")
      PrintN("")
      PrintN("Ladon can not run with ROM images!")
      Exit()
    Case #IMAGE_NT_OPTIONAL_HDR32_MAGIC
      PrintN("image state: 32bit")
      ImageFormat = 1
    Case #IMAGE_NT_OPTIONAL_HDR64_MAGIC
      PrintN("image state: 64bit")
      ImageFormat = 2
  EndSelect

  Select ImageFormat
  
    Case 1 ;32bit
    
      ;Optinal Header einlesen
      CopyMemory(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER),NtOptionalHeader32,SizeOf(IMAGE_OPTIONAL_HEADER32))

      ;um welches Subsystem handelt es sich?
      Print("subsystem: ")
      Select NtOptionalHeader32\Subsystem
        Case #IMAGE_SUBSYSTEM_NATIVE
          PrintN("native")
          PrintN("")
          PrintN("This executable is a driver.")
          PrintN("Ladon dont support drivers.")
          Exit()
        Case #IMAGE_SUBSYSTEM_WINDOWS_GUI
          PrintN("Windows GUI")
        Case #IMAGE_SUBSYSTEM_WINDOWS_CUI
          PrintN("Windows CUI")
        Case #IMAGE_SUBSYSTEM_OS2_CUI
          PrintN("OS2 CUI")
          PrintN("")
          PrintN("This executable is for OS2.")
          PrintN("Ladon dont support OS2.")
          Exit()
        Case #IMAGE_SUBSYSTEM_POSIX_CUI
          PrintN("Posix CUI")
          PrintN("")
          PrintN("This executable is for Posix.")
          PrintN("Ladon dont support Posix.")
          Exit()
        Case #IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
          PrintN("Windows CE GUI")
          PrintN("")
          PrintN("This executable is for Windows CE.")
          PrintN("Ladon dont support Windows CE at now.")
          Exit()
        Case #IMAGE_SUBSYSTEM_EFI_APPLICATION
          PrintN("EFI Application")
          PrintN("")
          PrintN("This executable is a Extensible Firmware Interface.")
          PrintN("Ladon dont support EFI.")
          Exit()
        Case #IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
          PrintN("EFI Boot Service Driver")
          PrintN("")
          PrintN("This executable is a Extensible Firmware Interface.")
          PrintN("Ladon dont support EFI.")
          Exit()
        Case #IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
          PrintN("EFI Runtime Driver")
          PrintN("")
          PrintN("This executable is a Extensible Firmware Interface.")
          PrintN("Ladon dont support EFI.")
          Exit()
        Case #IMAGE_SUBSYSTEM_EFI_ROM
          PrintN("EFI ROM")
          PrintN("")
          PrintN("This executable is a Extensible Firmware Interface.")
          PrintN("Ladon dont support EFI.")
          Exit()
        Case #IMAGE_SUBSYSTEM_XBOX
          PrintN("Xbox")
          PrintN("")
          PrintN("This executable is for Xbox.")
          PrintN("Ladon dont support Xbox at now.")
          Exit()
        Case #IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
          PrintN("Windows Boot Application")
          PrintN("")
          PrintN("This executable is a Boot Application.")
          PrintN("Ladon dont support Boot Applications.")
          Exit()
        Default
          PrintN("unknown")
          PrintN("")
          PrintN("The subsystem of this executable is unknown.")
          PrintN("Ladon PE-Injector will not process executables with unknown subsystem.")
          Exit()
      EndSelect
      
      ;Data Directory einlesen
      ReDim NtDataDirectory.IMAGE_DATA_DIRECTORY(NtOptionalHeader32\NumberOfRvaAndSizes - 1)
      For i = 0 To NtOptionalHeader32\NumberOfRvaAndSizes - 1
        NtDataDirectory(i)\VirtualAddress = PeekL(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER) + SizeOf(IMAGE_OPTIONAL_HEADER32) + (i * 8))
        NtDataDirectory(i)\Size = PeekL(OrigFileBuffer + NtHeaderOffset + 10 + SizeOf(IMAGE_FILE_HEADER) + SizeOf(IMAGE_OPTIONAL_HEADER32) + (i * 8))
      Next

      ;Section Header einlesen
      ReDim SectionHeader.IMAGE_SECTION_HEADER(NtFileHeader\NumberOfSections - 1)
      For i = 0 To NtFileHeader\NumberOfSections - 1
        CopyMemory(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER) + SizeOf(IMAGE_OPTIONAL_HEADER32) + (8 * NtOptionalHeader32\NumberOfRvaAndSizes) + (i * SizeOf(IMAGE_SECTION_HEADER)),SectionHeader(i),SizeOf(IMAGE_SECTION_HEADER))
      Next
      Print("sections in executable:")
      For i = 0 To NtFileHeader\NumberOfSections - 1
        Print(" " + SectionHeader(i)\Name)
      Next
      PrintN("")
  
      ;Codesection identifizieren
      CodeSectionIndex = -1
      For i = 0 To NtFileHeader\NumberOfSections - 1
        If NtOptionalHeader32\AddressOfEntryPoint => SectionHeader(i)\VirtualAddress And NtOptionalHeader32\AddressOfEntryPoint < SectionHeader(i)\VirtualAddress + SectionHeader(i)\SizeOfRawData
          CodeSectionIndex = i
          Break
        EndIf
      Next
      If CodeSectionIndex = -1
        PrintN("")
        PrintN("Entry code section not found!")
        Exit()
      EndIf
      PrintN("entry code section: " + SectionHeader(CodeSectionIndex)\Name)
      
      ;ist die Codesection schreibbar?
      If SectionHeader(CodeSectionIndex)\Characteristics & #IMAGE_SCN_MEM_WRITE <> #IMAGE_SCN_MEM_WRITE
        PrintN("The entry code section is not writable.")
        PrintN("Note: Entry code section will be writable in new EXE. Do not change that!")        
        SectionHeader(CodeSectionIndex)\Characteristics | #IMAGE_SCN_MEM_WRITE
      Else
        PrintN("The entry code section is writable.")
      EndIf
      
      ;Import Directory nach LoadLibraryA durchsuchen
      ;Ist das Import Directory vorhanden?
      If NtDataDirectory(1)\VirtualAddress = 0
        PrintN("")
        PrintN("Import directory not found!")
        Exit()
      EndIf
      ;Section mit Import Directory ermitteln
      ImportSectionIndex = -1
      For i = 0 To NtFileHeader\NumberOfSections - 1
        If NtDataDirectory(1)\VirtualAddress => SectionHeader(i)\VirtualAddress And NtDataDirectory(1)\VirtualAddress < SectionHeader(i)\VirtualAddress + SectionHeader(i)\SizeOfRawData
          ImportSectionIndex = i
          Break
        EndIf
      Next
      If ImportSectionIndex = -1
        PrintN("")
        PrintN("Import directory section not found!")
        Exit()
      EndIf
      PrintN("import directory section: " + SectionHeader(ImportSectionIndex)\Name)
      ;Import von kernel32.dll suchen
      i = 0
      Repeat
        CopyMemory(OrigFileBuffer + NtDataDirectory(1)\VirtualAddress - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData + i,ImportDescriptor,SizeOf(IMAGE_IMPORT_DESCRIPTOR))
        i + SizeOf(IMAGE_IMPORT_DESCRIPTOR)
        If ImportDescriptor\Characteristics = 0 And ImportDescriptor\FirstThunk = 0
          PrintN("")
          PrintN("Import of kernel32.dll not found!")
          Exit()
        EndIf
        If LCase(PeekS(OrigFileBuffer + ImportDescriptor\Name1 - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData)) = "kernel32.dll"
          ;nach LibraryLoadA suchen
          i = 0
          Repeat
              ImportRVA = PeekL(OrigFileBuffer + ImportDescriptor\FirstThunk - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData + i)
              If ImportRVA = 0
                PrintN("")
                PrintN("Import of LoadLibraryA not found!")
                PrintN("Ladon Loader needs the LoadLibraryA API function.")
                PrintN("Please import it and recompile your executable.")
                Exit()
              EndIf
              If ImportRVA & #IMAGE_ORDINAL_FLAG32 <> #IMAGE_ORDINAL_FLAG32
                If LCase(PeekS(OrigFileBuffer + ImportRVA - SectionHeader(ImportSectionIndex)\VirtualAddress + SectionHeader(ImportSectionIndex)\PointerToRawData + 2)) = "loadlibrarya"
                  PrintN("LoadLibraryA import found.")
                  LoadLibraryAImportPointer = NtOptionalHeader32\ImageBase + ImportDescriptor\FirstThunk + i
                  Break
                EndIf
              EndIf
              i + 4
          ForEver
          Break
        EndIf
      ForEver
      PrintN("done")
      
      ;code section komprimieren
      PrintN("")
      PrintN("compressing code section...")
      CompCodeSectionBuffer = AllocateMemory(SectionHeader(CodeSectionIndex)\SizeOfRawData)
      CompCodeSectionSize = PackMemory(OrigFileBuffer + SectionHeader(CodeSectionIndex)\PointerToRawData,CompCodeSectionBuffer,SectionHeader(CodeSectionIndex)\SizeOfRawData + 8,9)
      If CompCodeSectionSize = 0 Or CompCodeSectionSize > SectionHeader(CodeSectionIndex)\SizeOfRawData - 100
        PrintN("")
        PrintN("Code section can not be compressed.")
        PrintN("Maybe it's to small or allready compressed.")
        Exit()
      EndIf
      PrintN("done")
      
      ;Code des Ladon Loaders generieren
      PrintN("")
      PrintN("generating loader code...")
      LoaderCodeBuffer = AllocateMemory(1024)
      Position = LoaderCodeBuffer
      PokeB(Position,$68) ;push const
      Position + 1
      PokeL(Position, NtOptionalHeader32\ImageBase + SectionHeader(CodeSectionIndex)\VirtualAddress + 12) ;const (Adresse des Strings "Ladon32.dll")
      Position + 4
      PokeW(Position,$15FF) ;call [const]
      Position + 2
      PokeL(Position,LoadLibraryAImportPointer) ;const (Adresse des Pointers von LoadLibraryA)
      Position + 4
      PokeB(Position,$C3) ;ret
      Position + 1
      PokeS(Position,"Ladon32.dll")
      Position + Len("Ladon32.dll") + 1
      PrintN("done")
      
      ;neues executable bauen
      PrintN("")
      PrintN("building new executable...")
      ;neuen Entrypoint setzen
      PokeL(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER) + 14,SectionHeader(CodeSectionIndex)\VirtualAddress)
      ;alten Entrypoint sichern
      PokeL(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER) + 62,NtOptionalHeader32\AddressOfEntryPoint)
      ;Code Section Charakteristika setzen
      PokeL(OrigFileBuffer + NtHeaderOffset + 6 + SizeOf(IMAGE_FILE_HEADER) + SizeOf(IMAGE_OPTIONAL_HEADER32) + (8 * NtOptionalHeader32\NumberOfRvaAndSizes) + (CodeSectionIndex * SizeOf(IMAGE_SECTION_HEADER)) + 36,SectionHeader(CodeSectionIndex)\Characteristics)      
      ;Loader Code in Code Section schreiben
      CopyMemory(LoaderCodeBuffer,OrigFileBuffer + SectionHeader(CodeSectionIndex)\PointerToRawData,Position - LoaderCodeBuffer)
      ;komprimierten Code in Code Section schreiben
      CopyMemory(CompCodeSectionBuffer,OrigFileBuffer + SectionHeader(CodeSectionIndex)\PointerToRawData + Position - LoaderCodeBuffer,CompCodeSectionSize)
      PrintN("done")
      
      ;neues executable speichern
      PrintN("")
      PrintN("saving new executable...")
      If Len(PEFileName) > 4
        PEFileName = Left(PEFileName,Len(PEFileName) - 4) + "_Writable.exe"
      Else
        PEFileName = PEFileName + "_Writable.exe"
      EndIf
      PrintN("filename: " + PEFileName)
      If CreateFile(1,PEFileName) = 0
        PrintN("")
        PrintN("Error: Can't create file!")
        Exit()
      EndIf
      WriteData(1,OrigFileBuffer,FileLen)
      CloseFile(1)
      PrintN("done")
      
  EndSelect











EndIf

PrintN("")
PrintN("Press any key to end program.")
Repeat
  Delay(20)
  KeyPressed = Inkey()
  If KeyPressed <> Chr(0)
    End
  EndIf
ForEver
End
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Helle »

Nicht verwirren lassen, mein obiger Code unterscheidet nicht simpel nur zwischen 32-oder 64-Bit, sondern erkennt natürlich das Format, für welches System das File compiliert wurde (sollte eigentlich klar sein, siehe die Konstanten). Hier mal etwas erweitert:

Code: Alles auswählen

;- Strukturen (in PB integriert)
I_D_H.IMAGE_DOS_HEADER
I_NT_H.IMAGE_NT_HEADERS

#IMAGE_NT_SIGNATURE               = $00004550    ;"PE  ", PE = Portable Executable, Dateiformat für ausführbare Dateien in Win32- und Win64-OS 
;hier mal einige Typen, etliche davon hier Muster ohne Wert (z.B. nicht für PE)
#IMAGE_FILE_MACHINE_UNKNOWN       = $0000        ;unbekannter Typ
#IMAGE_FILE_MACHINE_I386          = $014C        ;Intel i386 oder spätere und kompatible Prozessoren
#IMAGE_FILE_MACHINE_I860          = $014D        ;Intel i860
#IMAGE_FILE_MACHINE_R3000B        = $0160        ;MIPS big-endian R3000
#IMAGE_FILE_MACHINE_R3000L        = $0162        ;MIPS little-endian R3000
#IMAGE_FILE_MACHINE_R4000         = $0166        ;MIPS little endian R4000
#IMAGE_FILE_MACHINE_R10000        = $0168        ;MIPS little-endian R10000
#IMAGE_FILE_MACHINE_WCEMIPSV2     = $0169        ;MIPS little-endian WCE v2
#IMAGE_FILE_MACHINE_ALPHA         = $0184        ;DEC Alpha und DEC Alpha_AXP
#IMAGE_FILE_MACHINE_SH3           = $01A2        ;Hitachi SH3
#IMAGE_FILE_MACHINE_SH3DSP        = $01A3        ;Hitachi SH3 DSP
#IMAGE_FILE_MACHINE_SH3E          = $01a4        ;SH3E little-endian
#IMAGE_FILE_MACHINE_SH4           = $01A6        ;Hitachi SH4 little-endian
#IMAGE_FILE_MACHINE_SH5           = $01A8        ;Hitachi SH5
#IMAGE_FILE_MACHINE_ARM           = $01C0        ;ARM little-endian
#IMAGE_FILE_MACHINE_THUMB         = $01C2        ;Thumb 
#IMAGE_FILE_MACHINE_AM33          = $01D3        ;Matsushita AM33
#IMAGE_FILE_MACHINE_POWERPC       = $01F0        ;IBM Power PC little-endian
#IMAGE_FILE_MACHINE_POWERPCFP     = $01F1        ;IBM Power PC mit Floating-Point-Support
#IMAGE_FILE_MACHINE_IA64          = $0200        ;Intel Itanium Prozessor-Familie
#IMAGE_FILE_MACHINE_MIPS16        = $0266        ;MIPS16
#IMAGE_FILE_MACHINE_ALPHA64       = $0284        ;DEC ALPHA64
#IMAGE_FILE_MACHINE_MIPSFPU       = $0366        ;MIPS mit FPU
#IMAGE_FILE_MACHINE_MIPSFPU16     = $0466        ;MIPS16 mit FPU
#IMAGE_FILE_MACHINE_TRICORE       = $0520        ;Infineon
#IMAGE_FILE_MACHINE_CEF           = $0CEF        ;CEF  $C0EF ? 
#IMAGE_FILE_MACHINE_EBC           = $0EBC        ;EFI byte code
#IMAGE_FILE_MACHINE_AMD64         = $8664        ;AMD/Intel x64
#IMAGE_FILE_MACHINE_M32R          = $9041        ;Mitsubishi M32R little-endian
#IMAGE_FILE_MACHINE_CEE           = $C0EE        ;CEE

If OpenWindow(0, 0, 0, 500, 300, "Wähle File aus !", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
  ExplorerTreeGadget(0, 10, 10, 480, 280, "*.exe", #PB_Explorer_NoDriveRequester)
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_CloseWindow
      End
    EndIf
  Until EventType() = #PB_EventType_LeftDoubleClick And GetGadgetState(0) = #PB_Explorer_File

  File$ = GetGadgetText(0)
  If OpenFile(0, File$)
    LF = Lof(0)
    ReadData(0, @I_D_H, SizeOf(I_D_H))

    New_File_Header = I_D_H\e_lfanew
    If New_File_Header - 8 > LF
      MessageRequester("Fehler !", File$ + " ist kein File im PE-File-Format !")
      End  
    EndIf   

    FileSeek(0, New_File_Header)
    ReadData(0, @I_NT_H, SizeOf(I_NT_H))
    CloseFile(0)
    If I_NT_H\Signature <> #IMAGE_NT_SIGNATURE   ;Test auf "PE  "
      MessageRequester("Fehler !", File$ + " ist kein File im PE-File-Format !")
      End
    EndIf

    Select (I_NT_H\FileHeader\Machine) & $FFFF
      Case #IMAGE_FILE_MACHINE_I386
        File$ + " ist ein 32-Bit-File!"
      Case #IMAGE_FILE_MACHINE_AMD64
        File$ + " ist ein 64-Bit-File!"  
      Case #IMAGE_FILE_MACHINE_IA64
        File$ + " ist ein IA64-Bit-File!"
      Default                                    ;oder weitere Abfragen, s.o. die Konstanten
        File$ + " ist kein File im 32- oder 64-Bit-Windows-Format !"
    EndSelect
    MessageRequester("Ergebnis", File$)
   Else 
    MessageRequester("Fehler !", File$ + " kann nicht geöffnet werden (in Benutzung ?) !")
  EndIf
EndIf
Gruß
Helle
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Thorium »

Helle hat geschrieben:Nicht verwirren lassen, mein obiger Code unterscheidet nicht simpel nur zwischen 32-oder 64-Bit, sondern erkennt natürlich das Format, für welches System das File compiliert wurde (sollte eigentlich klar sein, siehe die Konstanten). Hier mal etwas erweitert:
Nein, du checkst nicht ob das file im 64bit State ist, du checkst nur ob der Code im File 64bit ist. Man kann davon ausgehen das es ein 64bit File ist, wenn der Code 64bit ist. Trotzdem ist das nicht der Indikator, der Indikator ist die Magic des Optional Headers, wie ich schon geschrieben habe. Denn der optional Header unterscheidet sich jenachdem ob das PE im 32bit State ist oder im 64bit State.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Sicro
Beiträge: 963
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Ermitteln, EXE-Datei 32- oder 64-Bit ist

Beitrag von Sicro »

Ich danke euch :D

Euren Codes habe ich die Vorgehensweise zur Ermittlung entnommen
und eine eigene kleine Procedure gebastelt.

Code: Alles auswählen

Procedure.l IsExe64Bit(Path.s)
  #IMAGE_DOS_HEADER = $5A4D
  #IMAGE_NT_SIGNATURE = $00004550
  #IMAGE_FILE_EXECUTABLE_IMAGE = $2

  #IMAGE_NT_OPTIONAL_HDR32_MAGIC = $10B
  #IMAGE_NT_OPTIONAL_HDR64_MAGIC = $20B
  
  Protected FileID, FileSize.l, NtHeaderOffset.l
  
  FileID = ReadFile(#PB_Any, Path)
  If Not IsFile(FileID)
    ; Datei konnte nicht geöffnet werden
    ProcedureReturn -1
  EndIf
    
  FileSize = Lof(FileID)
    
  ; Größe der Datei prüfen
  If FileSize < 512
    ; Datei ist kein PE
    CloseFile(FileID)
    ProcedureReturn -1
  EndIf
  
  If ReadWord(FileID) <> #IMAGE_DOS_HEADER
    ; Datei ist kein PE
    CloseFile(FileID)
    ProcedureReturn -1
  EndIf
 
  ; Offset des NT-Headers auslesen
  FileSeek(FileID, 60)
  NtHeaderOffset = ReadLong(FileID)
  If NtHeaderOffset > FileSize - 4
    ; Datei ist kein PE
    CloseFile(FileID)
    ProcedureReturn -1
  EndIf
 
  ; Ist es eine PE-EXE?
  FileSeek(FileID, NtHeaderOffset)
  If ReadLong(FileID) <> #IMAGE_NT_SIGNATURE
    ; Datei ist kein PE
    CloseFile(FileID)
    ProcedureReturn -1
  EndIf
  
  ; Ist die Datei eine Stand-Alone-Executable?
  FileSeek(FileID, NtHeaderOffset + 4 + OffsetOf(IMAGE_FILE_HEADER\Characteristics))
  If ReadWord(FileID) & #IMAGE_FILE_EXECUTABLE_IMAGE <> #IMAGE_FILE_EXECUTABLE_IMAGE
    ; Keine Stand-Alone-Executable
    CloseFile(File_ID)
    ProcedureReturn -1
  EndIf
  
  ; Ist Datei 32- oder 64-Bit?
  FileSeek(FileID, NtHeaderOffset + 4 + SizeOf(IMAGE_FILE_HEADER))
  Select ReadWord(FileID)
    Case #IMAGE_NT_OPTIONAL_HDR32_MAGIC
      ; 32-Bit
      CloseFile(FileID)
      ProcedureReturn #False
    Case #IMAGE_NT_OPTIONAL_HDR64_MAGIC
      ; 64-Bit
      CloseFile(FileID)
      ProcedureReturn #True
    Default
      ; Unkown
      CloseFile(FileID)
      ProcedureReturn -1
  EndSelect
EndProcedure
Mfg Sicro
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Antworten