2010-05-01 18 views
6

Usando Delphi 2007+ o Lazarus (Win64) Estoy buscando una forma de determinar si un dll está compilado como x64 o x86.Cómo determinar si el archivo dll fue compilado como un bit x64 o x86 usando Delphi o Lazarus

+0

He encontrado las siguientes preguntas, pero no he tenido tiempo para asimilarlo: http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.tools/ 2006-12/msg00011.html Este enlace: http://www.delphidabbler.com/articles?article=8&part=2 mencionado en el artículo vinculado anterior proporciona fuente Delphi para analizar el encabezado del archivo que puede identificar 16 y 32 bit, pero no 64. El código puede ejecutarse en Delphi 2007 tal como está pero no en Delphi2010 o Lazarus, al menos no sin más modificaciones de las que tuve tiempo o experiencia. – TheSteven

Respuesta

14

Debe leer y analizar el encabezado PE.

De esta manera:

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

Gracias por la respuesta. Desafortunadamente, esto requeriría que JCL funcione. No he agregado JCL a mi Delphi 2007, pero podría hacerlo si parece ser la única solución conveniente. – TheSteven

+0

¿Qué? Este código no usa ninguna clase JCL ni rutinas. – Alex

+1

Su versión actualizada funciona perfectamente en Delphi 2007 y Delphi 2010. Una solución elegante, gracias. – TheSteven

4

usted podría utilizar JclPeImage del JCL. La siguiente aplicación muestra cómo hacerlo.


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

Si está utilizando JCL - hay un enfoque más simple - usando la función PeMapImgTarget o la propiedad PEImage.Target (en su ejemplo). No es necesario que analices los encabezados por ti mismo. – Alex

+0

Aún no usa JCL, puede hacerlo eventualmente. He estado intentando duplicar mis componentes Delphi2007 y Delphi2010 porque he estado planeando migrar a Delphi2010. ¿Está JCL disponible para Delphi2010? – TheSteven

+0

JCL está disponible para D2010. – Alex

Cuestiones relacionadas