Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if dll file was compiled as x64 or x86 bit using either Delphi or Lazarus

Using either Delphi 2007+ or Lazarus(Win64) I'm looking for a way to determine if a dll is compiled as x64 or x86?

like image 249
TheSteven Avatar asked May 01 '10 01:05

TheSteven


People also ask

How do you tell if a DLL is 64 or 32-bit?

Launch depends.exe, go to File, click Open... and open the desired DLL file. In the Module section find the Module with the name of the DLL that you opened. The CPU column tells if the file was compiled for 32 bits or 64 bits.

How do I know if a .NET assembly was built for x86 or x64?

Probing the Assembly using corflagsLaunch Developer Command Prompt for Visual Studio and then type command corflags <FullPathAndFileNameOfYourAssembly> . The output would consist of few flags which can be interpreted as follows. Assembly will run as x86 (32-bit) only. Assembly will run as x64 (64-bit) only.

How do I change a 32-bit DLL to 64-bit?

Solution 2 If possible create a separate 32 bits application that uses the 32 bit dll and call that using Process. Start()[^] from your 64 bits application. There are other ways like using named pipes for inter-process communincation, but they are quite complex to implement.


2 Answers

You should read and parse PE header.

Like this:

function Isx64(const Strm: TStream): Boolean;
const
  IMAGE_FILE_MACHINE_I386     = $014c; // Intel x86
  IMAGE_FILE_MACHINE_IA64     = $0200; // Intel Itanium Processor Family (IPF)
  IMAGE_FILE_MACHINE_AMD64    = $8664; // x64 (AMD64 or EM64T)
  // You'll unlikely encounter the things below:
  IMAGE_FILE_MACHINE_R3000_BE = $160;  // MIPS big-endian
  IMAGE_FILE_MACHINE_R3000    = $162;  // MIPS little-endian, 0x160 big-endian
  IMAGE_FILE_MACHINE_R4000    = $166;  // MIPS little-endian
  IMAGE_FILE_MACHINE_R10000   = $168;  // MIPS little-endian
  IMAGE_FILE_MACHINE_ALPHA    = $184;  // Alpha_AXP }
  IMAGE_FILE_MACHINE_POWERPC  = $1F0;  // IBM PowerPC Little-Endian
var
  Header: TImageDosHeader;
  ImageNtHeaders: TImageNtHeaders;
begin
  Strm.ReadBuffer(Header, SizeOf(Header));
  if (Header.e_magic <> IMAGE_DOS_SIGNATURE) or
     (Header._lfanew = 0) then
    raise Exception.Create('Invalid executable');
  Strm.Position := Header._lfanew;

  Strm.ReadBuffer(ImageNtHeaders, SizeOf(ImageNtHeaders));
  if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then
    raise Exception.Create('Invalid executable');

  Result := ImageNtHeaders.FileHeader.Machine <> IMAGE_FILE_MACHINE_I386;
end;
like image 57
Alex Avatar answered Sep 19 '22 10:09

Alex


You could use JclPeImage from the JCL. The following app shows how to do it.


program Isx64ImageTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, JclWin32, JclPEImage;

var
  PEImage: TJclPeImage;
begin
  PEImage := TJclPeImage.Create;
  try
    //usage is "Isx64ImageTest filename"
    PEImage.FileName := ParamStr(1);
    //print the machine value as string
    WriteLn(Format('Machine value of image %s is %s',
      [PEImage.FileName, PEImage.HeaderValues[JclPeHeader_Machine]]));
    //check for a special machine value
    case PEImage.LoadedImage.FileHeader^.FileHeader.Machine of
      IMAGE_FILE_MACHINE_I386:  begin end;
      IMAGE_FILE_MACHINE_AMD64: begin end;
      else
      begin
      end;
    end;
  finally
    PEImage.Free;
  end;
end.
like image 39
Uwe Schuster Avatar answered Sep 20 '22 10:09

Uwe Schuster