Utilizzando Delphi 2007+ o Lazarus (Win64) Sto cercando un modo per determinare se una DLL è compilata come x64 o x86?Come determinare se il file dll è stato compilato come x64 o x86 bit utilizzando Delphi o Lazarus
risposta
È necessario leggere e analizzare l'intestazione PE.
Ti piace questa:
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;
Grazie per la risposta. Sfortunatamente questo avrebbe richiesto il funzionamento di JCL. Non ho aggiunto JCL al mio Delphi 2007, ma potrebbe sembrare l'unica soluzione conveniente. – TheSteven
Cosa? Questo codice non utilizza alcuna classe JCL né routine. – Alex
La tua versione aggiornata funziona bene in Delphi 2007 e Delphi 2010. Una soluzione elegante - grazie. – TheSteven
è possibile utilizzare JclPeImage dal JCL. La seguente app mostra come farlo.
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.
Se stai usando JCL - c'è un approccio più semplice - usando la funzione PeMapImgTarget o la proprietà PEImage.Target (nel tuo esempio). Non è necessario analizzare le intestazioni da solo. – Alex
Non usare ancora JCL, potrebbe eventualmente farlo. Ho cercato di eseguire il mirroring dei miei componenti Delphi2007 e Delphi2010 perché avevo intenzione di migrare a Delphi2010. JCL è disponibile per Delphi2010? – TheSteven
JCL è disponibile per D2010. – Alex
ho trovato le seguenti informazioni, ma non ho avuto il tempo di assimilare: http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.tools/ 2006-12/msg00011.html Questo collegamento: http://www.delphidabbler.com/articles?article=8&part=2 menzionato nel precedente articolo collegato fornisce a Delphi l'origine per analizzare l'intestazione del file che può identificare 16 & 32 bit, ma non 64. Il codice può essere eseguito su Delphi 2007 così com'è ma non su Delphi2010 o Lazarus - almeno non senza ulteriori modifiche di quante ne avessi avuto per esperienza o tempo. – TheSteven