views:

114

answers:

1

I have many dll files and I would like to select them into two different folders (PC and PPC). For this I need to know the target platform of the dll file or any other details about its platform.

I use Python 3.1.1. I have tried the win32api which does not compatible with this Python version. So, I tried to use the ctypes.windll with try-except method where the try is true the loaded-in dll is "PC" and if not, unable to load the dll that is "PPC". But, I have a problem with this idea.

There are some dll files which I know that "PC" dll but unable to load in memory. The try-except does not work with them. So, I need to request info from the dll file about the target platform of itself.

Do you have any idea about this problem?

Many thanks.

A: 

Hi,

I found a solution based on the dll file structure. Here is the part of my code:

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 ) )
W00D00