¿Cómo puedo probar un archivo DLL de Windows para determinar si es de 32 bits o de 64 bits?

Me gustaría escribir un guión de prueba o un progtwig que afirme que todos los archivos DLL en un directorio determinado son de un tipo de comstackción en particular.

Utilizaría esto como una comprobación de cordura al final de un proceso de comstackción en un SDK para asegurarme de que la versión de 64 bits no haya conseguido de alguna manera algunos archivos DLL de 32 bits y viceversa.

¿Hay una manera fácil de mirar un archivo DLL y determinar su tipo?

La solución debería funcionar tanto en xp32 como en xp64.

Detalles de Gory

Una DLL usa el formato ejecutable PE, y no es demasiado complicado leer esa información fuera del archivo.

Consulte este artículo de MSDN en el formato de archivo PE para obtener una descripción general. Debe leer el encabezado de MS-DOS y luego leer la estructura IMAGE_NT_HEADERS . Contiene la estructura IMAGE_FILE_HEADER que contiene la información que necesita en el miembro de Machine que contiene uno de los siguientes valores

  • IMAGE_FILE_MACHINE_I386 (0x014c)
  • IMAGE_FILE_MACHINE_IA64 (0x0200)
  • IMAGE_FILE_MACHINE_AMD64 (0x8664)

Esta información debe estar en un desplazamiento fijo en el archivo, pero aún así recomiendo atravesar el archivo y verificar la firma del encabezado de MS-DOS y de IMAGE_NT_HEADERS para asegurarse de que pueda hacer frente a los cambios futuros.

Use ImageHelp para leer los encabezados …

También puede usar la API ImageHelp para hacer esto: cargar la DLL con LoadImage y obtendrá una estructura LOADED_IMAGE que contendrá un puntero a la estructura IMAGE_NT_HEADERS. Desasigne LOADED_IMAGE con ImageUnload.

… o adaptar este guion áspero de Perl

Aquí está el guión de Perl aproximado que hace el trabajo. Comprueba que el archivo tiene un encabezado DOS, luego lee el desplazamiento PE de los 60 bytes IMAGE_DOS_HEADER en el archivo.

Luego busca el inicio de la parte PE, lee la firma y la verifica, y luego extrae el valor que nos interesa.

#!/usr/bin/perl # # usage: petype  # $exe = $ARGV[0]; open(EXE, $exe) or die "can't open $exe: $!"; binmode(EXE); if (read(EXE, $doshdr, 64)) { ($magic,$skip,$offset)=unpack('a2a58l', $doshdr); die("Not an executable") if ($magic ne 'MZ'); seek(EXE,$offset,SEEK_SET); if (read(EXE, $pehdr, 6)){ ($sig,$skip,$machine)=unpack('a2a2v', $pehdr); die("No a PE Executable") if ($sig ne 'PE'); if ($machine == 0x014c){ print "i386\n"; } elsif ($machine == 0x0200){ print "IA64\n"; } elsif ($machine == 0x8664){ print "AMD64\n"; } else{ printf("Unknown machine type 0x%lx\n", $machine); } } } close(EXE); 

Una forma cruda sería llamar a dumpbin con la opción de encabezados desde las herramientas de Visual Studio en cada DLL y buscar el resultado apropiado:

 dumpbin / headers my32bit.dll

 Se encontró una firma de PE

 Tipo de archivo: DLL

 VALORES DE LA CABEZA DEL ARCHIVO
              Máquina 14C (x86)
                1 número de secciones
         45499E0A sello de fecha y hora Jue Nov 02 03:28:10 2006
                0 puntero de archivo a la tabla de símbolos
                0 cantidad de símbolos
               E0 tamaño del encabezado opcional
             2102 características
                    Ejecutable
                    Máquina de palabras de 32 bits
                    DLL

 VALORES DE CABECERA OPCIONALES
              10B magic # (PE32)

Puede ver un par de pistas en ese resultado que es una DLL de 32 bits, incluido el valor 14C que menciona Paul. Debería ser fácil de buscar en un script.

Si tiene Cygwin instalado (lo recomiendo encarecidamente por varias razones), puede usar la utilidad ‘archivo’ en el archivo DLL

 file  

que daría un resultado como este:

 icuuc36.dll: MS-DOS executable PE for MS Windows (DLL) (GUI) Intel 80386 32-bit 

Dependencia Walker dice todo (bueno casi). http://www.dependencywalker.com/

No “instala”, simplemente obténgalo, extráigalo y ejecute el comando ejecutivo. Funciona para cualquier aplicación de módulo de Windows x32 o x64.

Según recuerdo, es bastante sencillo ver todas las dependencias, es decir, los módulos dll, y desde el appl. es una sum de las dependencias que uno puede determinar si está completo x64, x32 (x86) o un poco de cada uno.

El tipo de CPU para el que se construyó el módulo está en la columna “CPU”. La mayoría de las aplicaciones de 64 bits siguen siendo un poco de cada una, pero ap de 32 bits con todo x86.

Hermoso progtwig para geeks / progtwigdores y es gratis …

He escrito una herramienta muy simple que hace exactamente eso: se llama PE Deconstructor.

Simplemente enciéndelo y carga tu archivo DLL:

enter image description here

En el ejemplo anterior, la DLL cargada es de 32 bits.

Puede descargarlo aquí (solo tengo la versión comstackda de 64 bits del cajero automático):
http://files.quickmediasolutions.com/exe/pedeconstructor_0.1_amd64.exe

Una versión anterior de 32 bits está disponible aquí:
http://dl.dropbox.com/u/31080052/pedeconstructor.zip