Using either Delphi 2007+ or Lazarus(Win64) I'm looking for a way to determine if a dll is compiled as x64 or x86?
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.
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.
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.
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;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With