Using either Delphi 2007+ or Lazarus(Win64) I'm looking for a way to determine if a dll is compiled as x64 or x86?
How to determine if dll file was compiled as x64 or x86 bit using either Delphi or Lazarus
I've found the following information but haven't had time to assimilate it: tech-archive.net/Archive/Development/… This link: delphidabbler.com/articles?article=8&part=2 mentioned in the previous linked article provides Delphi source to parse the file header that can identify 16 & 32 bit, but not 64. The code can run on Delphi 2007 as is but not on Delphi2010 or Lazarus - at least not without more modifications than I had time or experience for. –
Farrish
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;
Thanks for the response. Unfortunately this would required JCL to work. I have not added JCL to my Delphi 2007 but may if it looks like the only expedient solution. –
Farrish
Your updated version works just fine in Delphi 2007 and Delphi 2010. An elegant solution - thank you. –
Farrish
Note that these constants are in unit Windows on FPC. (at least in 2.4.0+ don't know about older ones) –
Uncloak
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're using JCL - there is more simpler approach - by using PeMapImgTarget function or PEImage.Target property (in your example). No need to analyze headers by yourself. –
Grow
Not using JCL yet, may eventually do so. I've been trying to mirror my Delphi2007 and Delphi2010 components because I've been planning on migrating to Delphi2010. Is JCL available for Delphi2010? –
Farrish
© 2022 - 2024 — McMap. All rights reserved.