これで、SECTIONヘッダーを除けば
> DUMPBIN /HEADERS foo.exe
と同じ情報をとれるようになった。
show_optional_header.py:
import sys, logging, struct, ctypes BYTE = ctypes.c_ubyte WORD = ctypes.c_ushort LONG = ctypes.c_long DWORD = ctypes.c_ulong class IMAGE_DOS_HEADER(ctypes.Structure): #省略 class IMAGE_FILE_HEADER(ctypes.Structure): #省略 class IMAGE_DATA_DIRECTORY(ctypes.Structure): _fields_ = [ ('VirtualAddress', DWORD), ('Size', DWORD), ] IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 class IMAGE_OPTIONAL_HEADER(ctypes.Structure): _fields_ = [ ('Magic', WORD), ('MajorLinkerVersion', BYTE), ('MinorLinkerVersion', BYTE), ('SizeOfCode', DWORD), ('SizeOfInitializedData', DWORD), ('SizeOfUninitializedData', DWORD), ('AddressOfEntryPoint', DWORD), ('BaseOfCode', DWORD), ('BaseOfData', DWORD), ('ImageBase', DWORD), ('SectionAlignment', DWORD), ('FileAlignment', DWORD), ('MajorOperatingSystemVersion', WORD), ('MinorOperatingSystemVersion', WORD), ('MajorImageVersion', WORD), ('MinorImageVersion', WORD), ('MajorSubsystemVersion', WORD), ('MinorSubsystemVersion', WORD), ('Win32VersionValue', DWORD), ('SizeOfImage', DWORD), ('SizeOfHeaders', DWORD), ('CheckSum', DWORD), ('Subsystem', WORD), ('DllCharacteristics', WORD), ('SizeOfStackReserve', DWORD), ('SizeOfStackCommit', DWORD), ('SizeOfHeapReserve', DWORD), ('SizeOfHeapCommit', DWORD), ('LoaderFlags', DWORD), ('NumberOfRvaAndSizes', DWORD), ('DataDirectory', IMAGE_DATA_DIRECTORY * IMAGE_NUMBEROF_DIRECTORY_ENTRIES ), ] class IMAGE_NT_HEADERS(ctypes.Structure): _fields_ = [ ('Signature', DWORD), ('FileHeader', IMAGE_FILE_HEADER), ('OptionalHeader', IMAGE_OPTIONAL_HEADER), ] if 2 != len(sys.argv): print 'usage: python %s filename' % sys.argv[0] quit() file_name = sys.argv[1] logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(name)s %(levelname)s %(message)s', ) log = logging.getLogger('main') try: f = open(file_name, 'rb') except IOError, e: log.error("open(%s) faileed." % file_name) log.error(e) raise e f.seek(0, 0) sz = ctypes.sizeof(IMAGE_DOS_HEADER) data = f.read(sz) dos_header = IMAGE_DOS_HEADER() fit = min(len(data), sz) ctypes.memmove(ctypes.addressof(dos_header), data, fit) f.seek(dos_header.e_lfanew, 0) sz = ctypes.sizeof(IMAGE_NT_HEADERS) data = f.read(sz) pe_header = IMAGE_NT_HEADERS() fit = min(len(data), sz) ctypes.memmove(ctypes.addressof(pe_header), data, fit) print "IMAGE_NT_HEADER:" print "\tSignature: %08X" % pe_header.Signature print "\tFileHeader, OptionalHeader: (continued)" file_header = pe_header.FileHeader print "-------------------------------" print "IMAGE_FILE_HEADER:" print "\tMachine: %04X" % file_header.Machine print "\tNumberOfSections: %04X" % file_header.NumberOfSections print "\tTimeDateStamp: %08X" % file_header.TimeDateStamp print "\tPointerToSymbolTable: %08X" % file_header.PointerToSymbolTable print "\tNumberOfSymbols: %08X" % file_header.NumberOfSymbols print "\tSizeOfOptionalHeader: %08X" % file_header.SizeOfOptionalHeader print "\tCharacteristics: %04X" % file_header.Characteristics opt_header = pe_header.OptionalHeader print "-------------------------------" print "IMAGE_OPTIONAL_HEADER:" print "\tMagic: %04X" % opt_header.Magic print "\tMajorLinkerVersion: %02X" % opt_header.MajorLinkerVersion print "\tMinorLinkerVersion: %02X" % opt_header.MinorLinkerVersion print "\tSizeOfCode: %08X" % opt_header.SizeOfCode print "\tSizeOfInitializedData: %08X" % opt_header.SizeOfInitializedData print "\tSizeOfUninitializedData: %08X" % opt_header.SizeOfUninitializedData print "\tAddressOfEntryPoint: %08X" % opt_header.AddressOfEntryPoint print "\tBaseOfCode: %08X" % opt_header.BaseOfCode print "\tBaseOfData: %08X" % opt_header.BaseOfData print "\tImageBase: %08X" % opt_header.ImageBase print "\tSectionAlignment: %08X" % opt_header.SectionAlignment print "\tFileAlignment: %08X" % opt_header.FileAlignment print "\tMajorOperatingSystemVersion: %04X" % opt_header.MajorOperatingSystemVersion print "\tMinorOperatingSystemVersion: %04X" % opt_header.MinorOperatingSystemVersion print "\tMajorImageVersion: %04X" % opt_header.MajorImageVersion print "\tMinorImageVersion: %04X" % opt_header.MinorImageVersion print "\tMajorSubsystemVersion: %04X" % opt_header.MajorSubsystemVersion print "\tMinorSubsystemVersion: %04X" % opt_header.MinorSubsystemVersion print "\tWin32VersionValue: %08X" % opt_header.Win32VersionValue print "\tSizeOfImage: %08X" % opt_header.SizeOfImage print "\tSizeOfHeaders: %08X" % opt_header.SizeOfHeaders print "\tCheckSum: %08X" % opt_header.CheckSum print "\tSubsystem: %08X" % opt_header.Subsystem print "\tDllCharacteristics: %08X" % opt_header.DllCharacteristics print "\tSizeOfStackReserve: %08X" % opt_header.SizeOfStackReserve print "\tSizeOfStackCommit: %08X" % opt_header.SizeOfStackCommit print "\tSizeOfHeapReserve: %08X" % opt_header.SizeOfHeapReserve print "\tSizeOfHeapCommit: %08X" % opt_header.SizeOfHeapCommit print "\tLoaderFlags: %08X" % opt_header.LoaderFlags print "\tNumberOfRvaAndSizes: %08X" % opt_header.NumberOfRvaAndSizes for i in range(IMAGE_NUMBEROF_DIRECTORY_ENTRIES): print "\tDataDirectory[%d]: [RVA=%X],[SIZE=%X]" % (i, opt_header.DataDirectory[i].VirtualAddress, opt_header.DataDirectory[i].Size)
IMAGE_DOS_HEADER, IMAGE_FILE_HEADERについては 日記/2010/05/25/IMAGE_NT_HEADERSとIMAGE_FILE_HEADERを覗いてみる。 参照。
DUMPBINだと、DataDirectoryの用途も表示してくれる。
IMAGE_OPTIONAL_HEADERの各フィールドの説明については、
↑のFigure5参照。
コメント