2

多くの dll ファイルがあり、それらを 2 つの異なるフォルダー (PC と PPC) に選択したいと考えています。このためには、dll ファイルのターゲット プラットフォーム、またはそのプラットフォームに関するその他の詳細を知る必要があります。

Python 3.1.1 を使用しています。この Python バージョンと互換性のない win32api を試しました。そのため、ctypes.windll を try-except メソッドで使用しようとしました。try が true の場合、ロードされた dll は「PC」であり、そうでない場合は、「PPC」である dll をロードできません。しかし、私はこの考えに問題があります。

「PC」dllであることがわかっているが、メモリにロードできないdllファイルがいくつかあります。それらに対して try-except は機能しません。したがって、それ自体のターゲット プラットフォームに関する dll ファイルから情報を要求する必要があります。

この問題について何か考えはありますか?

どうもありがとう。

4

1 に答える 1

1

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 ) )
于 2009-12-14T10:28:02.580 に答える