Comment puis-je tester un fichier DLL Windows pour déterminer s'il s'agit d'un fichier 32 bits ou 64 bits? [dupliquer]
-
20-08-2019 - |
Question
Cette question a déjà une réponse ici:
J'aimerais écrire un script de test ou un programme qui affirme que tous les fichiers DLL d'un répertoire sont d'un type de construction particulier.
Je l’utiliserais comme vérification de bonne santé à la fin du processus de construction d’un SDK pour s’assurer que la version 64 bits ne contient pas de fichiers DLL 32 bits et inversement.
Existe-t-il un moyen simple de consulter un fichier DLL et de déterminer son type?
La solution devrait fonctionner à la fois sur xp32 et xp64.
La solution
Détails Gory
Une DLL utilise le format exécutable PE et il n'est pas trop difficile de lire ces informations dans le fichier.
Voir cet article MSDN dans le format de fichier PE pour un aperçu. Vous devez lire l’en-tête MS-DOS, puis le IMAGE_NT_HEADERS. structure. Cela contient la structure IMAGE_FILE_HEADER qui contient les informations vous concernant. besoin dans le membre de l'ordinateur qui contient l'une des valeurs suivantes
- IMAGE_FILE_MACHINE_I386 (0x014c)
- IMAGE_FILE_MACHINE_IA64 (0x0200)
- IMAGE_FILE_MACHINE_AMD64 (0x8664)
Ces informations doivent apparaître avec un décalage fixe dans le fichier, mais je vous recommande néanmoins de parcourir le fichier et de vérifier la signature de l'en-tête MS-DOS et de la commande IMAGE_NT_HEADERS pour vous assurer de faire face aux modifications futures.
Utilisez ImageHelp pour lire les en-têtes ...
Vous pouvez également utiliser l’ API ImageHelp . Pour ce faire, chargez la DLL avec LoadImage et vous obtiendrez une structure LOADED_IMAGE qui contiendra un pointeur sur une structure IMAGE_NT_HEADERS. Libérez LOADED_IMAGE avec ImageUnload.
... ou adaptez ce script Perl brut
Voici un script approximatif en Perl qui fait le travail. Il vérifie que le fichier a un en-tête DOS, puis lit le décalage PE de 60 octets IMAGE_DOS_HEADER dans le fichier.
Il cherche ensuite le début de la partie PE, lit la signature et la vérifie, 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, 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);
Autres conseils
Une méthode simple consiste à appeler dumpbin avec l'option d'en-têtes à partir des outils Visual Studio de chaque DLL et à rechercher le résultat approprié:
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 mentionnée par Paul. Devrait être facile à rechercher dans un script.
Si vous avez Cygwin installé (ce que je recommande fortement pour diverses raisons), vous pouvez utiliser le ' fichier 'utilitaire sur la DLL
file <filename>
qui donnerait une sortie comme celle-ci:
icuuc36.dll: MS-DOS executable PE for MS Windows (DLL) (GUI) Intel 80386 32-bit
Dependency Walker dit tout (enfin presque). http://www.dependencywalker.com/
Cela ne > pas; installer & "; -Juste l'obtenir, l'extraire et lancer l'exécutif. Cela fonctionne pour n’importe quel module | application 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 depuis l’appl. est la somme des dépendances que l’on peut vérifier s’il s’agit de x64 complet, x32 (x86) ou un peu de chacun.
Le type de CPU pour lequel le module a été créé est dans la " CPU " colonne. La plupart des APS 64 bits sont encore un peu de chacun, mais des 32 bits avec tous les x86.
Beau programme pour les geeks / programmeurs et c'est gratuit ...
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:
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 de l'ATM compilé):
http://files.quickmediasolutions.com/exe/pedeconstructor_0.1_amd64.exe
Une version 32 bits plus ancienne est disponible ici:
http://dl.dropbox.com/u/31080052/pedeconstructor.zip