Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Ist Anwendung 32 oder 64 Bit (https://www.delphipraxis.net/167227-ist-anwendung-32-oder-64-bit.html)

Luckie 19. Mär 2012 11:56

Ist Anwendung 32 oder 64 Bit
 
Ich bin ja seit einer Woche stolzer Besitzer eines vier kern 645-Bit Rechners und Windows 7 64-Bit. Jetzt hatte ich mir ein Programm runtergeladen ohne Installer und wollte es in den richtigen Ordner kopieren: "Program Files" oder "Program Files(x86)". Nur hatte ich das Problem, dass ich nicht wusste, ob es eine 32 oder 64 Bit Anwendung ist. OK, es stand nicht dabei, dass es eine 645 Bit Anwendung ist, also könnte man davon ausgehen, dass es sich um eine 32 Bit Anwendung handelt.

Aber ich wüsste gerne mit welcher API Funktion man herausfinden kann, ob eine fremde Anwendung 32 oder 64 Bit ist. Ich wollte mir da dann nämlich ein kleines Programm zu schreiben, mit dem ich herausfinden kann, ob ein anderes Programm eben 32 oder 64 Bit ist.

Daniel 19. Mär 2012 12:00

AW: Ist Anwendung 32 oder 64 Bit
 
MSDN-Library durchsuchenImageNtHeader ist wohl Dein Freund.

Siehe auch:
http://stackoverflow.com/questions/9...86-x64-or-ia64
und
http://stackoverflow.com/questions/4...32bit-or-64bit

//edit: In Deinem Beitrag verstecken sich ein paar 5en zuviel ;-)

Luckie 19. Mär 2012 12:02

AW: Ist Anwendung 32 oder 64 Bit
 
Danke.

Unsinn. Ich bin nur schon auf die Zukunft vorbereitet mit dem Rechner. ;)

himitsu 19. Mär 2012 12:53

AW: Ist Anwendung 32 oder 64 Bit
 
Oder einfach mal starten, in den Taskmanager schauen
und danach in den Programmeordner verschieben.

Luckie 19. Mär 2012 13:08

AW: Ist Anwendung 32 oder 64 Bit
 
@Himitsu: Hey, ich bin Programmierer. ;)

Aphton 19. Mär 2012 14:44

AW: Ist Anwendung 32 oder 64 Bit
 
Vlt. etwas füe die Code-Library

Delphi-Quellcode:
function IsExecutable32Bit(const lpExeFilename: String): Boolean;
const
  kb32 = 1024 * 32;
var
  Buffer : Array[0..kb32-1] of Byte; // warning: assuming both headers are in there!
  hFile  : DWord;
  bRead  : DWord;
  bToRead : DWord;
  pDos   : PImageDosHeader;
  pNt    : PImageNtHeaders;
begin
  Result := False;
  hFile := CreateFile(pChar(lpExeFilename), GENERIC_READ, FILE_SHARE_READ, NIL,
    OPEN_EXISTING, 0, 0);
  if hFile <> INVALID_HANDLE_VALUE then
    try
      bToRead := GetFileSize(hFile, NIL);
      if bToRead > kb32 then bToRead := kb32;
      if not ReadFile(hFile, Buffer, bToRead, bRead, NIL) then Exit;
      if bRead = bToRead then
      begin
        pDos := @Buffer[0];
        if pDos.e_magic = IMAGE_DOS_SIGNATURE then
        begin
          pNt := PImageNtHeaders(LongInt(pDos) + pDos._lfanew);
          if pNt.Signature = IMAGE_NT_SIGNATURE then
            Result := pNt.FileHeader.Machine and IMAGE_FILE_32BIT_MACHINE > 0;
        end; {
        else
          raise Exception.Create('File is not a valid executable.');
        }
      end;  {
        else
          raise Exception.Create('File is not an executable.');
        }
    finally
      CloseHandle(hFile);
    end;
end;

function IsExecutable64Bit(const lpExeFilename: String): Boolean;
// since as of now (march 2012), there only exist 32 and 64 bit executables,
// if its not the one, its assumably the other
begin
  Result := not IsExecutable32Bit(lpExeFilename);
end;

Luckie 19. Mär 2012 15:49

AW: Ist Anwendung 32 oder 64 Bit
 
Hmpf, wenn man es nicht sofort programmiert... :(

Iwo Asnet 19. Mär 2012 15:58

AW: Ist Anwendung 32 oder 64 Bit
 
Zitat:

Zitat von Aphton (Beitrag 1157370)
Vlt. etwas füe die Code-Library...

Pah, viel zu kompliziert :mrgreen:
Delphi-Quellcode:
Function Is32EXE (aFileName : String) : Boolean;
Begin
  Result := Pos('Program Files(x86)',aFilename)=0;
End;
:wall:

p80286 19. Mär 2012 16:02

AW: Ist Anwendung 32 oder 64 Bit
 
Und wenn aus irgendwelchen finsteren Quellen doch noch eine 16Bit echse auftaucht?????

Gruß
K-H

Luckie 19. Mär 2012 16:14

AW: Ist Anwendung 32 oder 64 Bit
 
Zitat:

Zitat von p80286 (Beitrag 1157386)
Und wenn aus irgendwelchen finsteren Quellen doch noch eine 16Bit echse auftaucht?????

Die laufen nicht unter 64 Bit, also stellt sich die Frage gar nicht.

Aphton 19. Mär 2012 16:25

AW: Ist Anwendung 32 oder 64 Bit
 
Puh, glück gehabt xD

p80286 19. Mär 2012 16:32

AW: Ist Anwendung 32 oder 64 Bit
 
Zitat:

Zitat von Luckie (Beitrag 1157343)
Jetzt hatte ich mir ein Programm runtergeladen ohne Installer und wollte es in den richtigen Ordner kopieren: "Program Files" oder "Program Files(x86)".

Das klingt für mich so, daß es alles mögliche sein könnte

Gruß
K-H

mkinzler 19. Mär 2012 16:34

AW: Ist Anwendung 32 oder 64 Bit
 
Der Pfad dürfte zudem egal sein

Luckie 19. Mär 2012 16:39

AW: Ist Anwendung 32 oder 64 Bit
 
Zitat:

Zitat von mkinzler (Beitrag 1157399)
Der Pfad dürfte zudem egal sein

Ich bin ordnungsliebend. Da kommt nichts einfach "irgendwo" hin. ;)

Amateurprofi 19. Mär 2012 17:06

AW: Ist Anwendung 32 oder 64 Bit
 
Zitat:

Zitat von Luckie (Beitrag 1157405)
Zitat:

Zitat von mkinzler (Beitrag 1157399)
Der Pfad dürfte zudem egal sein

Ich bin ordnungsliebend. Da kommt nichts einfach "irgendwo" hin. ;)

Auch keine 5?

ringli 19. Mär 2012 18:04

AW: Ist Anwendung 32 oder 64 Bit
 
Ich werfe mal diese Funktion in den (virtuellen) Raum:
Delphi-Quellcode:
const
  SCS_32BIT_BINARY = 0;
  SCS_64BIT_BINARY = 6;
  SCS_DOS_BINARY  = 1;
  SCS_OS216_BINARY = 5;
  SCS_PIF_BINARY  = 3;
  SCS_POSIX_BINARY = 4;
  SCS_WOW_BINARY  = 2;

  KERNEL32_DLL    = 'kernel32.dll';

  // Typ eines Binaries erkennen
  // DYNAMISCHER FUNKTIONSIMPORT !!!
type
  TGetBinaryType = function (lpApplicationName: PWideChar; out lpBinaryType: DWORD): Boolean; stdcall;

function GetBinaryType(lpApplicationName: PWideChar; out lpBinaryType: DWORD): Boolean;
var
  DLL_Handle       : THandle;       // für dynamischen Funktionsimport!
  DLL_GetBinaryType : TGetBinaryType; // für dynamischen Funktionsimport!
begin
  // Handle für die KERNEL32.DLL erhalten
  DLL_Handle := LoadLibraryW(PWideChar(KERNEL32_DLL));
  // Wenn Handle vorhanden, Adressen der Funktionen ermitteln
  if DLL_Handle <> 0 then
    begin
      try
        @DLL_GetBinaryType := GetProcAddress(DLL_Handle, 'GetBinaryTypeW');
        // Wurde GetBinaryTypeW in der DLL gefunden?
        if @DLL_GetBinaryType <> nil then
          begin
            Result := DLL_GetBinaryType(lpApplicationName, lpBinaryType);
          end
        else
          begin
            RaiseLastOSError;
            Result := False;
          end;
      finally
        FreeLibrary(DLL_Handle);
      end;
    end
  else
    begin
      RaiseLastOSError;
      Result := False;
    end;
end;
Das dürfte der offizielle Weg sein. Optimierungspotenzial nicht ausgeschlossen. ;)

himitsu 19. Mär 2012 21:02

AW: Ist Anwendung 32 oder 64 Bit
 
Delphi-Quellcode:
function IsExecutable32Bit(const Filename: String): Boolean;
var
  hFile : THandle;
  bRead : {$IF Defined(NativeUInt)}NativeUInt{$ELSE}LongWord{$IFEND};
  Buffer : array[0..1024*64-1] of Byte; // Warning: Assuming both headers are in there!
  DosHeader : TImageDosHeader absolute Buffer;
  NtHeader : PImageNtHeaders;
begin
  Result := False;
  hFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, 0, 0);
  if hFile <> INVALID_HANDLE_VALUE then
  begin
    try
      if ReadFile(hFile, Buffer, SizeOf(Buffer), bRead, NIL)
          and (DosHeader.e_magic = IMAGE_DOS_SIGNATURE)
          and (DosHeader._lfanew + SizeOf(TImageNtHeaders) <= bRead) then
        begin
          NtHeader := PImageNtHeaders(@Buffer[DosHeader._lfanew]);
          if NtHeader.Signature = IMAGE_NT_SIGNATURE then
            Result := NtHeader.FileHeader.Machine and IMAGE_FILE_32BIT_MACHINE <> 0;
        end; {
        else
          raise Exception.Create('File is not a valid executable.'); }
    finally
      CloseHandle(hFile);
    end;
  end; {
  else
    raise Exception.Create('File is not readable.'); }
end;
Bissl aufgeräumt und die Position des NTHeaders geprüft.
Auch für NonVCL-Programme unter 32 KB.

Und zum Offiziellen:
Delphi-Quellcode:
type
  TBinaryType = (tbUnknown, btDLL, tbWin32, btDOS, btWOW, btPIF, btPOSIX, btOS2_16, btWin64);

function GetBinaryType(Filename: string): TBinaryType;
type
  TGetBinaryType = function(Filename: PChar; var BinaryType: DWORD): BOOL; stdcall;
var
  GetBinaryTypeProc: TGetBinaryType;
  Value: DWORD;
begin
  GetBinaryTypeProc := GetProcAddress(GetModuleHandle('kernel32.dll'),
    {$IF SizeOf(Char) = 1}'GetBinaryTypeA'{$ELSE}'GetBinaryTypeW'{$IFEND});
  Value := 0;
  if not Assigned(GetBinaryTypeProc) then
    Result := tbUnknown
  else if GetBinaryTypeProc(PChar(Filename), Value) then
    Result := TBinaryType(Value + Ord(tbWin32))
  else if GetLastError = ERROR_BAD_EXE_FORMAT then
    Result := btDLL
  else
    Result := tbUnknown;
end;
(die kernel32.dll ist im Prinzip immer geladen)

Assarbad 16. Apr 2012 20:12

AW: Ist Anwendung 32 oder 64 Bit
 
Zitat:

Zitat von mkinzler (Beitrag 1157399)
Der Pfad dürfte zudem egal sein

Leider nein. Während 64bit-Anwendungen alles zu sehen bekommen, bekommen WOW64 die Hucke vollgelogen. Dazu gehören dann eben diverse Pfade. Will man das umgehen muß die Anwendung "sich dessen bewußt sein" und aktiv MSDN-Library durchsuchenWow64DisableWow64FsRedirection und Freunde einsetzen.

Interessant wird das bspw. wenn du eine WOW64-Anwendung hast und dann bspw. eine Shellerweiterung für 64bit und eine für 32bit. Kopier den Schmarrn dann mal in %ProgramFiles(x86)% und mal in %ProgramFiles% und staune :) ...

Willst du diese Shellerweiterung nicht in ihr eigenes Verzeichnis sperren, mußt du den Pfad beachten. Will nicht heißen, daß es bei dem Programm welches Luckie benutzt eine Rolle spielen würde, aber es ist nicht so egal wie du zu meinen scheinst ;)

Zitat:

Zitat von himitsu (Beitrag 1157441)
(die kernel32.dll ist im Prinzip immer geladen)

Die Aussage kannst du für das Win32-Subsystem (also alle Delphiprogramme die nicht nochmal modifiziert wurden) absolut machen (also nicht "im Prinzip" :mrgreen:). kernel32.dll wird direkt nach ntdll.dll (also der Verbindung der Subsysteme mit dem Kernel) geladen und enthält Code der bspw. dafür zuständig ist Prozesse beim Win32-Subsystem (csrss.exe) anzumelden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz