如何使用Python 3.1.1获取dll的目标平台信息?

时间:2009-12-11 17:42:52

标签: python api dll winapi platform

我有很多dll文件,我想将它们分成两个不同的文件夹(PC和PPC)。 为此,我需要知道dll文件的目标平台或其平台的任何其他细节。

我使用Python 3.1.1。我试过了与这个Python版本不兼容的win32api。所以,我尝试使用ctypes.windll和try-except方法,其中try为true,加载的dll是“PC”,如果没有,则无法加载“PPC”的dll。但是,我对这个想法有疑问。

有一些dll文件,我知道“PC”DLL但无法加载到内存中。 try-except不适用于它们。所以,我需要从dll文件中请求有关目标平台的信息。

你对这个问题有什么看法吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

我找到了一个基于dll文件结构的解决方案。这是我的代码的一部分:

def DLLIdentifier( self ):
    '''
     Microsoft Portable Executable and Common Object File Format Specification
     http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx 

     After the MS DOS stub, at the file offset specified at offset 0x3c, 
     is a 4-byte signature that identifies the file as a PE format image file. 
     This signature is "PE\0\0" (the letters "P" and "E" followed by two null bytes).
     At the beginning of an object file, or immediately after the signature of an image file, 
     is a standard COFF file header in the following format. 
     Note that the Windows loader limits the number of sections to 96.
     The Machine field has one of the following values that specifies its CPU type. 
     An image file can be run only on the specified machine or on a system that emulates the specified machine.
    '''
    Platform = 'UNKNOWN'
    for Row in codecs.open( os.path.join( self.Root, self.File ), 'rb' ):
        if b'\x00PE\x00\x00' in Row:
            # IMAGE_FILE_MACHINE_UNKNOWN      0x0         The contents of this field are assumed to be applicable to any machine type
            if b'\x00PE\x00\x00\x00\x00' in Row:
                Platform = 'UNKNOWN'
                break
            # IMAGE_FILE_MACHINE_AM33         0x1d3       Matsushita AM33
            elif b'\x00PE\x00\x00\xD3\x01' in Row:
                Platform = 'AM33'
                break
            # IMAGE_FILE_MACHINE_AMD64        0x8664      x64
            elif b'\x00PE\x00\x00\x664\x08' in Row:
                Platform = 'AMD64'
                break
            # IMAGE_FILE_MACHINE_ARM          0x1c0       ARM little endian
            elif b'\x00PE\x00\x00\xC0\x01' in Row:
                Platform = 'ARM'
                break
            # IMAGE_FILE_MACHINE_EBC          0xebc       EFI byte code
            elif b'\x00PE\x00\x00\xBC\x0E' in Row:
                Platform = 'EBC'
                break
            # IMAGE_FILE_MACHINE_I386         0x14c       Intel 386 or later processors and compatible processors
            elif b'\x00PE\x00\x00\x4C\x01' in Row:
                Platform = 'I386'
                break
            # IMAGE_FILE_MACHINE_IA64         0x200       Intel Itanium processor family
            elif b'\x00PE\x00\x00\x00\x02' in Row:
                Platform = 'IA64'
                break
            # IMAGE_FILE_MACHINE_M32R         0x9041      Mitsubishi M32R little endian
            elif b'\x00PE\x00\x00\x041\x09' in Row:
                Platform = 'M32R'
                break
            # IMAGE_FILE_MACHINE_MIPS16       0x266       MIPS16
            elif b'\x00PE\x00\x00\x66\x02' in Row:
                Platform = 'MIPS16'
                break
            # IMAGE_FILE_MACHINE_MIPSFPU      0x366       MIPS with FPU
            elif b'\x00PE\x00\x00\x66\x03' in Row:
                Platform = 'MIPSFPU'
                break
            # IMAGE_FILE_MACHINE_MIPSFPU16    0x466       MIPS16 with FPU
            elif b'\x00PE\x00\x00\x66\x04' in Row:
                Platform = 'MIPSFPU16'
                break
            # IMAGE_FILE_MACHINE_POWERPC      0x1f0       Power PC little endian
            elif b'\x00PE\x00\x00\xF0\x01' in Row:
                Platform = 'POWERPC'
                break
            # IMAGE_FILE_MACHINE_POWERPCFP    0x1f1       Power PC with floating point support
            elif b'\x00PE\x00\x00\xF1\x01' in Row:
                Platform = 'POWERPCFP'
                break
            # IMAGE_FILE_MACHINE_R4000        0x166       MIPS little endian
            elif b'\x00PE\x00\x00\x66\x01' in Row:
                Platform = 'R4000'
                break
            # IMAGE_FILE_MACHINE_SH3          0x1a2       Hitachi SH3
            elif b'\x00PE\x00\x00\xA2\x01' in Row:
                Platform = 'SH3'
                break
            # IMAGE_FILE_MACHINE_SH3DSP       0x1a3       Hitachi SH3 DSP
            elif b'\x00PE\x00\x00\xA3\x01' in Row:
                Platform = 'SH3DSP'
                break
            # IMAGE_FILE_MACHINE_SH4          0x1a6       Hitachi SH4
            elif b'\x00PE\x00\x00\xA6\x01' in Row:
                Platform = 'SH4'
                break
            # IMAGE_FILE_MACHINE_SH5          0x1a8       Hitachi SH5
            elif b'\x00PE\x00\x00\xA8\x01' in Row:
                Platform = 'SH5'
                break
            # IMAGE_FILE_MACHINE_THUMB        0x1c2       Thumb
            elif b'\x00PE\x00\x00\xC2\x01' in Row:
                Platform = 'THUMB'
                break
            # IMAGE_FILE_MACHINE_WCEMIPSV2    0x169       MIPS little - endian WCE v2
            elif b'\x00PE\x00\x00\x69\x01' in Row:
                Platform = 'WCEMIPSV2'
                break
            else:
                StartIndex = Row.find( b'\x00PE\x00\x00' )
                EndIndex = StartIndex + 7
                PlatformCode = Row[StartIndex:EndIndex]
                self.ErrorState = False
                self.oLogger.critical( 'The unknown platform code is "{}".'.format( PlatformCode ) )

    assert Platform != 'UNKNOWN', 'Unknown .dll file "{}" at\n{}'.format( self.File, os.path.join( self.Root, self.File ) )

    if Platform == 'I386':
        self.PlatformType = 'PC'
    elif Platform in ( 'ARM', 'THUMB' ):
        self.PlatformType = 'PPC'
    else:
        self.ErrorState = False
        self.oLogger.critical( 'The unknown dll file with "{}" platform code.'.format( Platform ) )