11
votes

Déterminez si une exécutable (ou une bibliothèque) est de 32-Ou 64 bits (sous Windows)

J'essaie de savoir si une exécutable (ou une bibliothèque) donnée est compilée pour 32 bits ou 64 bits de Python. Je rencontre Vista 64-bits et je voudrais déterminer si une certaine application d'un répertoire est compilée pour 32 bits ou 64 bits.

Y a-t-il un moyen simple de le faire en utilisant uniquement les bibliothèques Python standard (en utilisant actuellement 2,5,4)?


0 commentaires

5 Réponses :


23
votes

L'API Windows pour cela est getbinairetype . Vous pouvez appeler cela de python à l'aide de pywin32 : xxx pré>

Si vous voulez faire cela sans pywin32, vous devrez lire le en-tête PE vous-même. Voici un exemple en C #, et voici une Port rapide à Python: P>

import struct

IMAGE_FILE_MACHINE_I386=332
IMAGE_FILE_MACHINE_IA64=512
IMAGE_FILE_MACHINE_AMD64=34404

f=open("c:\windows\explorer.exe", "rb")

s=f.read(2)
if s!="MZ":
    print "Not an EXE file"
else:
    f.seek(60)
    s=f.read(4)
    header_offset=struct.unpack("<L", s)[0]
    f.seek(header_offset+4)
    s=f.read(2)
    machine=struct.unpack("<H", s)[0]

    if machine==IMAGE_FILE_MACHINE_I386:
        print "IA-32 (32-bit x86)"
    elif machine==IMAGE_FILE_MACHINE_IA64:
        print "IA-64 (Itanium)"
    elif machine==IMAGE_FILE_MACHINE_AMD64:
        print "AMD64 (64-bit x86)"
    else:
        print "Unknown architecture"

f.close()


8 commentaires

Ce serait bien si je pouvais obtenir ces informations sans utiliser le module PYWIN32.


Je viens de modifier la réponse pour montrer comment vous pouvez le faire sans pywin32.


@Martin. Merci pour les liens, je verrai si je peux mettre quelque chose ensemble.


Il suffit d'ajouter un port de l'exemple C # à Python.


Le fichier ne devrait-il pas être ouvert en mode binaire?


Cette affiche « l'architecture inconnue » sur ma machine. Les rapports variables de la machine -31132. Aucune suggestion?


Mon mauvais - image_file_machine_ia64 est itanium. -31132 (ou 34404 non signé) est AMD64 (alias 64 bits X86). Vous n'avez pas de système de 64 bits que je peux tester cela, mais j'espère que cela devrait fonctionner maintenant.


J'ai pu utiliser cette solution (Python 3.5) après avoir incorporé les modifications suggérées dans la réponse fournie ci-dessous par Jason R Coombs.



5
votes

Si vous exécutez Python 2.5 ou plus tard sur Windows, vous pouvez également utiliser l'API Windows sans pywin32 à l'aide de CTYPES.

from ctypes import windll, POINTER
from ctypes.wintypes import LPWSTR, DWORD, BOOL

SCS_32BIT_BINARY = 0 # A 32-bit Windows-based application
SCS_64BIT_BINARY = 6 # A 64-bit Windows-based application
SCS_DOS_BINARY = 1 # An MS-DOS-based application
SCS_OS216_BINARY = 5 # A 16-bit OS/2-based application
SCS_PIF_BINARY = 3 # A PIF file that executes an MS-DOS-based application
SCS_POSIX_BINARY = 4 # A POSIX-based application
SCS_WOW_BINARY = 2 # A 16-bit Windows-based application

_GetBinaryType = windll.kernel32.GetBinaryTypeW
_GetBinaryType.argtypes = (LPWSTR, POINTER(DWORD))
_GetBinaryType.restype = BOOL

def GetBinaryType(filepath):
    res = DWORD()
    handle_nonzero_success(_GetBinaryType(filepath, res))
    return res


0 commentaires

1
votes

J'ai pu utiliser la réponse de Martin B avec succès dans un programme Python 3.5 après avoir effectué ce réglage:

s=f.read(2).decode(encoding="utf-8", errors="strict")


0 commentaires

0
votes
  1. Utilisation de Python 3.7, 32 bits sur 64 bits Win 7, le premier fragment de code dans la réponse supérieure ne fonctionne pas pour moi. Il échoue parce que GetBinyType est un symbole inconnu. La solution consiste à utiliser win32file.getbinairetype code>. Li>
  2. L'exécution également sur un fichier .PYD ne fonctionne pas, même s'il est renommé à un fichier .dll. Voir Suivant: P>

    Pythonwin.exe: 32 bit
    win32ui.pyd: Traceback (most recent call last):
      File "C:/Users/rdboylan/Documents/Wk devel/bitness.py", line 14, in <module>
        type = win32file.GetBinaryType(str(mytemp))
    pywintypes.error: (193, 'GetBinaryType', '%1 is not a valid Win32 application.')
    

0 commentaires

2
votes

J'ai édité Réponse pour fonctionner avec Python 3, ajouté avec code > SUPPORTATIONS ET ARM / ARM64 Support:

import struct

IMAGE_FILE_MACHINE_I386 = 332
IMAGE_FILE_MACHINE_IA64 = 512
IMAGE_FILE_MACHINE_AMD64 = 34404
IMAGE_FILE_MACHINE_ARM = 452
IMAGE_FILE_MACHINE_AARCH64 = 43620

with open('foo.exe', 'rb') as f:
    s = f.read(2)
    if s != b'MZ':
        print('Not an EXE file')
    else:
        f.seek(60)
        s = f.read(4)
        header_offset = struct.unpack('<L', s)[0]
        f.seek(header_offset + 4)
        s = f.read(2)
        machine = struct.unpack('<H', s)[0]

        if machine == IMAGE_FILE_MACHINE_I386:
            print('IA-32 (32-bit x86)')
        elif machine == IMAGE_FILE_MACHINE_IA64:
            print('IA-64 (Itanium)')
        elif machine == IMAGE_FILE_MACHINE_AMD64:
            print('AMD64 (64-bit x86)')
        elif machine == IMAGE_FILE_MACHINE_ARM:
            print('ARM eabi (32-bit)')
        elif machine == IMAGE_FILE_MACHINE_AARCH64:
            print('AArch64 (ARM-64, 64-bit)')
        else:
            print(f'Unknown architecture {machine}')


0 commentaires