Delphi BPL check for 32/64 bit

151 Views Asked by At

Is there a straightforward way to examine a Delphi BPL file for 32/64 bitness? I want to be able to do this outside of attempting to load the BPL itself - e.g. open the BPL as a binary file and read a specific address in the contents of the file that indicates whether it's compiled for 32-bit or 64-bit.

The referenced answer is for Python, not Delphi, and not everyone is aware that BPLs are actually just an extended for of DLLs.

2

There are 2 best solutions below

2
Uwe Raabe On

As we are speaking of BPL files here (which basically are DLLs following a certain convention), one can simply compare some Delphi BPLs coming with every installation and are located in separate subfolders of the redist folder.

At position $50 there is an ASCI string containing This program must be run under Win32 and This program must be run under Win64 respectively.

0
SteveS On

Here's code to detect this:

uses
  WinApi.Windows,
  System.Classes,
  System.SysUtils;

type
  TModuleBitness = (bnUnknown, bnBadMZSig, bnBadPESig, bn32Bit, bn64Bit);

const
  MinModuleSize = SizeOf(TImageDOSHeader) + 
                  SizeOf(UInt32) + 
                  SizeOf(TImageFileHeader);

function CheckFileBitness(const FN: String): TModuleBitness;
var
  F:    TFileStream;
  I:    UInt32;
  DHdr: TImageDOSHeader;
  COFF: TImageFileHeader;
begin
  //assume unknown type
  Result := bnUnknown;
  //if the file doesn't even exist, bail
  if not FileExists(FN) then
    Exit;
  //open the file
  F := TFileStream.Create(FN, fmOpenRead);
  try
    //make sure we have a big enough file
    if F.Size < MinModuleSize then
      Exit;
    //start at the beginning
    F.Seek(0, 0);
    //read DOS header
    F.Read(DHdr, SizeOf(DHdr));
    //is it valid?
    if DHdr.e_magic <> IMAGE_DOS_SIGNATURE then
      Exit(bnBadMZSig);

    //seek to offset of PE signature
    F.Seek(DHdr._lfanew, 0);
    //read PE signature DWORD
    F.Read(I, SizeOf(I));
    //is it valid?
    if I <> IMAGE_NT_SIGNATURE then
      Exit(bnBadPESig);

    //read the COFF image file header
    F.Read(COFF, SizeOf(COFF));
    //is it x64?
    if COFF.Machine = IMAGE_FILE_MACHINE_AMD64 then
      Result := bn64Bit
      //is it x86?
    else if COFF.Machine = IMAGE_FILE_MACHINE_I386 then
      Result := bn32Bit;
  finally
    F.Free;
  end;
end;