2010-05-01 9 views
6

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

+0

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

risposta

14

È 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; 
+0

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

+0

Cosa? Questo codice non utilizza alcuna classe JCL né routine. – Alex

+1

La tua versione aggiornata funziona bene in Delphi 2007 e Delphi 2010. Una soluzione elegante - grazie. – TheSteven

4

è 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. 
+1

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

+0

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

+0

JCL è disponibile per D2010. – Alex