Retreive PE File Type

posted 6 Jun 2010, 15:28 by Delphi Basics
This function, written by Xash, returns the type of an .exe (x32 or x64). An alternative method would be to use the api, GetBinaryType:
http://msdn.microsoft.com/en-us/library/aa364819%28VS.85%29.aspx

{
    Coder: Xash
    Website: hacksecu.com
    Compiled: Delphi 2007
}

Function:
function IsValidPe(FileName :String) :Boolean;
// by Xash
var
  hFile       :DWORD;
  DosHeader   :TImageDosHeader;
  NtHeaders   :TImageNtHeaders;
  dwRead      :DWORD;
begin
  Result := True;

  if not FileExists(FileName) then // Si le fichier n'existe pas on ne continue pas
  begin
    Result := False;
    Exit;
  end;

  hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); // On ouvre le fichier en mode lecture
  try
    try
      SetFilePointer(hFile, 0, nil, FILE_BEGIN);
      ReadFile(hFile, DosHeader, SizeOf(DosHeader), dwRead, nil); // On lit l'entête DOS

      if DosHeader.e_magic <> IMAGE_DOS_SIGNATURE then // Si la signature n'est pas valide (MZ)
        Result := False
      else
      begin
        SetFilePointer(hFile, DosHeader._lfanew, nil, FILE_BEGIN); // On place le curseur au début de l'entête PE
        ReadFile(hFile, NtHeaders, SizeOf(NtHeaders), dwRead, nil); // On lit l'entête PE

        if NtHeaders.Signature <> IMAGE_NT_SIGNATURE then // Si la signature n'est pas valide (PE\0\0)
          Result := False;
      end;
    except
      On Exception do
        Result := False; // Si il y a un probléme on retourne false
    end;
  finally
    CloseHandle(hFile);
  end;
end;

Usage:
function PeFileType(FileName :String) :String;
// by Xash
var
  hFile       :DWORD;
  DosHeader   :TImageDosHeader;
  NtHeaders   :TImageNtHeaders;
  dwRead      :DWORD;
begin
  Result := '?';

  if not FileExists(FileName) then // Si le fichier n'existe pas on ne continue pas
    Exit;

  if not IsValidPe(FileName) then // Si il n'a pas un PE valide
    Exit;

  hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); // On ouvre le fichier en mode lecture
  try
    ReadFile(hFile, DosHeader, SizeOf(DosHeader), dwRead, nil); // On lit l'entête DOS
    SetFilePointer(hFile, DosHeader._lfanew, nil, FILE_BEGIN); // On place le curseur au début de l'entête PE
    ReadFile(hFile, NtHeaders, SizeOf(NtHeaders), dwRead, nil); // On lit l'entête PE
    if NtHeaders.OptionalHeader.Magic = $10B then // 0x10B PE32
      Result := '32';
    if NtHeaders.OptionalHeader.Magic = $20B then // 0x20B PE32+
      Result := '64';
  finally
    CloseHandle(hFile);
  end
end;
Comments