268 votes

Comment puis-je tester un fichier DLL Windows pour déterminer s'il s'agit d'un fichier 32 bits ou 64 bits ?

J'aimerais écrire un test script ou un programme qui affirme que tous les fichiers DLL dans un répertoire donné sont d'un type de construction particulier.

Je m'en servirais comme d'un contrôle de bon sens à la fin d'un processus de construction d'un SDK pour m'assurer que la version 64 bits ne contient pas de fichiers DLL 32 bits et vice versa.

Existe-t-il un moyen simple de regarder un fichier DLL et de déterminer son type ?

La solution devrait fonctionner à la fois sur xp32 et xp64.

7 votes

J'apprécie qu'une fois la réponse à cette question connue et stackoverflow.com/q/197951/5427 partager une solution. Cependant, les questions posées étaient différentes. L'une portait explicitement sur les dlls et l'autre sur les exes. Cette question reçoit un bon nombre de votes positifs et je pense qu'elle correspond bien au problème auquel les gens essaient de trouver une réponse. Des réflexions similaires sur la duplication sont discutées ici meta.stackoverflow.com/q/266244/5427

172voto

Jeremy Points 1698

Un moyen rudimentaire serait d'appeler dumpbin avec l'option headers à partir des outils Visual Studio sur chaque DLL et de rechercher la sortie appropriée :

dumpbin /headers my32bit.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
             14C machine (x86)
               1 number of sections
        45499E0A time date stamp Thu Nov 02 03:28:10 2006
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
            2102 characteristics
                   Executable
                   32 bit word machine
                   DLL

OPTIONAL HEADER VALUES
             10B magic # (PE32)

Vous pouvez voir quelques indices dans cette sortie qu'il s'agit d'une DLL 32 bits, y compris la valeur 14C que Paul mentionne. Cela devrait être facile à rechercher dans un script.

14 votes

ATTENTION : Cette méthode ne semble pas fonctionner sur quoi que ce soit de .NET ? Renvoie le 32 bits pour tous les programmes .NET .dll ou .exe, qu'ils aient été compilés pour x32 ou x32/x64 ("All CPU"). C'est comme si chaque exécutable .NET avait un en-tête natif 32 bits et appelait le runtime .NET 32 bits ou 64 bits approprié lorsqu'il était invoqué.

2 votes

Intéressant. Cela me semble correct puisqu'une DLL AnyCPU "pourrait" fonctionner sur une machine 32 bits. Qu'en est-il des DLL .NET uniquement 64 bits ?

6 votes

@Contango : Ce n'est pas entièrement vrai (les DLL x64 seulement montrent l'en-tête correct, même si l'exécutable .NET). La partie "N'importe quel CPU" est vraie parce que le "bitness réel" sera déterminé au chargement de l'assemblage, donc cela ne peut pas être codé en dur dans l'assemblage lui-même. Vous pouvez utiliser corflags qui est fourni avec dumpbin afin d'obtenir des informations sur l'exécutable .NET.

122voto

DevSolar Points 18897

Si vous avez Cygwin (ou MobaXTerm, ou Git Bash pour Windows, ou WSL, ou...) installé (ce que je recommande fortement pour diverses raisons), vous pouvez utiliser l'utilitaire 'file' sur la DLL

file <filename>

ce qui donnerait un résultat comme celui-ci :

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

0 votes

Salut DevSolar, S'il vous plaît laissez-moi savoir comment effectuer ceci dans Cygwin. Merci, Magesh.

3 votes

Erm... où est le problème ? file <filename> . Je ne suis pas sûr que file fait partie de la configuration de base, ou si vous devez le sélectionner pour l'installation, mais il est certainement disponible dans Cygwin comme je l'ai utilisé dans le passé.

4 votes

Pour tous ceux qui utilisent MingW et ne le réalisent pas, il s'agit également d'une chose basée sur Cygwin, et elle a aussi cela.

113voto

Paul Dixon Points 122033

Détails sanglants

Une DLL utilise le PE format de fichier exécutable, et il n'est pas trop difficile à lire que les informations du fichier.

Voir cet article MSDN sur le PE Format de Fichier pour une vue d'ensemble. Vous avez besoin de lire le MS-DOS en-tête, puis lire le IMAGE_NT_HEADERS structure. Il contient les IMAGE_FILE_HEADER structure qui contient les informations dont vous avez besoin dans la Machine à états qui contient l'une des valeurs suivantes

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

Cette information doit être fixe à un décalage dans le fichier, mais je voudrais encore vous recommandons de traversant le fichier et la vérification de la signature de la MS-DOS et l'en-tête IMAGE_NT_HEADERS pour être sûr de faire face à tous les changements à venir.

Utilisation ImageHelp de lire les en-têtes...

Vous pouvez également utiliser le ImageHelp API pour ce faire, charger la DLL avec LoadImage et vous obtiendrez un LOADED_IMAGE structure qui contient un pointeur vers un IMAGE_NT_HEADERS structure. Désallouer la LOADED_IMAGE avec ImageUnload.

...ou d'adapter cette rude script Perl

Voici rugueux script Perl qui fait le travail. Il vérifie que le fichier a un DOS en-tête, puis lit le PE décalage à partir de la IMAGE_DOS_HEADER 60 octets dans le fichier.

Il cherche alors le début de la PE partie, se lit la signature et le vérifie, et puis extrait la valeur qui nous intéresse.

#!/usr/bin/perl
#
# usage: petype <exefile>
#
$exe = $ARGV[0];

open(EXE, $exe) or die "can't open $exe: $!";
binmode(EXE);
if (read(EXE, $doshdr, 68)) {

   ($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);

6 votes

Très pratique. J'ai créé une traduction Python de votre code : github.com/tgandor/meats/blob/master/missing/arch_of.py

0 votes

@TomaszGandor super truc. Pour info, j'ai dû changer 'MZ' y 'PE' à b'MZ' y b'PE' pour que ces "si" soient évalués correctement. Je ne sais pas si c'était un problème spécifique à la plateforme ou autre.

0 votes

Non, cela signifie simplement que vous avez Python 3.x ;) Merci, corrigé sur GitHub. Je suis en train de migrer vers 3.x à contrecœur (j'écris sur 2.7, en essayant d'être compatible avec le futur). Et donc j'oublie parfois que les fichiers ouverts avec 'rb' renvoie des chaînes binaires comme b'MZ' (sur Py2 bytes est juste la valeur par défaut str et de Py3 str est unicode ).

49voto

Ric Points 141

Le marcheur de dépendance dit tout (enfin presque). http://www.dependencywalker.com/

Il ne s'installe pas - il suffit de l'obtenir, de l'extraire et de lancer l'exécution. Il fonctionne pour tout module ou application Windows x32 ou x64.

Si je me souviens bien, il est assez simple de voir toutes les dépendances, c'est-à-dire les modules dll, et puisque l'application est une somme de dépendances, on peut vérifier si elle est entièrement x64, x32(x86) ou un peu de chaque.

Le type de CPU pour lequel le module a été construit est indiqué dans la colonne "CPU". La plupart des ap 64 bits sont toujours un peu de chaque mais les ap 32 bits sont tous des x86.

Beau programme pour les geeks/programmeurs et il est gratuit...

5 votes

Dependency Walker ne semble pas fonctionner sur les fichiers .NET .dll ou .exe. J'ai fait un test rapide avec des applications console .NET 32 bits et 64 bits, et il ne pouvait pas faire la différence.

4 votes

@Gravitas Pour les fichiers .Net, vous devez utiliser CorFlags.exe.

0 votes

Les liens de téléchargement sur le site web sont cassés.

42voto

Nathan Osman Points 13475

J'ai écrit un outil très simple qui fait exactement cela - il s'appelle PE Deconstructor.

Il suffit de le lancer et de charger votre fichier DLL :

enter image description here

Dans l'exemple ci-dessus, la DLL chargée est en 32 bits.

Vous pouvez le télécharger ici (je n'ai que la version 64 bits compilée ATM) :
https://files.quickmediasolutions.com/exe/pedeconstructor_0.1_amd64.exe

Une ancienne version 32 bits est disponible ici :
https://dl.dropbox.com/u/31080052/pedeconstructor.zip

2 votes

J'ai essayé ceci sur l'exécutable PE Deconstructor amd64 et il a dit qu'il était 32 bits.

0 votes

@chrysanhy : C'est étrange. D'autres outils indiquent-ils que l'exécutable est en 32 bits ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X