15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# -*- coding: Latin-1 -*- 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""pefile, Portable Executable reader module 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)All the PE file basic structures are available with their default names 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)as attributes of the instance returned. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Processed elements such as the import table are made available with lowercase 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)names, to differentiate them from the upper case basic structure names. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pefile has been tested against the limits of valid PE headers, that is, malware. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Lots of packed malware attempt to abuse the format way beyond its standard use. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)To the best of my knowledge most of the abuses are handled gracefully. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Copyright (c) 2005, 2006, 2007, 2008 Ero Carrera <ero@dkbza.org> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)All rights reserved. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)For detailed copyright information see the file COPYING in 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)the root of the distribution archive. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__author__ = 'Ero Carrera' 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__version__ = '1.2.9.1' 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__contact__ = 'ero@dkbza.org' 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import struct 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import math 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import exceptions 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import string 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import array 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sha1, sha256, sha512, md5 = None, None, None, None 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)try: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import hashlib 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha1 = hashlib.sha1 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha256 = hashlib.sha256 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha512 = hashlib.sha512 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) md5 = hashlib.md5 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)except ImportError: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import sha 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha1 = sha.new 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except ImportError: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pass 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import md5 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) md5 = md5.new 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except ImportError: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pass 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fast_load = False 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_DOS_SIGNATURE = 0x5A4D 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_OS2_SIGNATURE = 0x454E 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_OS2_SIGNATURE_LE = 0x454C 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_VXD_SIGNATURE = 0x454C 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_NT_SIGNATURE = 0x00004550 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_NUMBEROF_DIRECTORY_ENTRIES= 16 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_ORDINAL_FLAG = 0x80000000L 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_ORDINAL_FLAG64 = 0x8000000000000000L 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OPTIONAL_HEADER_MAGIC_PE = 0x10b 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OPTIONAL_HEADER_MAGIC_PE_PLUS = 0x20b 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)directory_entry_types = [ 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_EXPORT', 0), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_IMPORT', 1), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_RESOURCE', 2), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_EXCEPTION', 3), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_SECURITY', 4), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_BASERELOC', 5), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_DEBUG', 6), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_COPYRIGHT', 7), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_GLOBALPTR', 8), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_TLS', 9), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG', 10), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT', 11), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_IAT', 12), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT', 13), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR',14), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_RESERVED', 15) ] 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DIRECTORY_ENTRY = dict([(e[1], e[0]) for e in directory_entry_types]+directory_entry_types) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)image_characteristics = [ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_RELOCS_STRIPPED', 0x0001), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_EXECUTABLE_IMAGE', 0x0002), 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_LINE_NUMS_STRIPPED', 0x0004), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_LOCAL_SYMS_STRIPPED', 0x0008), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_AGGRESIVE_WS_TRIM', 0x0010), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_LARGE_ADDRESS_AWARE', 0x0020), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_16BIT_MACHINE', 0x0040), 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_BYTES_REVERSED_LO', 0x0080), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_32BIT_MACHINE', 0x0100), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_DEBUG_STRIPPED', 0x0200), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP', 0x0400), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_NET_RUN_FROM_SWAP', 0x0800), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_SYSTEM', 0x1000), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_DLL', 0x2000), 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_UP_SYSTEM_ONLY', 0x4000), 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_BYTES_REVERSED_HI', 0x8000) ] 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IMAGE_CHARACTERISTICS = dict([(e[1], e[0]) for e in 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_characteristics]+image_characteristics) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)section_characteristics = [ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_CNT_CODE', 0x00000020), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_CNT_INITIALIZED_DATA', 0x00000040), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_CNT_UNINITIALIZED_DATA', 0x00000080), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_LNK_OTHER', 0x00000100), 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_LNK_INFO', 0x00000200), 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_LNK_REMOVE', 0x00000800), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_LNK_COMDAT', 0x00001000), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_FARDATA', 0x00008000), 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_PURGEABLE', 0x00020000), 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_16BIT', 0x00020000), 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_LOCKED', 0x00040000), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_PRELOAD', 0x00080000), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_1BYTES', 0x00100000), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_2BYTES', 0x00200000), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_4BYTES', 0x00300000), 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_8BYTES', 0x00400000), 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_16BYTES', 0x00500000), 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_32BYTES', 0x00600000), 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_64BYTES', 0x00700000), 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_128BYTES', 0x00800000), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_256BYTES', 0x00900000), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_512BYTES', 0x00A00000), 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_1024BYTES', 0x00B00000), 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_2048BYTES', 0x00C00000), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_4096BYTES', 0x00D00000), 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_8192BYTES', 0x00E00000), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_ALIGN_MASK', 0x00F00000), 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_LNK_NRELOC_OVFL', 0x01000000), 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_DISCARDABLE', 0x02000000), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_NOT_CACHED', 0x04000000), 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_NOT_PAGED', 0x08000000), 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_SHARED', 0x10000000), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_EXECUTE', 0x20000000), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_READ', 0x40000000), 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SCN_MEM_WRITE', 0x80000000L) ] 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECTION_CHARACTERISTICS = dict([(e[1], e[0]) for e in 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_characteristics]+section_characteristics) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)debug_types = [ 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_UNKNOWN', 0), 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_COFF', 1), 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_CODEVIEW', 2), 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_FPO', 3), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_MISC', 4), 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_EXCEPTION', 5), 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_FIXUP', 6), 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_OMAP_TO_SRC', 7), 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_OMAP_FROM_SRC', 8), 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_BORLAND', 9), 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DEBUG_TYPE_RESERVED10', 10) ] 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEBUG_TYPE = dict([(e[1], e[0]) for e in debug_types]+debug_types) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)subsystem_types = [ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_UNKNOWN', 0), 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_NATIVE', 1), 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_WINDOWS_GUI', 2), 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_WINDOWS_CUI', 3), 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_OS2_CUI', 5), 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_POSIX_CUI', 7), 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_WINDOWS_CE_GUI', 9), 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_EFI_APPLICATION', 10), 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER', 11), 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER', 12), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_EFI_ROM', 13), 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_SUBSYSTEM_XBOX', 14)] 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SUBSYSTEM_TYPE = dict([(e[1], e[0]) for e in subsystem_types]+subsystem_types) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)machine_types = [ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_UNKNOWN', 0), 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_AM33', 0x1d3), 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_AMD64', 0x8664), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_ARM', 0x1c0), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_EBC', 0xebc), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_I386', 0x14c), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_IA64', 0x200), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_MR32', 0x9041), 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_MIPS16', 0x266), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_MIPSFPU', 0x366), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_MIPSFPU16',0x466), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_POWERPC', 0x1f0), 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_POWERPCFP',0x1f1), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_R4000', 0x166), 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_SH3', 0x1a2), 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_SH3DSP', 0x1a3), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_SH4', 0x1a6), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_SH5', 0x1a8), 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_THUMB', 0x1c2), 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_FILE_MACHINE_WCEMIPSV2',0x169), 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ] 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MACHINE_TYPE = dict([(e[1], e[0]) for e in machine_types]+machine_types) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)relocation_types = [ 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_ABSOLUTE', 0), 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_HIGH', 1), 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_LOW', 2), 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_HIGHLOW', 3), 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_HIGHADJ', 4), 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_MIPS_JMPADDR', 5), 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_SECTION', 6), 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_REL', 7), 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_MIPS_JMPADDR16', 9), 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_IA64_IMM64', 9), 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_DIR64', 10), 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_REL_BASED_HIGH3ADJ', 11) ] 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RELOCATION_TYPE = dict([(e[1], e[0]) for e in relocation_types]+relocation_types) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dll_characteristics = [ 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_RESERVED_0x0001', 0x0001), 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_RESERVED_0x0002', 0x0002), 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_RESERVED_0x0004', 0x0004), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_RESERVED_0x0008', 0x0008), 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE', 0x0040), 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY', 0x0080), 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_NX_COMPAT', 0x0100), 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION', 0x0200), 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_NO_SEH', 0x0400), 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_NO_BIND', 0x0800), 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_RESERVED_0x1000', 0x1000), 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER', 0x2000), 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE', 0x8000) ] 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DLL_CHARACTERISTICS = dict([(e[1], e[0]) for e in dll_characteristics]+dll_characteristics) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Resource types 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)resource_type = [ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_CURSOR', 1), 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_BITMAP', 2), 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_ICON', 3), 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_MENU', 4), 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_DIALOG', 5), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_STRING', 6), 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_FONTDIR', 7), 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_FONT', 8), 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_ACCELERATOR', 9), 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_RCDATA', 10), 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_MESSAGETABLE', 11), 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_GROUP_CURSOR', 12), 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_GROUP_ICON', 14), 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_VERSION', 16), 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_DLGINCLUDE', 17), 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_PLUGPLAY', 19), 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_VXD', 20), 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_ANICURSOR', 21), 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_ANIICON', 22), 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_HTML', 23), 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('RT_MANIFEST', 24) ] 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RESOURCE_TYPE = dict([(e[1], e[0]) for e in resource_type]+resource_type) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Language definitions 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lang = [ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_NEUTRAL', 0x00), 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_INVARIANT', 0x7f), 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_AFRIKAANS', 0x36), 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ALBANIAN', 0x1c), 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ARABIC', 0x01), 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ARMENIAN', 0x2b), 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ASSAMESE', 0x4d), 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_AZERI', 0x2c), 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_BASQUE', 0x2d), 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_BELARUSIAN', 0x23), 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_BENGALI', 0x45), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_BULGARIAN', 0x02), 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_CATALAN', 0x03), 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_CHINESE', 0x04), 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_CROATIAN', 0x1a), 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_CZECH', 0x05), 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_DANISH', 0x06), 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_DIVEHI', 0x65), 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_DUTCH', 0x13), 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ENGLISH', 0x09), 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ESTONIAN', 0x25), 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_FAEROESE', 0x38), 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_FARSI', 0x29), 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_FINNISH', 0x0b), 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_FRENCH', 0x0c), 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_GALICIAN', 0x56), 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_GEORGIAN', 0x37), 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_GERMAN', 0x07), 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_GREEK', 0x08), 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_GUJARATI', 0x47), 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_HEBREW', 0x0d), 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_HINDI', 0x39), 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_HUNGARIAN', 0x0e), 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ICELANDIC', 0x0f), 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_INDONESIAN', 0x21), 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ITALIAN', 0x10), 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_JAPANESE', 0x11), 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_KANNADA', 0x4b), 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_KASHMIRI', 0x60), 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_KAZAK', 0x3f), 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_KONKANI', 0x57), 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_KOREAN', 0x12), 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_KYRGYZ', 0x40), 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_LATVIAN', 0x26), 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_LITHUANIAN', 0x27), 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MACEDONIAN', 0x2f), 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MALAY', 0x3e), 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MALAYALAM', 0x4c), 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MANIPURI', 0x58), 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MARATHI', 0x4e), 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MONGOLIAN', 0x50), 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_NEPALI', 0x61), 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_NORWEGIAN', 0x14), 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ORIYA', 0x48), 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_POLISH', 0x15), 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_PORTUGUESE', 0x16), 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_PUNJABI', 0x46), 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ROMANIAN', 0x18), 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_RUSSIAN', 0x19), 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SANSKRIT', 0x4f), 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SERBIAN', 0x1a), 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SINDHI', 0x59), 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SLOVAK', 0x1b), 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SLOVENIAN', 0x24), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SPANISH', 0x0a), 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SWAHILI', 0x41), 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SWEDISH', 0x1d), 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SYRIAC', 0x5a), 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_TAMIL', 0x49), 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_TATAR', 0x44), 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_TELUGU', 0x4a), 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_THAI', 0x1e), 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_TURKISH', 0x1f), 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_UKRAINIAN', 0x22), 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_URDU', 0x20), 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_UZBEK', 0x43), 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_VIETNAMESE', 0x2a), 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_GAELIC', 0x3c), 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MALTESE', 0x3a), 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_MAORI', 0x28), 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_RHAETO_ROMANCE',0x17), 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SAAMI', 0x3b), 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SORBIAN', 0x2e), 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_SUTU', 0x30), 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_TSONGA', 0x31), 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_TSWANA', 0x32), 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_VENDA', 0x33), 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_XHOSA', 0x34), 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ZULU', 0x35), 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_ESPERANTO', 0x8f), 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_WALON', 0x90), 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_CORNISH', 0x91), 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_WELSH', 0x92), 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('LANG_BRETON', 0x93) ] 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LANG = dict(lang+[(e[1], e[0]) for e in lang]) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Sublanguage definitions 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sublang = [ 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_NEUTRAL', 0x00), 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_DEFAULT', 0x01), 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SYS_DEFAULT', 0x02), 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_SAUDI_ARABIA', 0x01), 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_IRAQ', 0x02), 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_EGYPT', 0x03), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_LIBYA', 0x04), 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_ALGERIA', 0x05), 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_MOROCCO', 0x06), 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_TUNISIA', 0x07), 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_OMAN', 0x08), 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_YEMEN', 0x09), 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_SYRIA', 0x0a), 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_JORDAN', 0x0b), 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_LEBANON', 0x0c), 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_KUWAIT', 0x0d), 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_UAE', 0x0e), 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_BAHRAIN', 0x0f), 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ARABIC_QATAR', 0x10), 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_AZERI_LATIN', 0x01), 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_AZERI_CYRILLIC', 0x02), 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_CHINESE_TRADITIONAL', 0x01), 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_CHINESE_SIMPLIFIED', 0x02), 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_CHINESE_HONGKONG', 0x03), 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_CHINESE_SINGAPORE', 0x04), 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_CHINESE_MACAU', 0x05), 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_DUTCH', 0x01), 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_DUTCH_BELGIAN', 0x02), 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_US', 0x01), 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_UK', 0x02), 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_AUS', 0x03), 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_CAN', 0x04), 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_NZ', 0x05), 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_EIRE', 0x06), 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_SOUTH_AFRICA', 0x07), 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_JAMAICA', 0x08), 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_CARIBBEAN', 0x09), 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_BELIZE', 0x0a), 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_TRINIDAD', 0x0b), 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_ZIMBABWE', 0x0c), 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ENGLISH_PHILIPPINES', 0x0d), 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_FRENCH', 0x01), 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_FRENCH_BELGIAN', 0x02), 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_FRENCH_CANADIAN', 0x03), 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_FRENCH_SWISS', 0x04), 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_FRENCH_LUXEMBOURG', 0x05), 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_FRENCH_MONACO', 0x06), 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GERMAN', 0x01), 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GERMAN_SWISS', 0x02), 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GERMAN_AUSTRIAN', 0x03), 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GERMAN_LUXEMBOURG', 0x04), 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GERMAN_LIECHTENSTEIN', 0x05), 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ITALIAN', 0x01), 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ITALIAN_SWISS', 0x02), 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_KASHMIRI_SASIA', 0x02), 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_KASHMIRI_INDIA', 0x02), 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_KOREAN', 0x01), 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_LITHUANIAN', 0x01), 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_MALAY_MALAYSIA', 0x01), 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_MALAY_BRUNEI_DARUSSALAM', 0x02), 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_NEPALI_INDIA', 0x02), 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_NORWEGIAN_BOKMAL', 0x01), 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_NORWEGIAN_NYNORSK', 0x02), 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_PORTUGUESE', 0x02), 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_PORTUGUESE_BRAZILIAN', 0x01), 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SERBIAN_LATIN', 0x02), 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SERBIAN_CYRILLIC', 0x03), 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH', 0x01), 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_MEXICAN', 0x02), 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_MODERN', 0x03), 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_GUATEMALA', 0x04), 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_COSTA_RICA', 0x05), 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_PANAMA', 0x06), 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_DOMINICAN_REPUBLIC', 0x07), 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_VENEZUELA', 0x08), 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_COLOMBIA', 0x09), 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_PERU', 0x0a), 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_ARGENTINA', 0x0b), 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_ECUADOR', 0x0c), 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_CHILE', 0x0d), 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_URUGUAY', 0x0e), 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_PARAGUAY', 0x0f), 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_BOLIVIA', 0x10), 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_EL_SALVADOR', 0x11), 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_HONDURAS', 0x12), 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_NICARAGUA', 0x13), 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SPANISH_PUERTO_RICO', 0x14), 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SWEDISH', 0x01), 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_SWEDISH_FINLAND', 0x02), 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_URDU_PAKISTAN', 0x01), 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_URDU_INDIA', 0x02), 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_UZBEK_LATIN', 0x01), 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_UZBEK_CYRILLIC', 0x02), 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_DUTCH_SURINAM', 0x03), 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ROMANIAN', 0x01), 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_ROMANIAN_MOLDAVIA', 0x02), 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_RUSSIAN', 0x01), 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_RUSSIAN_MOLDAVIA', 0x02), 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_CROATIAN', 0x01), 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_LITHUANIAN_CLASSIC', 0x02), 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GAELIC', 0x01), 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GAELIC_SCOTTISH', 0x02), 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('SUBLANG_GAELIC_MANX', 0x03) ] 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SUBLANG = dict(sublang+[(e[1], e[0]) for e in sublang]) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnicodeStringWrapperPostProcessor: 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This class attemps to help the process of identifying strings 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) that might be plain Unicode or Pascal. A list of strings will be 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wrapped on it with the hope the overlappings will help make the 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decission about their type.""" 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, pe, rva_ptr): 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.pe = pe 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.rva_ptr = rva_ptr 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.string = None 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_rva(self): 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the RVA of the string.""" 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.rva_ptr 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the escaped ASCII representation of the string.""" 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def convert_char(char): 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if char in string.printable: 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return char 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return r'\x%02x' % ord(char) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.string: 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ''.join([convert_char(c) for c in self.string]) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '' 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def invalidate(self): 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Make this instance None, to express it's no known string type.""" 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self = None 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def render_pascal_16(self): 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.string = self.pe.get_string_u_at_rva( 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.rva_ptr+2, 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_length=self.__get_pascal_16_length()) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ask_pascal_16(self, next_rva_ptr): 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """The next RVA is taken to be the one immediately following this one. 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Such RVA could indicate the natural end of the string and will be checked 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) with the possible length contained in the first word. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length = self.__get_pascal_16_length() 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if length == (next_rva_ptr - (self.rva_ptr+2)) / 2: 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.length = length 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __get_pascal_16_length(self): 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.__get_word_value_at_rva(self.rva_ptr) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __get_word_value_at_rva(self, rva): 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.pe.get_data(self.rva_ptr, 2) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(data)<2: 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.unpack('<H', data)[0] 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #def render_pascal_8(self): 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # """""" 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ask_unicode_16(self, next_rva_ptr): 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """The next RVA is taken to be the one immediately following this one. 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Such RVA could indicate the natural end of the string and will be checked 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to see if there's a Unicode NULL character there. 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.__get_word_value_at_rva(next_rva_ptr-2) == 0: 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.length = next_rva_ptr - self.rva_ptr 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def render_unicode_16(self): 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """""" 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.string = self.pe.get_string_u_at_rva(self.rva_ptr) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PEFormatError(Exception): 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Generic PE format error exception.""" 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, value): 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.value = value 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return repr(self.value) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Dump: 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Convenience class for dumping the PE information.""" 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.text = '' 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def add_lines(self, txt, indent=0): 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Adds a list of lines. 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The list can be indented with the optional argument 'indent'. 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in txt: 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.add_line(line, indent) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def add_line(self, txt, indent=0): 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Adds a line. 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The line can be indented with the optional argument 'indent'. 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.add(txt+'\n', indent) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def add(self, txt, indent=0): 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Adds some text, no newline will be appended. 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The text can be indented with the optional argument 'indent'. 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if isinstance(txt, unicode): 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = [] 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for c in txt: 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.append(str(c)) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except UnicodeEncodeError, e: 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.append(repr(c)) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) txt = ''.join(s) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.text += ' '*indent+txt 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def add_header(self, txt): 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Adds a header element.""" 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.add_line('-'*10+txt+'-'*10+'\n') 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def add_newline(self): 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Adds a newline.""" 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.text += '\n' 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_text(self): 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the text in its current state.""" 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.text 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Structure: 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Prepare structure object to extract members from data. 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Format is a list containing definitions for the elements 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) of the structure. 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, format, name=None, file_offset=None): 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Format is forced little endian, for big endian non Intel platforms 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__format__ = '<' 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__keys__ = [] 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# self.values = {} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__format_length__ = 0 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__set_format__(format[1]) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._all_zeroes = False 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__unpacked_data_elms__ = None 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__file_offset__ = file_offset 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if name: 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.name = name 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.name = format[0] 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __get_format__(self): 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.__format__ 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_file_offset(self): 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.__file_offset__ 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_file_offset(self, offset): 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__file_offset__ = offset 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def all_zeroes(self): 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Returns true is the unpacked data is all zeroes.""" 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._all_zeroes 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __set_format__(self, format): 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for elm in format: 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ',' in elm: 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elm_type, elm_name = elm.split(',', 1) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__format__ += elm_type 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elm_names = elm_name.split(',') 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names = [] 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for elm_name in elm_names: 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if elm_name in self.__keys__: 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) search_list = [x[:len(elm_name)] for x in self.__keys__] 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) occ_count = search_list.count(elm_name) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elm_name = elm_name+'_'+str(occ_count) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names.append(elm_name) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Some PE header structures have unions on them, so a certain 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # value might have different names, so each key has a list of 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # all the possible members referring to the data. 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__keys__.append(names) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__format_length__ = struct.calcsize(self.__format__) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def sizeof(self): 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return size of the structure.""" 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.__format_length__ 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __unpack__(self, data): 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(data)>self.__format_length__: 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = data[:self.__format_length__] 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Some malware have incorrect header lengths. 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Fail gracefully if this occurs 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Buggy malware: a29b0118af8b7408444df81701ad5a7f 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif len(data)<self.__format_length__: 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError('Data length less than expected header length.') 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if data.count(chr(0)) == len(data): 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._all_zeroes = True 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__unpacked_data_elms__ = struct.unpack(self.__format__, data) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in xrange(len(self.__unpacked_data_elms__)): 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key in self.__keys__[i]: 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# self.values[key] = self.__unpacked_data_elms__[i] 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setattr(self, key, self.__unpacked_data_elms__[i]) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __pack__(self): 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_values = [] 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in xrange(len(self.__unpacked_data_elms__)): 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key in self.__keys__[i]: 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_val = getattr(self, key) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_val = self.__unpacked_data_elms__[i] 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # In the case of Unions, when the first changed value 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # is picked the loop is exited 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if new_val != old_val: 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_values.append(new_val) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.pack(self.__format__, *new_values) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '\n'.join( self.dump() ) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __repr__(self): 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '<Structure: %s>' % (' '.join( [' '.join(s.split()) for s in self.dump()] )) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def dump(self, indentation=0): 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Returns a string representation of the structure.""" 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump = [] 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.append('[%s]' % self.name) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Refer to the __set_format__ method for an explanation 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # of the following construct. 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for keys in self.__keys__: 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key in keys: 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = getattr(self, key) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if isinstance(val, int) or isinstance(val, long): 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val_str = '0x%-8X' % (val) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if key == 'TimeDateStamp' or key == 'dwTimeStamp': 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val_str += ' [%s UTC]' % time.asctime(time.gmtime(val)) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except exceptions.ValueError, e: 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val_str += ' [INVALID TIME]' 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val_str = ''.join(filter(lambda c:c != '\0', str(val))) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.append('%-30s %s' % (key+':', val_str)) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dump 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SectionStructure(Structure): 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Convenience section handling class.""" 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_data(self, start, length=None): 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get data chunk from a section. 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Allows to query data from the section by passing the 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addresses where the PE file would be loaded by default. 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) It is then possible to retrieve code and data by its real 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addresses as it would be if loaded. 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = start - self.VirtualAddress 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if length: 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = offset+length 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = len(self.data) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.data[offset:end] 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_rva_from_offset(self, offset): 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offset - self.PointerToRawData + self.VirtualAddress 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_offset_from_rva(self, rva): 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (rva - self.VirtualAddress) + self.PointerToRawData 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def contains_offset(self, offset): 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Check whether the section contains the file offset provided.""" 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self.PointerToRawData: 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # bss and other sections containing only uninitialized data must have 0 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # and do not take space in the file 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.PointerToRawData <= offset < self.VirtualAddress + self.SizeOfRawData 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def contains_rva(self, rva): 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Check whether the section contains the address provided.""" 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # PECOFF documentation v8 says: 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # The total size of the section when loaded into memory. 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If this value is greater than SizeOfRawData, the section is zero-padded. 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # This field is valid only for executable images and should be set to zero 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # for object files. 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(self.data) < self.SizeOfRawData: 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = self.Misc_VirtualSize 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = max(self.SizeOfRawData, self.Misc_VirtualSize) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.VirtualAddress <= rva < self.VirtualAddress + size 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def contains(self, rva): 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #print "DEPRECATION WARNING: you should use contains_rva() instead of contains()" 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.contains_rva(rva) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_data(self, data): 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Set the data belonging to the section.""" 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.data = data 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_entropy(self): 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Calculate and return the entropy for the section.""" 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.entropy_H( self.data ) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_hash_sha1(self): 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the SHA-1 hex-digest of the section's data.""" 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sha1 is not None: 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sha1( self.data ).hexdigest() 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_hash_sha256(self): 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the SHA-256 hex-digest of the section's data.""" 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sha256 is not None: 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sha256( self.data ).hexdigest() 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_hash_sha512(self): 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the SHA-512 hex-digest of the section's data.""" 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sha512 is not None: 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sha512( self.data ).hexdigest() 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_hash_md5(self): 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the MD5 hex-digest of the section's data.""" 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if md5 is not None: 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return md5( self.data ).hexdigest() 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def entropy_H(self, data): 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Calculate the entropy of a chunk of data.""" 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(data) == 0: 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0.0 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) occurences = array.array('L', [0]*256) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for x in data: 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) occurences[ord(x)] += 1 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entropy = 0 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for x in occurences: 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if x: 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p_x = float(x) / len(data) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entropy -= p_x*math.log(p_x, 2) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entropy 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DataContainer: 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Generic data container.""" 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, **args): 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key, value in args.items(): 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setattr(self, key, value) 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImportDescData(DataContainer): 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds import descriptor information. 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll: name of the imported DLL 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imports: list of imported symbols (ImportData instances) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_IMPORT_DESCRIPTOR sctruture 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImportData(DataContainer): 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds imported symbol's information. 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinal: Ordinal of the symbol 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name: Name of the symbol 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bound: If the symbol is bound, this contains 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the address. 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExportDirData(DataContainer): 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds export directory information. 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_EXPORT_DIRECTORY structure 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbols: list of exported symbols (ExportData instances) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExportData(DataContainer): 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds exported symbols' information. 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinal: ordinal of the symbol 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address: address of the symbol 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name: name of the symbol (None if the symbol is 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exported by ordinal only) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder: if the symbol is forwarded it will 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contain the name of the target symbol, 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None otherwise. 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResourceDirData(DataContainer): 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds resource directory information. 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_RESOURCE_DIRECTORY structure 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries: list of entries (ResourceDirEntryData instances) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResourceDirEntryData(DataContainer): 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds resource directory entry data. 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_RESOURCE_DIRECTORY_ENTRY structure 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name: If the resource is identified by name this 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute will contain the name string. None 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) otherwise. If identified by id, the id is 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) availabe at 'struct.Id' 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id: the id, also in struct.Id 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory: If this entry has a lower level directory 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this attribute will point to the 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceDirData instance representing it. 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data: If this entry has no futher lower directories 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) and points to the actual resource data, this 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute will reference the corresponding 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceDataEntryData instance. 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (Either of the 'directory' or 'data' attribute will exist, 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) but not both.) 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResourceDataEntryData(DataContainer): 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds resource data entry information. 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_RESOURCE_DATA_ENTRY structure 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lang: Primary language ID 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sublang: Sublanguage ID 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DebugData(DataContainer): 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds debug information. 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_DEBUG_DIRECTORY structure 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BaseRelocationData(DataContainer): 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds base relocation information. 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_BASE_RELOCATION structure 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries: list of relocation data (RelocationData instances) 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RelocationData(DataContainer): 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds relocation information. 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type: Type of relocation 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The type string is can be obtained by 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RELOCATION_TYPE[type] 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva: RVA of the relocation 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TlsData(DataContainer): 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds TLS information. 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_TLS_DIRECTORY structure 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BoundImportDescData(DataContainer): 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds bound import descriptor data. 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This directory entry will provide with information on the 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLLs this PE files has been bound to (if bound at all). 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The structure will contain the name and timestamp of the 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLL at the time of binding so that the loader can know 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whether it differs from the one currently present in the 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system and must, therefore, re-bind the PE's imports. 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_BOUND_IMPORT_DESCRIPTOR structure 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name: DLL name 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries: list of entries (BoundImportRefData instances) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the entries will exist if this DLL has forwarded 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbols. If so, the destination DLL will have an 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry in this list. 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BoundImportRefData(DataContainer): 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Holds bound import forwader reference data. 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Contains the same information as the bound descriptor but 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for forwarded DLLs, if any. 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct: IMAGE_BOUND_FORWARDER_REF structure 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name: dll name 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PE: 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """A Portable Executable representation. 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This class provides access to most of the information in a PE file. 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) It expects to be supplied the name of the file to load or PE data 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to process and an optional argument 'fast_load' (False by default) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) which controls whether to load all the directories information, 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) which can be quite time consuming. 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pe = pefile.PE('module.dll') 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pe = pefile.PE(name='module.dll') 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) would load 'module.dll' and process it. If the data would be already 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) available in a buffer the same could be achieved with: 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pe = pefile.PE(data=module_dll_data) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The "fast_load" can be set to a default by setting its value in the 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module itself by means,for instance, of a "pefile.fast_load = True". 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) That will make all the subsequent instances not to load the 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whole PE structure. The "full_load" method can be used to parse 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the missing data at a later stage. 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Basic headers information will be available in the attributes: 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DOS_HEADER 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NT_HEADERS 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_HEADER 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPTIONAL_HEADER 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) All of them will contain among their attrbitues the members of the 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) corresponding structures as defined in WINNT.H 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The raw data corresponding to the header (from the beginning of the 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file up to the start of the first section) will be avaiable in the 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance's attribute 'header' as a string. 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The sections will be available as a list in the 'sections' attribute. 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Each entry will contain as attributes all the structure's members. 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Directory entries will be available as attributes (if they exist): 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (no other entries are processed at this point) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY_IMPORT (list of ImportDescData instances) 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY_EXPORT (ExportDirData instance) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY_RESOURCE (ResourceDirData instance) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY_DEBUG (list of DebugData instances) 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY_BASERELOC (list of BaseRelocationData instances) 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY_TLS 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY_BOUND_IMPORT (list of BoundImportData instances) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The following dictionary attributes provide ways of mapping different 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constants. They will accept the numeric value and return the string 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation and the opposite, feed in the string and get the 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) numeric constant: 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IMAGE_CHARACTERISTICS 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECTION_CHARACTERISTICS 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEBUG_TYPE 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SUBSYSTEM_TYPE 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MACHINE_TYPE 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RELOCATION_TYPE 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESOURCE_TYPE 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LANG 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SUBLANG 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Format specifications for PE structures. 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_DOS_HEADER_format__ = ('IMAGE_DOS_HEADER', 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,e_magic', 'H,e_cblp', 'H,e_cp', 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,e_crlc', 'H,e_cparhdr', 'H,e_minalloc', 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,e_maxalloc', 'H,e_ss', 'H,e_sp', 'H,e_csum', 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,e_ip', 'H,e_cs', 'H,e_lfarlc', 'H,e_ovno', '8s,e_res', 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,e_oemid', 'H,e_oeminfo', '20s,e_res2', 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,e_lfanew')) 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_FILE_HEADER_format__ = ('IMAGE_FILE_HEADER', 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,Machine', 'H,NumberOfSections', 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,TimeDateStamp', 'L,PointerToSymbolTable', 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,NumberOfSymbols', 'H,SizeOfOptionalHeader', 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,Characteristics')) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_DATA_DIRECTORY_format__ = ('IMAGE_DATA_DIRECTORY', 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,VirtualAddress', 'L,Size')) 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_OPTIONAL_HEADER_format__ = ('IMAGE_OPTIONAL_HEADER', 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,Magic', 'B,MajorLinkerVersion', 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'B,MinorLinkerVersion', 'L,SizeOfCode', 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,SizeOfInitializedData', 'L,SizeOfUninitializedData', 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,AddressOfEntryPoint', 'L,BaseOfCode', 'L,BaseOfData', 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,ImageBase', 'L,SectionAlignment', 'L,FileAlignment', 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,MajorOperatingSystemVersion', 'H,MinorOperatingSystemVersion', 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,MajorImageVersion', 'H,MinorImageVersion', 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,MajorSubsystemVersion', 'H,MinorSubsystemVersion', 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,Reserved1', 'L,SizeOfImage', 'L,SizeOfHeaders', 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,CheckSum', 'H,Subsystem', 'H,DllCharacteristics', 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,SizeOfStackReserve', 'L,SizeOfStackCommit', 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,SizeOfHeapReserve', 'L,SizeOfHeapCommit', 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,LoaderFlags', 'L,NumberOfRvaAndSizes' )) 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_OPTIONAL_HEADER64_format__ = ('IMAGE_OPTIONAL_HEADER64', 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,Magic', 'B,MajorLinkerVersion', 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'B,MinorLinkerVersion', 'L,SizeOfCode', 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,SizeOfInitializedData', 'L,SizeOfUninitializedData', 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,AddressOfEntryPoint', 'L,BaseOfCode', 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Q,ImageBase', 'L,SectionAlignment', 'L,FileAlignment', 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,MajorOperatingSystemVersion', 'H,MinorOperatingSystemVersion', 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,MajorImageVersion', 'H,MinorImageVersion', 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,MajorSubsystemVersion', 'H,MinorSubsystemVersion', 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,Reserved1', 'L,SizeOfImage', 'L,SizeOfHeaders', 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,CheckSum', 'H,Subsystem', 'H,DllCharacteristics', 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Q,SizeOfStackReserve', 'Q,SizeOfStackCommit', 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Q,SizeOfHeapReserve', 'Q,SizeOfHeapCommit', 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,LoaderFlags', 'L,NumberOfRvaAndSizes' )) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_NT_HEADERS_format__ = ('IMAGE_NT_HEADERS', ('L,Signature',)) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_SECTION_HEADER_format__ = ('IMAGE_SECTION_HEADER', 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('8s,Name', 'L,Misc,Misc_PhysicalAddress,Misc_VirtualSize', 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,VirtualAddress', 'L,SizeOfRawData', 'L,PointerToRawData', 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,PointerToRelocations', 'L,PointerToLinenumbers', 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,NumberOfRelocations', 'H,NumberOfLinenumbers', 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,Characteristics')) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_DELAY_IMPORT_DESCRIPTOR_format__ = ('IMAGE_DELAY_IMPORT_DESCRIPTOR', 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,grAttrs', 'L,szName', 'L,phmod', 'L,pIAT', 'L,pINT', 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,pBoundIAT', 'L,pUnloadIAT', 'L,dwTimeStamp')) 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_IMPORT_DESCRIPTOR_format__ = ('IMAGE_IMPORT_DESCRIPTOR', 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,OriginalFirstThunk,Characteristics', 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,TimeDateStamp', 'L,ForwarderChain', 'L,Name', 'L,FirstThunk')) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_EXPORT_DIRECTORY_format__ = ('IMAGE_EXPORT_DIRECTORY', 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,Characteristics', 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,TimeDateStamp', 'H,MajorVersion', 'H,MinorVersion', 'L,Name', 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,Base', 'L,NumberOfFunctions', 'L,NumberOfNames', 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,AddressOfFunctions', 'L,AddressOfNames', 'L,AddressOfNameOrdinals')) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_RESOURCE_DIRECTORY_format__ = ('IMAGE_RESOURCE_DIRECTORY', 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,Characteristics', 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,TimeDateStamp', 'H,MajorVersion', 'H,MinorVersion', 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,NumberOfNamedEntries', 'H,NumberOfIdEntries')) 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_RESOURCE_DIRECTORY_ENTRY_format__ = ('IMAGE_RESOURCE_DIRECTORY_ENTRY', 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,Name', 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,OffsetToData')) 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_RESOURCE_DATA_ENTRY_format__ = ('IMAGE_RESOURCE_DATA_ENTRY', 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,OffsetToData', 'L,Size', 'L,CodePage', 'L,Reserved')) 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __VS_VERSIONINFO_format__ = ( 'VS_VERSIONINFO', 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,Length', 'H,ValueLength', 'H,Type' )) 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __VS_FIXEDFILEINFO_format__ = ( 'VS_FIXEDFILEINFO', 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,Signature', 'L,StrucVersion', 'L,FileVersionMS', 'L,FileVersionLS', 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,ProductVersionMS', 'L,ProductVersionLS', 'L,FileFlagsMask', 'L,FileFlags', 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,FileOS', 'L,FileType', 'L,FileSubtype', 'L,FileDateMS', 'L,FileDateLS')) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __StringFileInfo_format__ = ( 'StringFileInfo', 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,Length', 'H,ValueLength', 'H,Type' )) 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __StringTable_format__ = ( 'StringTable', 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,Length', 'H,ValueLength', 'H,Type' )) 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __String_format__ = ( 'String', 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('H,Length', 'H,ValueLength', 'H,Type' )) 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __Var_format__ = ( 'Var', ('H,Length', 'H,ValueLength', 'H,Type' )) 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_THUNK_DATA_format__ = ('IMAGE_THUNK_DATA', 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,ForwarderString,Function,Ordinal,AddressOfData',)) 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_THUNK_DATA64_format__ = ('IMAGE_THUNK_DATA', 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Q,ForwarderString,Function,Ordinal,AddressOfData',)) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_DEBUG_DIRECTORY_format__ = ('IMAGE_DEBUG_DIRECTORY', 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,Characteristics', 'L,TimeDateStamp', 'H,MajorVersion', 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'H,MinorVersion', 'L,Type', 'L,SizeOfData', 'L,AddressOfRawData', 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,PointerToRawData')) 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_BASE_RELOCATION_format__ = ('IMAGE_BASE_RELOCATION', 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,VirtualAddress', 'L,SizeOfBlock') ) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_TLS_DIRECTORY_format__ = ('IMAGE_TLS_DIRECTORY', 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,StartAddressOfRawData', 'L,EndAddressOfRawData', 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,AddressOfIndex', 'L,AddressOfCallBacks', 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,SizeOfZeroFill', 'L,Characteristics' ) ) 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_TLS_DIRECTORY64_format__ = ('IMAGE_TLS_DIRECTORY', 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Q,StartAddressOfRawData', 'Q,EndAddressOfRawData', 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Q,AddressOfIndex', 'Q,AddressOfCallBacks', 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'L,SizeOfZeroFill', 'L,Characteristics' ) ) 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_BOUND_IMPORT_DESCRIPTOR_format__ = ('IMAGE_BOUND_IMPORT_DESCRIPTOR', 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,TimeDateStamp', 'H,OffsetModuleName', 'H,NumberOfModuleForwarderRefs')) 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __IMAGE_BOUND_FORWARDER_REF_format__ = ('IMAGE_BOUND_FORWARDER_REF', 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('L,TimeDateStamp', 'H,OffsetModuleName', 'H,Reserved') ) 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, name=None, data=None, fast_load=None): 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.sections = [] 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings = [] 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.PE_TYPE = None 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not name and not data: 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # This list will keep track of all the structures created. 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # That will allow for an easy iteration through the list 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # in order to save the modifications made 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__structures__ = [] 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not fast_load: 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fast_load = globals()['fast_load'] 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__parse__(name, data, fast_load) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __unpack_data__(self, format, data, file_offset): 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Apply structure format to raw data. 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns and unpacked structure object if successful, None otherwise. 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) structure = Structure(format, file_offset=file_offset) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if len(data) < structure.sizeof(): 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # return None 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) structure.__unpack__(data) 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, err: 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Corrupt header "%s" at file offset %d. Exception: %s' % ( 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format[0], file_offset, str(err)) ) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__structures__.append(structure) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return structure 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __parse__(self, fname, data, fast_load): 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse a Portable Executable file. 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Loads a PE file, parsing all its structures and making them available 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) through the instance's attributes. 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if fname: 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = file(fname, 'rb') 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__ = fd.read() 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd.close() 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif data: 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__ = data 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.DOS_HEADER = self.__unpack_data__( 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_DOS_HEADER_format__, 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__, file_offset=0) 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self.DOS_HEADER or self.DOS_HEADER.e_magic != IMAGE_DOS_SIGNATURE: 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError('DOS Header magic not found.') 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Check for sane value in e_lfanew 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.DOS_HEADER.e_lfanew > len(self.__data__): 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError('Invalid e_lfanew value, probably not a PE file') 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nt_headers_offset = self.DOS_HEADER.e_lfanew 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.NT_HEADERS = self.__unpack_data__( 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_NT_HEADERS_format__, 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__[nt_headers_offset:], 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = nt_headers_offset) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # We better check the signature right here, before the file screws 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # around with sections: 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Some malware will cause the Signature value to not exist at all 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self.NT_HEADERS or not self.NT_HEADERS.Signature: 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError('NT Headers not found.') 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.NT_HEADERS.Signature != IMAGE_NT_SIGNATURE: 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError('Invalid NT Headers signature.') 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.FILE_HEADER = self.__unpack_data__( 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_FILE_HEADER_format__, 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__[nt_headers_offset+4:], 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = nt_headers_offset+4) 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_flags = self.retrieve_flags(IMAGE_CHARACTERISTICS, 'IMAGE_FILE_') 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self.FILE_HEADER: 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError('File Header missing') 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the image's flags according the the Characteristics member 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_flags(self.FILE_HEADER, self.FILE_HEADER.Characteristics, image_flags) 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) optional_header_offset = \ 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nt_headers_offset+4+self.FILE_HEADER.sizeof() 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Note: location of sections can be controlled from PE header: 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sections_offset = optional_header_offset + self.FILE_HEADER.SizeOfOptionalHeader 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER = self.__unpack_data__( 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_OPTIONAL_HEADER_format__, 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__[optional_header_offset:], 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = optional_header_offset) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # According to solardesigner's findings for his 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Tiny PE project, the optional header does not 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # need fields beyond "Subsystem" in order to be 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # loadable by the Windows loader (given that zeroes 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # are acceptable values and the header is loaded 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # in a zeroed memory page) 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If trying to parse a full Optional Header fails 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # we try to parse it again with some 0 padding 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MINIMUM_VALID_OPTIONAL_HEADER_RAW_SIZE = 69 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( self.OPTIONAL_HEADER is None and 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len(self.__data__[optional_header_offset:]) 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) >= MINIMUM_VALID_OPTIONAL_HEADER_RAW_SIZE ): 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Add enough zeroes to make up for the unused fields 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding_length = 128 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Create padding 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padded_data = self.__data__[optional_header_offset:] + ( 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '\0' * padding_length) 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER = self.__unpack_data__( 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_OPTIONAL_HEADER_format__, 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padded_data, 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = optional_header_offset) 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Check the Magic in the OPTIONAL_HEADER and set the PE file 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # type accordingly 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.OPTIONAL_HEADER is not None: 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.OPTIONAL_HEADER.Magic == OPTIONAL_HEADER_MAGIC_PE: 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.PE_TYPE = OPTIONAL_HEADER_MAGIC_PE 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif self.OPTIONAL_HEADER.Magic == OPTIONAL_HEADER_MAGIC_PE_PLUS: 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.PE_TYPE = OPTIONAL_HEADER_MAGIC_PE_PLUS 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER = self.__unpack_data__( 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_OPTIONAL_HEADER64_format__, 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__[optional_header_offset:], 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = optional_header_offset) 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Again, as explained above, we try to parse 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # a reduced form of the Optional Header which 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # is still valid despite not including all 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # structure members 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MINIMUM_VALID_OPTIONAL_HEADER_RAW_SIZE = 69+4 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( self.OPTIONAL_HEADER is None and 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len(self.__data__[optional_header_offset:]) 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) >= MINIMUM_VALID_OPTIONAL_HEADER_RAW_SIZE ): 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding_length = 128 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padded_data = self.__data__[optional_header_offset:] + ( 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '\0' * padding_length) 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER = self.__unpack_data__( 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_OPTIONAL_HEADER64_format__, 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padded_data, 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = optional_header_offset) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self.FILE_HEADER: 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError('File Header missing') 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Die gracefully if there is no OPTIONAL_HEADER field 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 975440f5ad5e2e4a92c4d9a5f22f75c1 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.PE_TYPE is None or self.OPTIONAL_HEADER is None: 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError("No Optional Header found, invalid PE32 or PE32+ file") 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll_characteristics_flags = self.retrieve_flags(DLL_CHARACTERISTICS, 'IMAGE_DLL_CHARACTERISTICS_') 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the Dll Characteristics flags according the the DllCharacteristics member 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_flags( 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER, 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER.DllCharacteristics, 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll_characteristics_flags) 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER.DATA_DIRECTORY = [] 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #offset = (optional_header_offset + self.FILE_HEADER.SizeOfOptionalHeader) 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = (optional_header_offset + self.OPTIONAL_HEADER.sizeof()) 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.NT_HEADERS.FILE_HEADER = self.FILE_HEADER 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.NT_HEADERS.OPTIONAL_HEADER = self.OPTIONAL_HEADER 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # The NumberOfRvaAndSizes is sanitized to stay within 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # reasonable limits so can be casted to an int 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.OPTIONAL_HEADER.NumberOfRvaAndSizes > 0x10: 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Suspicious NumberOfRvaAndSizes in the Optional Header. ' + 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Normal values are never larger than 0x10, the value is: 0x%x' % 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER.NumberOfRvaAndSizes ) 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in xrange(int(0x7fffffffL & self.OPTIONAL_HEADER.NumberOfRvaAndSizes)): 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(self.__data__[offset:]) == 0: 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(self.__data__[offset:]) < 8: 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.__data__[offset:]+'\0'*8 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.__data__[offset:] 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dir_entry = self.__unpack_data__( 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_DATA_DIRECTORY_format__, 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = offset) 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if dir_entry is None: 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Would fail if missing an entry 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 1d4937b2fa4d84ad1bce0309857e70ca offending sample 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dir_entry.name = DIRECTORY_ENTRY[i] 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except (KeyError, AttributeError): 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += dir_entry.sizeof() 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER.DATA_DIRECTORY.append(dir_entry) 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the offset goes outside the optional header, 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the loop is broken, regardless of how many directories 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # NumberOfRvaAndSizes says there are 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # We assume a normally sized optional header, hence that we do 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # a sizeof() instead of reading SizeOfOptionalHeader. 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Then we add a default number of drectories times their size, 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # if we go beyond that, we assume the number of directories 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # is wrong and stop processing 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if offset >= (optional_header_offset + 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER.sizeof() + 8*16) : 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = self.parse_sections(sections_offset) 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # There could be a problem if there are no raw data sections 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # greater than 0 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # fc91013eb72529da005110a3403541b6 example 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Should this throw an exception in the minimum header offset 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # can't be found? 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rawDataPointers = [ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.PointerToRawData for s in self.sections if s.PointerToRawData>0] 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(rawDataPointers) > 0: 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lowest_section_offset = min(rawDataPointers) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lowest_section_offset = None 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not lowest_section_offset or lowest_section_offset<offset: 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.header = self.__data__[:offset] 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.header = self.__data__[:lowest_section_offset] 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Check whether the entry point lies within a section 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.get_section_by_rva(self.OPTIONAL_HEADER.AddressOfEntryPoint) is not None: 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Check whether the entry point lies within the file 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ep_offset = self.get_offset_from_rva(self.OPTIONAL_HEADER.AddressOfEntryPoint) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ep_offset > len(self.__data__): 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Possibly corrupt file. AddressOfEntryPoint lies outside the file. ' + 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'AddressOfEntryPoint: 0x%x' % 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER.AddressOfEntryPoint ) 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'AddressOfEntryPoint lies outside the sections\' boundaries. ' + 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'AddressOfEntryPoint: 0x%x' % 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.OPTIONAL_HEADER.AddressOfEntryPoint ) 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not fast_load: 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.parse_data_directories() 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_warnings(self): 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the list of warnings. 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Non-critical problems found when parsing the PE file are 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appended to a list of warnings. This method returns the 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full list. 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.__warnings 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def show_warnings(self): 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Print the list of warnings. 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Non-critical problems found when parsing the PE file are 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appended to a list of warnings. This method prints the 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full list to standard output. 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for warning in self.__warnings: 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print '>', warning 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def full_load(self): 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Process the data directories. 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This mathod will load the data directories which might not have 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) been loaded if the "fast_load" option was used. 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.parse_data_directories() 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def write(self, filename=None): 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Write the PE file. 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This function will process all headers and components 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) of the PE file and include all changes made (by just 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assigning to attributes in the PE objects) and write 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the changes back to a file whose name is provided as 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) an argument. The filename is optional. 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The data to be written to the file will be returned 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) as a 'str' object. 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_data = list(self.__data__) 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for struct in self.__structures__: 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct_data = list(struct.__pack__()) 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = struct.get_file_offset() 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_data[offset:offset+len(struct_data)] = struct_data 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'VS_VERSIONINFO'): 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'FileInfo'): 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for entry in self.FileInfo: 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(entry, 'StringTable'): 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for st_entry in entry.StringTable: 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key, entry in st_entry.entries.items(): 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets = st_entry.entries_offsets[key] 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lengths = st_entry.entries_lengths[key] 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len( entry ) > lengths[1]: 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uc = zip( 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list(entry[:lengths[1]]), ['\0'] * lengths[1] ) 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = list() 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map(l.extend, uc) 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_data[ 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets[1] : offsets[1] + lengths[1]*2 ] = l 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uc = zip( 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list(entry), ['\0'] * len(entry) ) 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = list() 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map(l.extend, uc) 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_data[ 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets[1] : offsets[1] + len(entry)*2 ] = l 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remainder = lengths[1] - len(entry) 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_data[ 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets[1] + len(entry)*2 : 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets[1] + lengths[1]*2 ] = [ 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u'\0' ] * remainder*2 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_file_data = ''.join( [ chr(ord(c)) for c in file_data ] ) 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filename: 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f = file(filename, 'wb+') 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f.write(new_file_data) 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f.close() 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new_file_data 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_sections(self, offset): 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Fetch the PE file sections. 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The sections will be readily available in the "sections" attribute. 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Its attributes will contain all the section information plus "data" 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a buffer containing the section's data. 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The "Characteristics" member will be processed and attributes 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representing the section characteristics (with the 'IMAGE_SCN_' 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string trimmed from the constant's names) will be added to the 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section instance. 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Refer to the SectionStructure class for additional info. 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.sections = [] 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in xrange(self.FILE_HEADER.NumberOfSections): 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section = SectionStructure(self.__IMAGE_SECTION_HEADER_format__) 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not section: 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_offset = offset + section.sizeof() * i 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section.set_file_offset(section_offset) 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section.__unpack__(self.__data__[section_offset:]) 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__structures__.append(section) 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.SizeOfRawData > len(self.__data__): 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Error parsing section %d. ' % i) + 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'SizeOfRawData is larger than file.') 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.PointerToRawData > len(self.__data__): 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Error parsing section %d. ' % i) + 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'PointerToRawData points beyond the end of the file.') 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.Misc_VirtualSize > 0x10000000: 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Suspicious value found parsing section %d. ' % i) + 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'VirtualSize is extremely large > 256MiB.') 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.VirtualAddress > 0x10000000: 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Suspicious value found parsing section %d. ' % i) + 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'VirtualAddress is beyond 0x10000000.') 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Some packer used a non-aligned PointerToRawData in the sections, 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # which causes several common tools not to load the section data 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # properly as they blindly read from the indicated offset. 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # It seems that Windows will round the offset down to the largest 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # offset multiple of FileAlignment which is smaller than 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # PointerToRawData. The following code will do the same. 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #alignment = self.OPTIONAL_HEADER.FileAlignment 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_data_start = section.PointerToRawData 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( self.OPTIONAL_HEADER.FileAlignment != 0 and 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (section.PointerToRawData % self.OPTIONAL_HEADER.FileAlignment) != 0): 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Error parsing section %d. ' % i) + 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Suspicious value for FileAlignment in the Optional Header. ' + 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Normally the PointerToRawData entry of the sections\' structures ' + 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'is a multiple of FileAlignment, this might imply the file ' + 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'is trying to confuse tools which parse this incorrectly') 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_data_end = section_data_start+section.SizeOfRawData 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section.set_data(self.__data__[section_data_start:section_data_end]) 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_flags = self.retrieve_flags(SECTION_CHARACTERISTICS, 'IMAGE_SCN_') 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the section's flags according the the Characteristics member 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_flags(section, section.Characteristics, section_flags) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( section.__dict__.get('IMAGE_SCN_MEM_WRITE', False) and 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section.__dict__.get('IMAGE_SCN_MEM_EXECUTE', False) ): 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('Suspicious flags set for section %d. ' % i) + 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Both IMAGE_SCN_MEM_WRITE and IMAGE_SCN_MEM_EXECUTE are set.' + 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'This might indicate a packed executable.') 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.sections.append(section) 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.FILE_HEADER.NumberOfSections > 0 and self.sections: 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offset + self.sections[0].sizeof()*self.FILE_HEADER.NumberOfSections 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offset 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def retrieve_flags(self, flag_dict, flag_filter): 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Read the flags from a dictionary and return them in a usable form. 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Will return a list of (flag, value) for all flags in "flag_dict" 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matching the filter "flag_filter". 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [(f[0], f[1]) for f in flag_dict.items() if 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isinstance(f[0], str) and f[0].startswith(flag_filter)] 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_flags(self, obj, flag_field, flags): 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Will process the flags and set attributes in the object accordingly. 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The object "obj" will gain attritutes named after the flags provided in 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "flags" and valued True/False, matching the results of applyin each 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flag value from "flags" to flag_field. 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for flag in flags: 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if flag[1] & flag_field: 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setattr(obj, flag[0], True) 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setattr(obj, flag[0], False) 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_data_directories(self): 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse and process the PE file's data directories.""" 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory_parsing = ( 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_IMPORT', self.parse_import_directory), 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_EXPORT', self.parse_export_directory), 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_RESOURCE', self.parse_resources_directory), 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_DEBUG', self.parse_debug_directory), 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_BASERELOC', self.parse_relocations_directory), 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_TLS', self.parse_directory_tls), 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT', self.parse_delay_import_directory), 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT', self.parse_directory_bound_imports) ) 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for entry in directory_parsing: 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dir_entry = self.OPTIONAL_HEADER.DATA_DIRECTORY[ 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIRECTORY_ENTRY[entry[0]]] 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except IndexError: 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if dir_entry.VirtualAddress: 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = entry[1](dir_entry.VirtualAddress, dir_entry.Size) 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if value: 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setattr(self, entry[0][6:], value) 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_directory_bound_imports(self, rva, size): 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """""" 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bnd_descr = Structure(self.__IMAGE_BOUND_IMPORT_DESCRIPTOR_format__) 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bnd_descr_size = bnd_descr.sizeof() 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = rva 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bound_imports = [] 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bnd_descr = self.__unpack_data__( 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_BOUND_IMPORT_DESCRIPTOR_format__, 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__[rva:rva+bnd_descr_size], 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = rva) 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if bnd_descr is None: 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If can't parse directory then silently return. 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # This directory does not necesarily have to be valid to 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # still have a valid PE file 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'The Bound Imports directory exists but can\'t be parsed.') 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if bnd_descr.all_zeroes(): 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += bnd_descr.sizeof() 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_refs = [] 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(bnd_descr.NumberOfModuleForwarderRefs): 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Both structures IMAGE_BOUND_IMPORT_DESCRIPTOR and 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # IMAGE_BOUND_FORWARDER_REF have the same size. 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bnd_frwd_ref = self.__unpack_data__( 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_BOUND_FORWARDER_REF_format__, 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__[rva:rva+bnd_descr_size], 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = rva) 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not bnd_frwd_ref: 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError( 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "IMAGE_BOUND_FORWARDER_REF cannot be read") 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += bnd_frwd_ref.sizeof() 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name_str = self.get_string_from_data( 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start+bnd_frwd_ref.OffsetModuleName, self.__data__) 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not name_str: 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_refs.append(BoundImportRefData( 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = bnd_frwd_ref, 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = name_str)) 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name_str = self.get_string_from_data( 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start+bnd_descr.OffsetModuleName, self.__data__) 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not name_str: 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bound_imports.append( 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundImportDescData( 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = bnd_descr, 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = name_str, 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries = forwarder_refs)) 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bound_imports 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_directory_tls(self, rva, size): 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """""" 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.PE_TYPE == OPTIONAL_HEADER_MAGIC_PE: 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format = self.__IMAGE_TLS_DIRECTORY_format__ 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif self.PE_TYPE == OPTIONAL_HEADER_MAGIC_PE_PLUS: 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format = self.__IMAGE_TLS_DIRECTORY64_format__ 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tls_struct = self.__unpack_data__( 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format, 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.get_data(rva), 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = self.get_offset_from_rva(rva)) 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not tls_struct: 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TlsData( struct = tls_struct ) 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_relocations_directory(self, rva, size): 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """""" 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlc = Structure(self.__IMAGE_BASE_RELOCATION_format__) 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlc_size = rlc.sizeof() 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = rva+size 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relocations = [] 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while rva<end: 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Malware that has bad rva entries will cause an error. 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Just continue on after an exception 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlc = self.__unpack_data__( 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_BASE_RELOCATION_format__, 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.get_data(rva, rlc_size), 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = self.get_offset_from_rva(rva) ) 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError: 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid relocation information. Can\'t read ' + 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'data at RVA: 0x%x' % rva) 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rlc = None 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not rlc: 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reloc_entries = self.parse_relocations( 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva+rlc_size, rlc.VirtualAddress, rlc.SizeOfBlock-rlc_size) 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relocations.append( 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BaseRelocationData( 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = rlc, 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries = reloc_entries)) 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not rlc.SizeOfBlock: 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += rlc.SizeOfBlock 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return relocations 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_relocations(self, data_rva, rva, size): 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """""" 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(data_rva, size) 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries = [] 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(len(data)/2): 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) word = struct.unpack('<H', data[idx*2:(idx+1)*2])[0] 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reloc_type = (word>>12) 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reloc_offset = (word&0x0fff) 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries.append( 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RelocationData( 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = reloc_type, 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva = reloc_offset+rva)) 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entries 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_debug_directory(self, rva, size): 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """""" 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbg = Structure(self.__IMAGE_DEBUG_DIRECTORY_format__) 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbg_size = dbg.sizeof() 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug = [] 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(size/dbg_size): 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(rva+dbg_size*idx, dbg_size) 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid debug information. Can\'t read ' + 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'data at RVA: 0x%x' % rva) 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbg = self.__unpack_data__( 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_DEBUG_DIRECTORY_format__, 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, file_offset = self.get_offset_from_rva(rva+dbg_size*idx)) 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not dbg: 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug.append( 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugData( 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = dbg)) 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return debug 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_resources_directory(self, rva, size=0, base_rva = None, level = 0): 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse the resources directory. 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Given the rva of the resources directory, it will process all 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) its entries. 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The root will have the corresponding member of its structure, 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IMAGE_RESOURCE_DIRECTORY plus 'entries', a list of all the 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries in the directory. 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Those entries will have, correspondingly, all the structure's 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) members (IMAGE_RESOURCE_DIRECTORY_ENTRY) and an additional one, 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "directory", pointing to the IMAGE_RESOURCE_DIRECTORY structure 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representing upper layers of the tree. This one will also have 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) an 'entries' attribute, pointing to the 3rd, and last, level. 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Another directory with more entries. Those last entries will 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) have a new atribute (both 'leaf' or 'data_entry' can be used to 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access it). This structure finally points to the resource data. 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) All the members of this structure, IMAGE_RESOURCE_DATA_ENTRY, 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) are available as its attributes. 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_rva = rva 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if base_rva is None: 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_rva = rva 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resources_section = self.get_section_by_rva(rva) 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the RVA is invalid all would blow up. Some EXEs seem to be 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # specially nasty and have an invalid RVA. 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(rva) 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid resources directory. Can\'t read ' + 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'directory data at RVA: 0x%x' % rva) 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Get the resource directory structure, that is, the header 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # of the table preceding the actual entries 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_dir = self.__unpack_data__( 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_RESOURCE_DIRECTORY_format__, data, 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = self.get_offset_from_rva(rva) ) 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if resource_dir is None: 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If can't parse resources directory then silently return. 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # This directory does not necesarily have to be valid to 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # still have a valid PE file 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid resources directory. Can\'t parse ' + 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'directory data at RVA: 0x%x' % rva) 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dir_entries = [] 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Advance the rva to the positon immediately following the directory 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # table header and pointing to the first entry in the table 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += resource_dir.sizeof() 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_of_entries = ( 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_dir.NumberOfNamedEntries + 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_dir.NumberOfIdEntries ) 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings_to_postprocess = list() 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(number_of_entries): 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = self.parse_resource_entry(rva) 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if res is None: 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the resources directory, ' + 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Entry %d is invalid, RVA = 0x%x. ' % 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (idx, rva) ) 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_name = None 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_id = None 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If all named entries have been processed, only Id ones 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # remain 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if idx >= resource_dir.NumberOfNamedEntries: 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_id = res.Name 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset = base_rva+res.NameOffset 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #entry_name = self.get_string_u_at_rva(ustr_offset, max_length=16) 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_name = UnicodeStringWrapperPostProcessor(self, ustr_offset) 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings_to_postprocess.append(entry_name) 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the resources directory, ' + 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'attempting to read entry name. ' + 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Can\'t read unicode string at offset 0x%x' % 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ustr_offset) ) 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if res.DataIsDirectory: 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # One trick malware can do is to recursively reference 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the next directory. This causes hilarity to ensue when 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # trying to parse everything correctly. 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the original RVA given to this function is equal to 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the next one to parse, we assume that it's a trick. 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Instead of raising a PEFormatError this would skip some 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # reasonable data so we just break. 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 9ee4d0a0caf095314fd7041a3e4404dc is the offending sample 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if original_rva == (base_rva + res.OffsetToDirectory): 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_directory = self.parse_resources_directory( 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_rva+res.OffsetToDirectory, 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_rva=base_rva, level = level+1) 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not entry_directory: 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dir_entries.append( 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceDirEntryData( 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = res, 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = entry_name, 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id = entry_id, 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory = entry_directory)) 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = self.parse_resource_data_entry( 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_rva + res.OffsetToDirectory) 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if struct: 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_data = ResourceDataEntryData( 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = struct, 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lang = res.Name & 0xff, 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sublang = (res.Name>>8) & 0xff) 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dir_entries.append( 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceDirEntryData( 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = res, 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = entry_name, 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id = entry_id, 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = entry_data)) 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Check if this entry contains version information 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if level == 0 and res.Id == RESOURCE_TYPE['RT_VERSION']: 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(dir_entries)>0: 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_entry = dir_entries[-1] 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rt_version_struct = None 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rt_version_struct = last_entry.directory.entries[0].directory.entries[0].data.struct 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except: 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Maybe a malformed directory structure...? 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Lets ignore it 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pass 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if rt_version_struct is not None: 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.parse_version_information(rt_version_struct) 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += res.sizeof() 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_rvas = [s.get_rva() for s in strings_to_postprocess] 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_rvas.sort() 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx, s in enumerate(strings_to_postprocess): 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.render_pascal_16() 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_directory_data = ResourceDirData( 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = resource_dir, 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries = dir_entries) 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resource_directory_data 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_resource_data_entry(self, rva): 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse a data entry from the resources directory.""" 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the RVA is invalid all would blow up. Some EXEs seem to be 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # specially nasty and have an invalid RVA. 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(rva) 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing a resource directory data entry, ' + 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'the RVA is invalid: 0x%x' % ( rva ) ) 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_entry = self.__unpack_data__( 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_RESOURCE_DATA_ENTRY_format__, data, 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = self.get_offset_from_rva(rva) ) 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_entry 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_resource_entry(self, rva): 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse a directory entry from the resources directory.""" 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource = self.__unpack_data__( 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_RESOURCE_DIRECTORY_ENTRY_format__, self.get_data(rva), 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = self.get_offset_from_rva(rva) ) 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if resource is None: 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #resource.NameIsString = (resource.Name & 0x80000000L) >> 31 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource.NameOffset = resource.Name & 0x7FFFFFFFL 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource.__pad = resource.Name & 0xFFFF0000L 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource.Id = resource.Name & 0x0000FFFFL 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource.DataIsDirectory = (resource.OffsetToData & 0x80000000L) >> 31 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource.OffsetToDirectory = resource.OffsetToData & 0x7FFFFFFFL 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resource 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_version_information(self, version_struct): 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse version information structure. 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The date will be made available in three attributes of the PE object. 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VS_VERSIONINFO will contain the first three fields of the main structure: 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Length', 'ValueLength', and 'Type' 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VS_FIXEDFILEINFO will hold the rest of the fields, accessible as sub-attributes: 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Signature', 'StrucVersion', 'FileVersionMS', 'FileVersionLS', 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'ProductVersionMS', 'ProductVersionLS', 'FileFlagsMask', 'FileFlags', 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'FileOS', 'FileType', 'FileSubtype', 'FileDateMS', 'FileDateLS' 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileInfo is a list of all StringFileInfo and VarFileInfo structures. 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringFileInfo structures will have a list as an attribute named 'StringTable' 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing all the StringTable structures. Each of those structures contains a 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dictionary 'entries' with all the key/value version information string pairs. 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VarFileInfo structures will have a list as an attribute named 'Var' containing 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all Var structures. Each Var structure will have a dictionary as an attribute 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) named 'entry' which will contain the name and value of the Var. 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Retrieve the data for the version info resource 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_offset = self.get_offset_from_rva( version_struct.OffsetToData ) 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data = self.__data__[ start_offset : start_offset+version_struct.Size ] 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Map the main structure and the subsequent string 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) versioninfo_struct = self.__unpack_data__( 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__VS_VERSIONINFO_format__, raw_data, 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = start_offset ) 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if versioninfo_struct is None: 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset = version_struct.OffsetToData + versioninfo_struct.sizeof() 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) versioninfo_string = self.get_string_u_at_rva( ustr_offset ) 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the version information, ' + 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'attempting to read VS_VERSION_INFO string. Can\'t ' + 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'read unicode string at offset 0x%x' % ( 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset ) ) 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) versioninfo_string = None 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the structure does not contain the expected name, it's assumed to be invalid 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if versioninfo_string != u'VS_VERSION_INFO': 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append('Invalid VS_VERSION_INFO block') 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the PE object's VS_VERSIONINFO to this one 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.VS_VERSIONINFO = versioninfo_struct 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # The the Key attribute to point to the unicode string identifying the structure 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.VS_VERSIONINFO.Key = versioninfo_string 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Process the fixed version information, get the offset and structure 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixedfileinfo_offset = self.dword_align( 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) versioninfo_struct.sizeof() + 2 * (len(versioninfo_string) + 1), 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixedfileinfo_struct = self.__unpack_data__( 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__VS_FIXEDFILEINFO_format__, 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[fixedfileinfo_offset:], 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = start_offset+fixedfileinfo_offset ) 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not fixedfileinfo_struct: 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the PE object's VS_FIXEDFILEINFO to this one 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.VS_FIXEDFILEINFO = fixedfileinfo_struct 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Start parsing all the StringFileInfo and VarFileInfo structures 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Get the first one 23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_offset = self.dword_align( 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixedfileinfo_offset + fixedfileinfo_struct.sizeof(), 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_stringfileinfo_offset = stringfileinfo_offset 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set the PE object's attribute that will contain them all. 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.FileInfo = list() 23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Process the StringFileInfo/VarFileInfo struct 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_struct = self.__unpack_data__( 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__StringFileInfo_format__, 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[stringfileinfo_offset:], 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = start_offset+stringfileinfo_offset ) 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stringfileinfo_struct is None: 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing StringFileInfo/VarFileInfo struct' ) 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Get the subsequent string defining the structure. 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset = ( version_struct.OffsetToData + 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_offset + versioninfo_struct.sizeof() ) 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_string = self.get_string_u_at_rva( ustr_offset ) 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the version information, ' + 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'attempting to read StringFileInfo string. Can\'t ' + 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'read unicode string at offset 0x%x' % ( ustr_offset ) ) 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set such string as the Key attribute 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_struct.Key = stringfileinfo_string 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Append the structure to the PE object's list 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.FileInfo.append(stringfileinfo_struct) 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Parse a StringFileInfo entry 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stringfileinfo_string == u'StringFileInfo': 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stringfileinfo_struct.Type == 1 and stringfileinfo_struct.ValueLength == 0: 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_offset = self.dword_align( 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_offset + stringfileinfo_struct.sizeof() + 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2*(len(stringfileinfo_string)+1), 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_struct.StringTable = list() 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Process the String Table entries 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct = self.__unpack_data__( 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__StringTable_format__, 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[stringtable_offset:], 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = start_offset+stringtable_offset ) 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not stringtable_struct: 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset = ( version_struct.OffsetToData + stringtable_offset + 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.sizeof() ) 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_string = self.get_string_u_at_rva( ustr_offset ) 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the version information, ' + 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'attempting to read StringTable string. Can\'t ' + 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'read unicode string at offset 0x%x' % ( ustr_offset ) ) 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.LangID = stringtable_string 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.entries = dict() 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.entries_offsets = dict() 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.entries_lengths = dict() 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_struct.StringTable.append(stringtable_struct) 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_offset = self.dword_align( 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_offset + stringtable_struct.sizeof() + 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2*(len(stringtable_string)+1), 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Process all entries in the string table 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while entry_offset < stringtable_offset + stringtable_struct.Length: 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_struct = self.__unpack_data__( 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__String_format__, raw_data[entry_offset:], 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = start_offset+entry_offset ) 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not string_struct: 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset = ( version_struct.OffsetToData + entry_offset + 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_struct.sizeof() ) 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = self.get_string_u_at_rva( ustr_offset ) 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_offset = self.get_offset_from_rva( ustr_offset ) 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the version information, ' + 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'attempting to read StringTable Key string. Can\'t ' + 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'read unicode string at offset 0x%x' % ( ustr_offset ) ) 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_offset = self.dword_align( 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2*(len(key)+1) + entry_offset + string_struct.sizeof(), 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset = version_struct.OffsetToData + value_offset 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = self.get_string_u_at_rva( ustr_offset, 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_length = string_struct.ValueLength ) 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_offset = self.get_offset_from_rva( ustr_offset ) 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the version information, ' + 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'attempting to read StringTable Value string. ' + 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Can\'t read unicode string at offset 0x%x' % ( 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset ) ) 24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if string_struct.Length == 0: 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_offset = stringtable_offset + stringtable_struct.Length 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_offset = self.dword_align( 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_struct.Length+entry_offset, version_struct.OffsetToData) 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_as_char = [] 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for c in key: 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ord(c)>128: 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_as_char.append('\\x%02x' %ord(c)) 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_as_char.append(c) 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_as_char = ''.join(key_as_char) 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setattr(stringtable_struct, key_as_char, value) 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.entries[key] = value 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.entries_offsets[key] = (key_offset, value_offset) 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.entries_lengths[key] = (len(key), len(value)) 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_offset = self.dword_align( 24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringtable_struct.Length + stringtable_offset, 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stringtable_offset >= stringfileinfo_struct.Length: 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Parse a VarFileInfo entry 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stringfileinfo_string == u'VarFileInfo': 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varfileinfo_struct = stringfileinfo_struct 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varfileinfo_struct.name = 'VarFileInfo' 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if varfileinfo_struct.Type == 1 and varfileinfo_struct.ValueLength == 0: 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_offset = self.dword_align( 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_offset + varfileinfo_struct.sizeof() + 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2*(len(stringfileinfo_string)+1), 25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varfileinfo_struct.Var = list() 25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Process all entries 25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_struct = self.__unpack_data__( 25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__Var_format__, 25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[var_offset:], 25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = start_offset+var_offset ) 25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not var_struct: 25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustr_offset = ( version_struct.OffsetToData + var_offset + 25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_struct.sizeof() ) 25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_string = self.get_string_u_at_rva( ustr_offset ) 25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the version information, ' + 25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'attempting to read VarFileInfo Var string. ' + 25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Can\'t read unicode string at offset 0x%x' % (ustr_offset)) 25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varfileinfo_struct.Var.append(var_struct) 25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varword_offset = self.dword_align( 25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2*(len(var_string)+1) + var_offset + var_struct.sizeof(), 25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orig_varword_offset = varword_offset 25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while varword_offset < orig_varword_offset + var_struct.ValueLength: 25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) word1 = self.get_word_from_data( 25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[varword_offset:varword_offset+2], 0) 25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) word2 = self.get_word_from_data( 25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[varword_offset+2:varword_offset+4], 0) 25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varword_offset += 4 25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_struct.entry = {var_string: '0x%04x 0x%04x' % (word1, word2)} 25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_offset = self.dword_align( 25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_offset+var_struct.Length, version_struct.OffsetToData) 25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if var_offset <= var_offset+var_struct.Length: 25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Increment and align the offset 25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_offset = self.dword_align( 25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringfileinfo_struct.Length+stringfileinfo_offset, 25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_struct.OffsetToData) 25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Check if all the StringFileInfo and VarFileInfo items have been processed 25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stringfileinfo_struct.Length == 0 or stringfileinfo_offset >= versioninfo_struct.Length: 25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_export_directory(self, rva, size): 25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse the export directory. 25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Given the rva of the export directory, it will process all 25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) its entries. 25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The exports will be made available through a list "exports" 25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing a tuple with the following elements: 25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ordinal, symbol_address, symbol_name) 25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) And also through a dicionary "exports_by_ordinal" whose keys 25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will be the ordinals and the values tuples of the from: 25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (symbol_address, symbol_name) 25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The symbol addresses are relative, not absolute. 25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) export_dir = self.__unpack_data__( 25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_EXPORT_DIRECTORY_format__, self.get_data(rva), 25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_offset = self.get_offset_from_rva(rva) ) 25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError: 26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing export directory at RVA: 0x%x' % ( rva ) ) 26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not export_dir: 26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_of_names = self.get_data( 26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) export_dir.AddressOfNames, export_dir.NumberOfNames*4) 26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_of_name_ordinals = self.get_data( 26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) export_dir.AddressOfNameOrdinals, export_dir.NumberOfNames*4) 26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_of_functions = self.get_data( 26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) export_dir.AddressOfFunctions, export_dir.NumberOfFunctions*4) 26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError: 26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing export directory at RVA: 0x%x' % ( rva ) ) 26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exports = [] 26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in xrange(export_dir.NumberOfNames): 26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbol_name = self.get_string_at_rva( 26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.get_dword_from_data(address_of_names, i)) 26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbol_ordinal = self.get_word_from_data( 26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_of_name_ordinals, i) 26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if symbol_ordinal*4<len(address_of_functions): 26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbol_address = self.get_dword_from_data( 26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_of_functions, symbol_ordinal) 26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Corrupt? a bad pointer... we assume it's all 26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # useless, no exports 26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the funcion's rva points within the export directory 26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # it will point to a string with the forwarded symbol's string 26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # instead of pointing the the function start address. 26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if symbol_address>=rva and symbol_address<rva+size: 26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_str = self.get_string_at_rva(symbol_address) 26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_str = None 26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exports.append( 26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExportData( 26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinal = export_dir.Base+symbol_ordinal, 26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address = symbol_address, 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = symbol_name, 26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder = forwarder_str)) 26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinals = [exp.ordinal for exp in exports] 26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(export_dir.NumberOfFunctions): 26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not idx+export_dir.Base in ordinals: 26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbol_address = self.get_dword_from_data( 26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_of_functions, 26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx) 26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Checking for forwarder again. 26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if symbol_address>=rva and symbol_address<rva+size: 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_str = self.get_string_at_rva(symbol_address) 26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_str = None 26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exports.append( 26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExportData( 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinal = export_dir.Base+idx, 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address = symbol_address, 26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = None, 26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder = forwarder_str)) 26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExportDirData( 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = export_dir, 26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbols = exports) 26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def dword_align(self, offset, base): 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += base 26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (offset+3) - ((offset+3)%4) - base 26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_delay_import_directory(self, rva, size): 26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Walk and parse the delay import directory.""" 26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_descs = [] 26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the RVA is invalid all would blow up. Some PEs seem to be 26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # specially nasty and have an invalid RVA. 26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(rva) 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the Delay import directory at RVA: 0x%x' % ( rva ) ) 27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_desc = self.__unpack_data__( 27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_DELAY_IMPORT_DESCRIPTOR_format__, 27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, file_offset = self.get_offset_from_rva(rva) ) 27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the structure is all zeores, we reached the end of the list 27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not import_desc or import_desc.all_zeroes(): 27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += import_desc.sizeof() 27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_data = self.parse_imports( 27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_desc.pINT, 27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_desc.pIAT, 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None) 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the Delay import directory. ' + 27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid import data at RVA: 0x%x' % ( rva ) ) 27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not import_data: 27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll = self.get_string_at_rva(import_desc.szName) 27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if dll: 27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_descs.append( 27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportDescData( 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = import_desc, 27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imports = import_data, 27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll = dll)) 27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return import_descs 27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_import_directory(self, rva, size): 27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Walk and parse the import directory.""" 27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_descs = [] 27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the RVA is invalid all would blow up. Some EXEs seem to be 27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # specially nasty and have an invalid RVA. 27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(rva) 27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the Import directory at RVA: 0x%x' % ( rva ) ) 27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_desc = self.__unpack_data__( 27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__IMAGE_IMPORT_DESCRIPTOR_format__, 27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, file_offset = self.get_offset_from_rva(rva) ) 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the structure is all zeores, we reached the end of the list 27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not import_desc or import_desc.all_zeroes(): 27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += import_desc.sizeof() 27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_data = self.parse_imports( 27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_desc.OriginalFirstThunk, 27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_desc.FirstThunk, 27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_desc.ForwarderChain) 27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, excp: 27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the Import directory. ' + 27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid Import data at RVA: 0x%x' % ( rva ) ) 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #raise excp 27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not import_data: 27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll = self.get_string_at_rva(import_desc.Name) 27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if dll: 27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_descs.append( 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportDescData( 27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct = import_desc, 27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imports = import_data, 27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll = dll)) 27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return import_descs 27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def parse_imports(self, original_first_thunk, first_thunk, forwarder_chain): 27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Parse the imported symbols. 27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) It will fill a list, which will be avalable as the dictionary 27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute "imports". Its keys will be the DLL names and the values 28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all the symbols imported from that object. 28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imported_symbols = [] 28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imports_section = self.get_section_by_rva(first_thunk) 28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not imports_section: 28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError, 'Invalid/corrupt imports.' 28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Import Lookup Table. Contains ordinals or pointers to strings. 28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ilt = self.get_import_table(original_first_thunk) 28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Import Address Table. May have identical content to ILT if 28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # PE file is not bounded, Will contain the address of the 28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # imported symbols once the binary is loaded or if it is already 28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # bound. 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iat = self.get_import_table(first_thunk) 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch: 28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Would crash if iat or ilt had None type 28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not iat and not ilt: 28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError( 28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid Import Table information. ' + 28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Both ILT and IAT appear to be broken.') 28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not iat and ilt: 28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table = ilt 28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif iat and not ilt: 28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table = iat 28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif ilt and ((len(ilt) and len(iat)==0) or (len(ilt) == len(iat))): 28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table = ilt 28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif (ilt and len(ilt))==0 and (iat and len(iat)): 28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table = iat 28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(len(table)): 28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_ord = None 28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_hint = None 28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_name = None 28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hint_name_table_rva = None 28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if table[idx].AddressOfData: 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.PE_TYPE == OPTIONAL_HEADER_MAGIC_PE: 28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinal_flag = IMAGE_ORDINAL_FLAG 28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif self.PE_TYPE == OPTIONAL_HEADER_MAGIC_PE_PLUS: 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinal_flag = IMAGE_ORDINAL_FLAG64 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If imported by ordinal, we will append the ordinal number 28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if table[idx].AddressOfData & ordinal_flag: 28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_by_ordinal = True 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_ord = table[idx].AddressOfData & 0xffff 28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_name = None 28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_by_ordinal = False 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hint_name_table_rva = table[idx].AddressOfData & 0x7fffffff 28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(hint_name_table_rva, 2) 28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Get the Hint 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_hint = self.get_word_from_data(data, 0) 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_name = self.get_string_at_rva(table[idx].AddressOfData+2) 28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pass 28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_address = first_thunk+self.OPTIONAL_HEADER.ImageBase+idx*4 28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if iat and ilt and ilt[idx].AddressOfData != iat[idx].AddressOfData: 28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_bound = iat[idx].AddressOfData 28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imp_bound = None 28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if imp_name != '' and (imp_ord or imp_name): 28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imported_symbols.append( 28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportData( 28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import_by_ordinal = import_by_ordinal, 28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ordinal = imp_ord, 28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hint = imp_hint, 28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = imp_name, 28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bound = imp_bound, 28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address = imp_address, 28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hint_name_table_rva = hint_name_table_rva)) 28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return imported_symbols 28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_import_table(self, rva): 28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table = [] 28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True and rva: 28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(rva) 28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__warnings.append( 28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Error parsing the import table. ' + 28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Invalid data at RVA: 0x%x' % ( rva ) ) 28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.PE_TYPE == OPTIONAL_HEADER_MAGIC_PE: 29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format = self.__IMAGE_THUNK_DATA_format__ 29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif self.PE_TYPE == OPTIONAL_HEADER_MAGIC_PE_PLUS: 29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format = self.__IMAGE_THUNK_DATA64_format__ 29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk_data = self.__unpack_data__( 29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format, data, file_offset=self.get_offset_from_rva(rva) ) 29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not thunk_data or thunk_data.all_zeroes(): 29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rva += thunk_data.sizeof() 29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table.append(thunk_data) 29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return table 29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_memory_mapped_image(self, max_virtual_address=0x10000000, ImageBase=None): 29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Returns the data corresponding to the memory layout of the PE file. 29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The data includes the PE header and the sections loaded at offsets 29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) corresponding to their relative virtual addresses. (the VirtualAddress 29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section header member). 29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Any offset in this data corresponds to the absolute memory address 29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageBase+offset. 29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The optional argument 'max_virtual_address' provides with means of limiting 29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) which section are processed. 29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Any section with their VirtualAddress beyond this value will be skipped. 29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Normally, sections with values beyond this range are just there to confuse 29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tools. It's a common trick to see in packed executables. 29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) If the 'ImageBase' optional argument is supplied, the file's relocations 29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will be applied to the image by calling the 'relocate_image()' method. 29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Collect all sections in one code block 29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.header 29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for section in self.sections: 29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Miscellanous integrity tests. 29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Some packer will set these to bogus values to 29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # make tools go nuts. 29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.Misc_VirtualSize == 0 or section.SizeOfRawData == 0: 29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.SizeOfRawData > len(self.__data__): 29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.PointerToRawData > len(self.__data__): 29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if section.VirtualAddress >= max_virtual_address: 29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding_length = section.VirtualAddress - len(data) 29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if padding_length>0: 29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data += '\0'*padding_length 29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif padding_length<0: 29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = data[:padding_length] 29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data += section.data 29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data 29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_data(self, rva, length=None): 29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get data regardless of the section where it lies on. 29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Given a rva and the size of the chunk to retrieve, this method 29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will find the section where the data lies and return the data. 29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = self.get_section_by_rva(rva) 29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not s: 29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if rva<len(self.header): 29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if length: 29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = rva+length 29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = None 29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.header[rva:end] 29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError, 'data at RVA can\'t be fetched. Corrupt header?' 29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.get_data(rva, length) 29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_rva_from_offset(self, offset): 29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the rva corresponding to this file offset. """ 29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = self.get_section_by_offset(offset) 29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not s: 29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError("specified offset (0x%x) doesn't belong to any section." % offset) 29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.get_rva_from_offset(offset) 29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_offset_from_rva(self, rva): 30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the file offset corresponding to this rva. 30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Given a rva , this method will find the section where the 30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data lies and return the offset within the file. 30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = self.get_section_by_rva(rva) 30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not s: 30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise PEFormatError, 'data at RVA can\'t be fetched. Corrupt header?' 30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.get_offset_from_rva(rva) 30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_string_at_rva(self, rva): 30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get an ASCII string located at the given address.""" 30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = self.get_section_by_rva(rva) 30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not s: 30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if rva<len(self.header): 30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_string_from_data(rva, self.header) 30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_string_from_data(rva-s.VirtualAddress, s.data) 30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_string_from_data(self, offset, data): 30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get an ASCII string from within the data.""" 30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch 30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = None 30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = data[offset] 30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except IndexError: 30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '' 30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = '' 30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ord(b): 30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s += b 30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += 1 30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = data[offset] 30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except IndexError: 30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s 30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_string_u_at_rva(self, rva, max_length = 2**16): 30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get an Unicode string located at the given address.""" 30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the RVA is invalid all would blow up. Some EXEs seem to be 30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # specially nasty and have an invalid RVA. 30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = self.get_data(rva, 2) 30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError, e: 30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #length = struct.unpack('<H', data)[0] 30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = u'' 30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(max_length): 30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uchr = struct.unpack('<H', self.get_data(rva+2*idx, 2))[0] 30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except struct.error: 30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if unichr(uchr) == u'\0': 30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s += unichr(uchr) 30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s 30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_section_by_offset(self, offset): 30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the section containing the given file offset.""" 30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sections = [s for s in self.sections if s.contains_offset(offset)] 30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sections: 30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sections[0] 30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_section_by_rva(self, rva): 30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Get the section containing the given address.""" 30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sections = [s for s in self.sections if s.contains_rva(rva)] 30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sections: 30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sections[0] 30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.dump_info() 30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def print_info(self): 31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Print all the PE header information in a human readable from.""" 31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print self.dump_info() 31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def dump_info(self, dump=None): 31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Dump all the PE header information into human readable string.""" 31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if dump is None: 31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump = Dump() 31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) warnings = self.get_warnings() 31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if warnings: 31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Parsing Warnings') 31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for warning in warnings: 31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(warning) 31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('DOS_HEADER') 31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.DOS_HEADER.dump()) 31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('NT_HEADERS') 31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.NT_HEADERS.dump()) 31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('FILE_HEADER') 31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.FILE_HEADER.dump()) 31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_flags = self.retrieve_flags(IMAGE_CHARACTERISTICS, 'IMAGE_FILE_') 31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('Flags: ') 31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = [] 31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for flag in image_flags: 31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if getattr(self.FILE_HEADER, flag[0]): 31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags.append(flag[0]) 31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(', '.join(flags)) 31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'OPTIONAL_HEADER') and self.OPTIONAL_HEADER is not None: 31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('OPTIONAL_HEADER') 31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.OPTIONAL_HEADER.dump()) 31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dll_characteristics_flags = self.retrieve_flags(DLL_CHARACTERISTICS, 'IMAGE_DLL_CHARACTERISTICS_') 31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('DllCharacteristics: ') 31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = [] 31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for flag in dll_characteristics_flags: 31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if getattr(self.OPTIONAL_HEADER, flag[0]): 31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags.append(flag[0]) 31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(', '.join(flags)) 31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('PE Sections') 31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_flags = self.retrieve_flags(SECTION_CHARACTERISTICS, 'IMAGE_SCN_') 31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for section in self.sections: 31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(section.dump()) 31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('Flags: ') 31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = [] 31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for flag in section_flags: 31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if getattr(section, flag[0]): 31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags.append(flag[0]) 31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(', '.join(flags)) 31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('Entropy: %f (Min=0.0, Max=8.0)' % section.get_entropy() ) 31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if md5 is not None: 31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('MD5 hash: %s' % section.get_hash_md5() ) 31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sha1 is not None: 31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('SHA-1 hash: %s' % section.get_hash_sha1() ) 31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sha256 is not None: 31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('SHA-256 hash: %s' % section.get_hash_sha256() ) 31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sha512 is not None: 31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('SHA-512 hash: %s' % section.get_hash_sha512() ) 31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hasattr(self, 'OPTIONAL_HEADER') and 31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hasattr(self.OPTIONAL_HEADER, 'DATA_DIRECTORY') ): 31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Directories') 31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for idx in xrange(len(self.OPTIONAL_HEADER.DATA_DIRECTORY)): 31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory = self.OPTIONAL_HEADER.DATA_DIRECTORY[idx] 31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(directory.dump()) 31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'VS_VERSIONINFO'): 31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Version Information') 31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.VS_VERSIONINFO.dump()) 31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'VS_FIXEDFILEINFO'): 31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.VS_FIXEDFILEINFO.dump()) 31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'FileInfo'): 32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for entry in self.FileInfo: 32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(entry.dump()) 32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(entry, 'StringTable'): 32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for st_entry in entry.StringTable: 32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [dump.add_line(' '+line) for line in st_entry.dump()] 32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(' LangID: '+st_entry.LangID) 32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for str_entry in st_entry.entries.items(): 32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(' '+str_entry[0]+': '+str_entry[1]) 32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif hasattr(entry, 'Var'): 32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for var_entry in entry.Var: 32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(var_entry, 'entry'): 32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [dump.add_line(' '+line) for line in var_entry.dump()] 32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line( 32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ' ' + var_entry.entry.keys()[0] + 32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ': ' + var_entry.entry.values()[0]) 32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'DIRECTORY_ENTRY_EXPORT'): 32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Exported symbols') 32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.DIRECTORY_ENTRY_EXPORT.struct.dump()) 32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('%-10s %-10s %s' % ('Ordinal', 'RVA', 'Name')) 32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for export in self.DIRECTORY_ENTRY_EXPORT.symbols: 32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('%-10d 0x%08Xh %s' % ( 32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) export.ordinal, export.address, export.name)) 32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if export.forwarder: 32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(' forwarder: %s' % export.forwarder) 32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'DIRECTORY_ENTRY_IMPORT'): 32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Imported symbols') 32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for module in self.DIRECTORY_ENTRY_IMPORT: 32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(module.struct.dump()) 32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for symbol in module.imports: 32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if symbol.import_by_ordinal is True: 32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('%s Ordinal[%s] (Imported by Ordinal)' % ( 32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module.dll, str(symbol.ordinal))) 32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('%s.%s Hint[%s]' % ( 32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module.dll, symbol.name, str(symbol.hint))) 32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if symbol.bound: 32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(' Bound: 0x%08X' % (symbol.bound)) 32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'DIRECTORY_ENTRY_BOUND_IMPORT'): 32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Bound imports') 32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for bound_imp_desc in self.DIRECTORY_ENTRY_BOUND_IMPORT: 32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(bound_imp_desc.struct.dump()) 32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('DLL: %s' % bound_imp_desc.name) 32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for bound_imp_ref in bound_imp_desc.entries: 32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(bound_imp_ref.struct.dump(), 4) 32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('DLL: %s' % bound_imp_ref.name, 4) 32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'DIRECTORY_ENTRY_DELAY_IMPORT'): 32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Delay Imported symbols') 32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for module in self.DIRECTORY_ENTRY_DELAY_IMPORT: 32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(module.struct.dump()) 32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for symbol in module.imports: 32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if symbol.import_by_ordinal is True: 32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('%s Ordinal[%s] (Imported by Ordinal)' % ( 32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module.dll, str(symbol.ordinal))) 32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add('%s.%s Hint[%s]' % ( 32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module.dll, symbol.name, str(symbol.hint))) 32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if symbol.bound: 32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line(' Bound: 0x%08X' % (symbol.bound)) 32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'DIRECTORY_ENTRY_RESOURCE'): 33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Resource directory') 33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.DIRECTORY_ENTRY_RESOURCE.struct.dump()) 33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for resource_type in self.DIRECTORY_ENTRY_RESOURCE.entries: 33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if resource_type.name is not None: 33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('Name: [%s]' % resource_type.name, 2) 33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('Id: [0x%X] (%s)' % ( 33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_type.struct.Id, RESOURCE_TYPE.get( 33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_type.struct.Id, '-')), 33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2) 33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(resource_type.struct.dump(), 2) 33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(resource_type, 'directory'): 33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(resource_type.directory.struct.dump(), 4) 33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for resource_id in resource_type.directory.entries: 33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if resource_id.name is not None: 33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('Name: [%s]' % resource_id.name, 6) 33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('Id: [0x%X]' % resource_id.struct.Id, 6) 33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(resource_id.struct.dump(), 6) 33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(resource_id, 'directory'): 33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(resource_id.directory.struct.dump(), 8) 33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for resource_lang in resource_id.directory.entries: 33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # dump.add_line('\\--- LANG [%d,%d][%s]' % ( 33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # resource_lang.data.lang, 33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # resource_lang.data.sublang, 33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # LANG[resource_lang.data.lang]), 8) 33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(resource_lang.struct.dump(), 10) 33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(resource_lang.data.struct.dump(), 12) 33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( hasattr(self, 'DIRECTORY_ENTRY_TLS') and 33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.DIRECTORY_ENTRY_TLS and 33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.DIRECTORY_ENTRY_TLS.struct ): 33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('TLS') 33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(self.DIRECTORY_ENTRY_TLS.struct.dump()) 33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'DIRECTORY_ENTRY_DEBUG'): 33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Debug information') 33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for dbg in self.DIRECTORY_ENTRY_DEBUG: 33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(dbg.struct.dump()) 33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('Type: '+DEBUG_TYPE[dbg.struct.Type]) 33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except KeyError: 33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('Type: 0x%x(Unknown)' % dbg.struct.Type) 33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, 'DIRECTORY_ENTRY_BASERELOC'): 33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_header('Base relocations') 33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for base_reloc in self.DIRECTORY_ENTRY_BASERELOC: 33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_lines(base_reloc.struct.dump()) 33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for reloc in base_reloc.entries: 33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('%08Xh %s' % ( 33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reloc.rva, RELOCATION_TYPE[reloc.type][16:]), 4) 33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except KeyError: 33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_line('0x%08X 0x%x(Unknown)' % ( 33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reloc.rva, reloc.type), 4) 33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dump.add_newline() 33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dump.get_text() 33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # OC Patch 33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_physical_by_rva(self, rva): 33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Gets the physical address in the PE file from an RVA value.""" 33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_offset_from_rva(rva) 33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except Exception: 33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Double-Word get/set 33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_data_from_dword(self, dword): 33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return a four byte string representing the double word value. (little endian).""" 33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.pack('<L', dword) 33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_dword_from_data(self, data, offset): 33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Convert four bytes of data to a double word (little endian) 34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'offset' is assumed to index into a dword array. So setting it to 34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N will return a dword out of the data sarting at offset N*4. 34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns None if the data can't be turned into a double word. 34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset+1)*4 > len(data): 34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.unpack('<L', data[offset*4:(offset+1)*4])[0] 34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_dword_at_rva(self, rva): 34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the double word value at the given RVA. 34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns None if the value can't be read, i.e. the RVA can't be mapped 34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to a file offset. 34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_dword_from_data(self.get_data(rva)[:4], 0) 34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError: 34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_dword_from_offset(self, offset): 34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the double word value at the given file offset. (little endian)""" 34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if offset+4 > len(self.__data__): 34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_dword_from_data(self.__data__[offset:offset+4], 0) 34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_dword_at_rva(self, rva, dword): 34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Set the double word value at the file offset corresponding to the given RVA.""" 34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.set_bytes_at_rva(rva, self.get_data_from_dword(dword)) 34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_dword_at_offset(self, offset, dword): 34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Set the double word value at the given file offset.""" 34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.set_bytes_at_offset(offset, self.get_data_from_dword(dword)) 34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Word get/set 34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_data_from_word(self, word): 34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return a two byte string representing the word value. (little endian).""" 34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.pack('<H', word) 34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_word_from_data(self, data, offset): 34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Convert two bytes of data to a word (little endian) 34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'offset' is assumed to index into a word array. So setting it to 34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N will return a dword out of the data sarting at offset N*2. 34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns None if the data can't be turned into a word. 34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset+1)*2 > len(data): 34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.unpack('<H', data[offset*2:(offset+1)*2])[0] 34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_word_at_rva(self, rva): 34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the word value at the given RVA. 34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns None if the value can't be read, i.e. the RVA can't be mapped 34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to a file offset. 34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_word_from_data(self.get_data(rva)[:2], 0) 34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError: 34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_word_from_offset(self, offset): 34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the word value at the given file offset. (little endian)""" 34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if offset+2 > len(self.__data__): 34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_word_from_data(self.__data__[offset:offset+2], 0) 34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_word_at_rva(self, rva, word): 34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Set the word value at the file offset corresponding to the given RVA.""" 34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.set_bytes_at_rva(rva, self.get_data_from_word(word)) 34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_word_at_offset(self, offset, word): 34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Set the word value at the given file offset.""" 34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.set_bytes_at_offset(offset, self.get_data_from_word(word)) 35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Quad-Word get/set 35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_data_from_qword(self, word): 35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return a eight byte string representing the quad-word value. (little endian).""" 35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.pack('<Q', word) 35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_qword_from_data(self, data, offset): 35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Convert eight bytes of data to a word (little endian) 35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'offset' is assumed to index into a word array. So setting it to 35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N will return a dword out of the data sarting at offset N*8. 35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns None if the data can't be turned into a quad word. 35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset+1)*8 > len(data): 35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return struct.unpack('<Q', data[offset*8:(offset+1)*8])[0] 35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_qword_at_rva(self, rva): 35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the quad-word value at the given RVA. 35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns None if the value can't be read, i.e. the RVA can't be mapped 35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to a file offset. 35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_qword_from_data(self.get_data(rva)[:8], 0) 35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except PEFormatError: 35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get_qword_from_offset(self, offset): 35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the quad-word value at the given file offset. (little endian)""" 35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if offset+8 > len(self.__data__): 35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.get_qword_from_data(self.__data__[offset:offset+8], 0) 35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_qword_at_rva(self, rva, qword): 35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Set the quad-word value at the file offset corresponding to the given RVA.""" 35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.set_bytes_at_rva(rva, self.get_data_from_qword(qword)) 35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_qword_at_offset(self, offset, qword): 35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Set the quad-word value at the given file offset.""" 35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.set_bytes_at_offset(offset, self.get_data_from_qword(qword)) 35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Set bytes 35615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ## 35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_bytes_at_rva(self, rva, data): 35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Overwrite, with the given string, the bytes at the file offset corresponding to the given RVA. 35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Return True if successful, False otherwise. It can fail if the 35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset is outside the file's boundaries. 35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = self.get_physical_by_rva(rva) 35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not offset: 35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise False 35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.set_bytes_at_offset(offset, data) 35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def set_bytes_at_offset(self, offset, data): 35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Overwrite the bytes at the given file offset with the given string. 35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Return True if successful, False otherwise. It can fail if the 35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset is outside the file's boundaries. 35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not isinstance(data, str): 35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise TypeError('data should be of type: str') 35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if offset >= 0 and offset < len(self.__data__): 35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__ = ( self.__data__[:offset] + 35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data + 35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.__data__[offset+len(data):] ) 35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Refresh the section's data with the modified information 35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for section in self.sections: 35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_data_start = section.PointerToRawData 35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section_data_end = section_data_start+section.SizeOfRawData 36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section.data = self.__data__[section_data_start:section_data_end] 36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def relocate_image(self, new_ImageBase): 36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Apply the relocation information to the image using the provided new image base. 36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This method will apply the relocation information to the image. Given the new base, 36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all the relocations will be processed and both the raw data and the section's data 36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will be fixed accordingly. 36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The resulting image can be retrieved as well through the method: 36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_memory_mapped_image() 36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) In order to get something that would more closely match what could be found in memory 36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) once the Windows loader finished its work. 36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relocation_difference = new_ImageBase - self.OPTIONAL_HEADER.ImageBase 36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for reloc in self.DIRECTORY_ENTRY_BASERELOC: 36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual_address = reloc.struct.VirtualAddress 36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_of_block = reloc.struct.SizeOfBlock 36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # We iterate with an index because if the relocation is of type 36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # IMAGE_REL_BASED_HIGHADJ we need to also process the next entry 36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # at once and skip it for the next interation 36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_idx = 0 36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while entry_idx<len(reloc.entries): 36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry = reloc.entries[entry_idx] 36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_idx += 1 36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if entry.type == RELOCATION_TYPE['IMAGE_REL_BASED_ABSOLUTE']: 36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Nothing to do for this type of relocation 36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pass 36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif entry.type == RELOCATION_TYPE['IMAGE_REL_BASED_HIGH']: 36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Fix the high 16bits of a relocation 36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Add high 16bits of relocation_difference to the 36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 16bit value at RVA=entry.rva 36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_word_at_rva( 36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.rva, 36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ( self.get_word_at_rva(entry.rva) + relocation_difference>>16)&0xffff ) 36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif entry.type == RELOCATION_TYPE['IMAGE_REL_BASED_LOW']: 36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Fix the low 16bits of a relocation 36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Add low 16 bits of relocation_difference to the 16bit value 36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # at RVA=entry.rva 36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_word_at_rva( 36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.rva, 36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ( self.get_word_at_rva(entry.rva) + relocation_difference)&0xffff) 36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif entry.type == RELOCATION_TYPE['IMAGE_REL_BASED_HIGHLOW']: 36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Handle all high and low parts of a 32bit relocation 36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Add relocation_difference to the value at RVA=entry.rva 36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_dword_at_rva( 36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.rva, 36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.get_dword_at_rva(entry.rva)+relocation_difference) 36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif entry.type == RELOCATION_TYPE['IMAGE_REL_BASED_HIGHADJ']: 36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Fix the high 16bits of a relocation and adjust 36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Add high 16bits of relocation_difference to the 32bit value 36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # composed from the (16bit value at RVA=entry.rva)<<16 plus 36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the 16bit value at the next relocation entry. 36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If the next entry is beyond the array's limits, 36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # abort... the table is corrupt 36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if entry_idx == len(reloc.entries): 36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_entry = reloc.entries[entry_idx] 36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_idx += 1 36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_word_at_rva( entry.rva, 36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((self.get_word_at_rva(entry.rva)<<16) + next_entry.rva + 36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relocation_difference & 0xffff0000) >> 16 ) 36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif entry.type == RELOCATION_TYPE['IMAGE_REL_BASED_DIR64']: 36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Apply the difference to the 64bit value at the offset 36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # RVA=entry.rva 36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.set_qword_at_rva( 36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.rva, 36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.get_qword_at_rva(entry.rva) + relocation_difference) 36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def verify_checksum(self): 37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.OPTIONAL_HEADER.CheckSum == self.generate_checksum() 37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def generate_checksum(self): 37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Get the offset to the CheckSum field in the OptionalHeader 37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum_offset = self.OPTIONAL_HEADER.__file_offset__ + 0x40 # 64 37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum = 0 37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in range( len(self.__data__) / 4 ): 37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Skip the checksum field 37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if i == checksum_offset / 4: 37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dword = struct.unpack('L', self.__data__[ i*4 : i*4+4 ])[0] 37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum = (checksum & 0xffffffff) + dword + (checksum>>32) 37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if checksum > 2**32: 37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum = (checksum & 0xffffffff) + (checksum >> 32) 37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum = (checksum & 0xffff) + (checksum >> 16) 37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum = (checksum) + (checksum >> 16) 37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checksum = checksum & 0xffff 37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return checksum + len(self.__data__) 3730