diff --git a/__init__.py b/__init__.py index 866ed65..9004c8c 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +1,3 @@ __all__ = ['pe'] -from .pe import * +from pe import * diff --git a/bmpimageplugin.py b/bmpimageplugin.py new file mode 100644 index 0000000..968254a --- /dev/null +++ b/bmpimageplugin.py @@ -0,0 +1,327 @@ +# +# The Python Imaging Library. +# $Id$ +# +# BMP file handler +# +# Windows (and OS/2) native bitmap storage format. +# +# history: +# 1995-09-01 fl Created +# 1996-04-30 fl Added save +# 1997-08-27 fl Fixed save of 1-bit images +# 1998-03-06 fl Load P images as L where possible +# 1998-07-03 fl Load P images as 1 where possible +# 1998-12-29 fl Handle small palettes +# 2002-12-30 fl Fixed load of 1-bit palette images +# 2003-04-21 fl Fixed load of 1-bit monochrome images +# 2003-04-23 fl Added limited support for BI_BITFIELDS compression +# +# Copyright (c) 1997-2003 by Secret Labs AB +# Copyright (c) 1995-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.7" + + +from PIL import Image, ImageFile, ImagePalette, _binary +from PIL.BmpImagePlugin import * #This is a hack to override the default bmp plugin for PIL +from cStringIO import StringIO +import math + +i8 = _binary.i8 +i16 = _binary.i16le +i32 = _binary.i32le +o8 = _binary.o8 +o16 = _binary.o16le +o32 = _binary.o32le + +# +# -------------------------------------------------------------------- +# Read BMP file + +BIT2MODE = { + # bits => mode, rawmode + 1: ("P", "P;1"), + 4: ("P", "P;4"), + 8: ("P", "P"), + 16: ("RGB", "BGR;15"), + 24: ("RGB", "BGR"), + 32: ("RGBA", "BGRA") +} + + +def _accept(prefix): + return prefix[:2] == b"BM" + + +## +# Image plugin for the Windows BMP format. + +class BmpImageFile(ImageFile.ImageFile): + + format = "BMP" + format_description = "Windows Bitmap" + + def _bitmap(self, header=0, offset=0): + if header: + self.fp.seek(header) + + read = self.fp.read + + if not offset: + offset = self.fp.tell() + # CORE/INFO + s = read(4) + s = s + ImageFile._safe_read(self.fp, i32(s)-4) + + if len(s) == 12: + + # OS/2 1.0 CORE + bits = i16(s[10:]) + self.size = i16(s[4:]), i16(s[6:]) + compression = 0 + lutsize = 3 + colors = 0 + direction = -1 + + elif len(s) in [40, 64, 108, 124]: + + # WIN 3.1 or OS/2 2.0 INFO + bits = i16(s[14:]) + self.size = i32(s[4:]), i32(s[8:]) + compression = i32(s[16:]) + pxperm = (i32(s[24:]), i32(s[28:])) # Pixels per meter + lutsize = 4 + colors = i32(s[32:]) + direction = -1 + if i8(s[11]) == 0xff: + # upside-down storage + self.size = self.size[0], 2**32 - self.size[1] + direction = 0 + + self.info["dpi"] = tuple(map(lambda x: math.ceil(x / 39.3701), + pxperm)) + + else: + raise IOError("Unsupported BMP header type (%d)" % len(s)) + + if (self.size[0]*self.size[1]) > 2**31: + # Prevent DOS for > 2gb images + raise IOError("Unsupported BMP Size: (%dx%d)" % self.size) + + if not colors: + colors = 1 << bits + + # MODE + try: + self.mode, rawmode = BIT2MODE[bits] + except KeyError: + raise IOError("Unsupported BMP pixel depth (%d)" % bits) + + if compression == 3: + # BI_BITFIELDS compression + mask = i32(s[0x36-14:]), i32(s[0x3a-14:]), i32(s[0x3E-14:]), i32(s[0x42-14:]) + if bits == 32 and mask == (0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000): + rawmode = "BGRA" + elif bits == 16 and mask == (0x00f800, 0x0007e0, 0x00001f): + rawmode = "BGR;16" + elif bits == 16 and mask == (0x007c00, 0x0003e0, 0x00001f): + rawmode = "BGR;15" + else: + print bits, map(hex, mask) + raise IOError("Unsupported BMP bitfields layout") + elif compression != 0: + raise IOError("Unsupported BMP compression (%d)" % compression) + + # LUT + if self.mode == "P": + palette = [] + greyscale = 1 + if colors == 2: + indices = (0, 255) + elif colors > 2**16 or colors <= 0: # We're reading a i32. + raise IOError("Unsupported BMP Palette size (%d)" % colors) + else: + indices = list(range(colors)) + for i in indices: + rgb = read(lutsize)[:3] + if rgb != o8(i)*3: + greyscale = 0 + palette.append(rgb) + if greyscale: + if colors == 2: + self.mode = rawmode = "1" + else: + self.mode = rawmode = "L" + else: + self.mode = "P" + self.palette = ImagePalette.raw( + "BGR", b"".join(palette) + ) + + if not offset: + offset = self.fp.tell() + + self.tile = [("raw", + (0, 0) + self.size, + offset, + (rawmode, ((self.size[0]*bits+31) >> 3) & (~3), + direction))] + + self.info["compression"] = compression + + def _open(self): + + # HEAD + s = self.fp.read(14) + if s[:2] != b"BM": + raise SyntaxError("Not a BMP file") + offset = i32(s[10:]) + + self._bitmap(offset=offset) + +class DibImageFile(BmpImageFile): + + format = "DIB" + format_description = "Windows Bitmap" + + def __init__(self, buf, *args, **kwargs): + BmpImageFile.__init__(self, buf, *args, **kwargs) + buf.seek(0) + self.buf = buf.read() + buf.seek(0) + + def _open(self): + self._bitmap() + + def get_file_data(self): + return self.buf + + def to_bitmapimage(self, header): + self.fp.seek(header['offset']) + d = bytearray(self.fp.read(header['size'])) + print self.info + dpi = (96,96) + ppm = tuple(map(lambda x: int(x * 39.3701), dpi)) + + d[24:28] = o32(ppm[0]) + d[28:32] = o32(ppm[1]) + + dib_size = i32(str(d[:4])) + offset = 14 + dib_size + data = StringIO() + data.write(b'BM'+ + o32(14+len(d)) + + o32(0) + + o32(offset)) + + data.write(d) + data.seek(0) + new_image = Image.open(data) + return new_image + +# +# -------------------------------------------------------------------- +# Write BMP file + +SAVE = { + "1": ("1", 1, 2), + "L": ("L", 8, 256), + "P": ("P", 8, 256), + "RGB": ("BGR", 24, 0), + "RGBA": ("BGRA", 32, 0), +} + + +def _save(im, fp, filename, check=0): + try: + rawmode, bits, colors = SAVE[im.mode] + except KeyError: + raise IOError("cannot write mode %s as BMP" % im.mode) + + if check: + return check + + info = im.encoderinfo + + dpi = info.get("dpi", (96, 96)) + + # 1 meter == 39.3701 inches + ppm = tuple(map(lambda x: int(x * 39.3701), dpi)) + + stride = ((im.size[0]*bits+7)//8+3) & (~3) + header = 108 if im.mode == 'RGBA' else 40 # or 64 for OS/2 version 2 + offset = 14 + header + colors*4 + image = stride * im.size[1] + + red_mask = 0x00ff0000 + green_mask = 0x0000ff00 + blue_mask = 0x000000ff + alpha_mask = 0xff000000 + + # bitmap header + fp.write(b"BM" + # file type (magic) + o32(offset+image+16) + # file size + o32(0) + # reserved + o32(offset+16)) # image data offset + + width,height = im.size + + # bitmap info header + fp.write(o32(header+16) + # info header size + o32(width) + # width + o32(height) + # height + o16(1) + # planes + o16(bits) + # depth + o32(3) + # compression (0=uncompressed) + o32(image) + # size of bitmap + o32(ppm[0]) + o32(ppm[1]) + # resolution + o32(colors) + # colors used + o32(colors) # colors important + #o32(red_mask) + # red channel ma + #o32(green_mask) + # green channel mask + #o32(blue_mask) + # blue channel mask + #o32(alpha_mask) + ) + # This was commented out because although it works, some + # decoders do not support images with a BI_BITFIELDS compression + # + if im.mode == 'RGBA': + fp.write(o32(red_mask) + # red channel mask + o32(green_mask) + # green channel mask + o32(blue_mask) + # blue channel mask + o32(alpha_mask) + # alpha channel mask + 'BGRs' + # Color Space + o8(0)*0x24 + # ciexyztriple color space endpoints + o32(0) + # red gamma + o32(0) + # green gamma + o32(0) # blue gamma + ) + + fp.write(bytearray(16)) + + if im.mode == "1": + for i in (0, 255): + fp.write(o8(i) * 4) + elif im.mode == "L": + for i in range(256): + fp.write(o8(i) * 4) + elif im.mode == "P": + fp.write(im.im.getpalette("RGB", "BGRX")) + + #fp.write( + ImageFile._save(im, fp, [("raw", (0, 0)+im.size, 0, + (rawmode, stride, -1))]) + +# +# -------------------------------------------------------------------- +# Registry + +Image.register_open(BmpImageFile.format, BmpImageFile, _accept) +Image.register_save(BmpImageFile.format, _save) + +Image.register_extension(BmpImageFile.format, ".bmp") diff --git a/ico_plugin.py b/ico_plugin.py new file mode 100644 index 0000000..1aeed0f --- /dev/null +++ b/ico_plugin.py @@ -0,0 +1,411 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Windows Icon support for PIL +# +# History: +# 96-05-27 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + +# This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis +# . +# https://code.google.com/p/casadebender/wiki/Win32IconImagePlugin +# +# Icon format references: +# * http://en.wikipedia.org/wiki/ICO_(file_format) +# * http://msdn.microsoft.com/en-us/library/ms997538.aspx + + +__version__ = "0.1" + +from PIL import Image, ImageFile, BmpImagePlugin, PngImagePlugin, _binary +import bmpimageplugin +from bmpimageplugin import * +from cStringIO import StringIO +from math import log, ceil + +i8 = _binary.i8 +i16 = _binary.i16le +i32 = _binary.i32le +o8 = _binary.o8 +o16 = _binary.o16le +o32 = _binary.o32le + +_MAGIC = b"\0\0\1\0" + + +def _accept(prefix): + return prefix[:4] == _MAGIC + + +class IcoFile: + format = 'ICO' + def __init__(self, buf): + """ + Parse image from file-like object containing ico file data + """ + + # check magic + s = buf.read(6) + if not _accept(s): + raise SyntaxError("not an ICO file") + + self.buf = buf + self.entries = [] + + # Number of items in file + self.nb_items = i16(s[4:]) + + # Get headers for each item + for i in xrange(self.nb_items): + s = buf.read(16) + + icon_header = { + 'width': i8(s[0]), + 'height': i8(s[1]), + 'nb_color': i8(s[2]), # No. of colors in image (0 if >=8bpp) + 'reserved': i8(s[3]), + 'planes': i16(s[4:]), + 'bpp': i16(s[6:]), + 'size': i32(s[8:]), + 'offset': i32(s[12:]) + } + + # See Wikipedia + for j in ('width', 'height'): + if not icon_header[j]: + icon_header[j] = 256 + + # See Wikipedia notes about color depth. + # We need this just to differ images with equal sizes + icon_header['color_depth'] = (icon_header['bpp'] or + (icon_header['nb_color'] != 0 and + ceil(log(icon_header['nb_color'], + 2))) or 256) + + icon_header['dim'] = (icon_header['width'], icon_header['height']) + icon_header['square'] = (icon_header['width'] * + icon_header['height']) + + self.entries.append(icon_header) + + self.entries = sorted(self.entries, key=lambda x: x['color_depth']) + # ICO images are usually squares + # self.entries = sorted(self.entries, key=lambda x: x['width']) + self.entries = sorted(self.entries, key=lambda x: x['square']) + self.entries.reverse() + + def sizes(self): + """ + Get a list of all available icon sizes and color depths. + """ + return set((h['width'], h['height']) for h in self.entries) + + def getimage(self, size, bpp=False): + """ + Get an image from the icon + """ + for (i, h) in enumerate(self.entries): + if size == h['dim'] and (bpp is False or bpp == h['color_depth']): + return self.frame(i) + return self.frame(0) + + def get_images(self): + images = [] + for i, header in enumerate(self.entries): + f = self.frame(i) + if f.format: + images.append(self.frame(i)) + return images + + def frame(self, idx): + """ + Get an image from frame idx + """ + + header = self.entries[idx] + + self.buf.seek(header['offset']) + data = self.buf.read(8) + self.buf.seek(header['offset']) + + if data[:8] == PngImagePlugin._MAGIC: + # png frame + s = StringIO() + s.write(self.buf.read(header['size'])) + s.seek(0) + self.buf.seek(header['offset']) + im = Image.open(s) + else: + # XOR + AND mask bmp frame + s = StringIO() + s.write(self.buf.read(header['size'])) + s.seek(0) + self.buf.seek(header['offset']) + im = bmpimageplugin.DibImageFile(s) + #im = im.to_bitmapimage(header) + #print im.tile + # change tile dimension to only encompass XOR image + im.size = (im.size[0], int(im.size[1] / 2)) + #print im.size + d, e, o, a = im.tile[0] + im.tile[0] = d, (0, 0) + im.size, o, a + + # figure out where AND mask image starts + mode = a[0] + bpp = 8 + for k in BmpImagePlugin.BIT2MODE.keys(): + if mode == BmpImagePlugin.BIT2MODE[k][1]: + bpp = k + break + + if 32 == bpp: + # 32-bit color depth icon image allows semitransparent areas + # PIL's DIB format ignores transparency bits, recover them. + # The DIB is packed in BGRX byte order where X is the alpha + # channel. + + # Back up to start of bmp data + self.buf.seek(o) + # extract every 4th byte (eg. 3,7,11,15,...) + alpha_bytes = self.buf.read(im.size[0] * im.size[1] * 4)[3::4] + + # convert to an 8bpp grayscale image + mask = Image.frombuffer( + 'L', # 8bpp + im.size, # (w, h) + alpha_bytes, # source chars + 'raw', # raw decoder + ('L', 0, -1) # 8bpp inverted, unpadded, reversed + ) + else: + # get AND image from end of bitmap + w = im.size[0] + if (w % 32) > 0: + # bitmap row data is aligned to word boundaries + w += 32 - (im.size[0] % 32) + + # the total mask data is + # padded row size * height / bits per char + + and_mask_offset = o + int(im.size[0] * im.size[1] * + (bpp / 8.0)) + total_bytes = int((w * im.size[1]) / 8) + + self.buf.seek(and_mask_offset) + maskData = self.buf.read(total_bytes) + + # convert raw data to image + mask = Image.frombuffer( + '1', # 1 bpp + im.size, # (w, h) + maskData, # source chars + 'raw', # raw decoder + ('1;I', int(w/8), -1) # 1bpp inverted, padded, reversed + ) + + # now we have two images, im is XOR image and mask is AND image + + if im.mode != 'RGBA': + im = im.convert('RGBA') + im.putalpha(mask) + + return im + + +## +# Image plugin for Windows Icon files. + +class IcoImageFile(ImageFile.ImageFile): + """ + PIL read-only image support for Microsoft Windows .ico files. + + By default the largest resolution image in the file will be loaded. This + can be changed by altering the 'size' attribute before calling 'load'. + + The info dictionary has a key 'sizes' that is a list of the sizes available + in the icon file. + + Handles classic, XP and Vista icon formats. + + This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis + . + https://code.google.com/p/casadebender/wiki/Win32IconImagePlugin + """ + format = "ICO" + format_description = "Windows Icon" + + def _open(self): + self.ico = IcoFile(self.fp) + self.info['sizes'] = self.ico.sizes() + self.size = self.ico.entries[0]['dim'] + self.load() + + def load(self): + im = self.ico.getimage(self.size) + # if tile is PNG, it won't really be loaded yet + im.load() + self.im = im.im + self.mode = im.mode + self.size = im.size + + def get_images(self): + return self.ico.get_images() + + def load_seek(self): + # Flage the ImageFile.Parser so that it + # just does all the decode at the end. + pass + +SAVE = { + "1": ("1", 1, 2), + "L": ("L", 8, 256), + "P": ("P", 8, 256), + "RGB": ("BGR", 24, 0), + "RGBA": ("BGRA", 32, 0), +} + +def get_data(im): + s = StringIO() + if im.format != 'DIB': + im.save(s, im.format) + else: + s.write(im.buf) + s.seek(0) + + if im.format == 'BMP': + bmp_f = s + bmp_f.seek(10) + offset = i32(bmp_f.read(4)) + dib_size = i32(bmp_f.read(4)) + dib = o32(dib_size)+bytearray(bmp_f.read(36)) + dib[:4] = o32(40) + dib[8:12] = o32(i32(str(dib[8:12]))*2) + dib[16:20] = o32(0) + dib = dib[:40] + bmp_f.seek(offset) + data = bytearray(bmp_f.read()) + data = dib+data + else: + data = bytearray(s.read()) + + return data + + + +def _save(image, fp, filename, check=0): + data = None + images = [] + if image.format != 'ICO': + bmp_f = StringIO() + image.save(bmp_f, format='BMP') + bmp_f.seek(0) + im2 = Image.open(bmp_f) + if im2.format: + images.append(im2) + else: + images = image.get_images() + + number_of_images = len(images) + + header_size = 6+16*number_of_images + + # ico header + fp.write(o16(0) + # reserved + o16(1) + # file type + o16(number_of_images)) # number of images + + current_offset = header_size + for i, im in enumerate(images): + + data = get_data(im) + + try: + rawmode, bits, colors = SAVE[im.mode] + except KeyError: + raise IOError("cannot write mode %s as BMP" % im.mode) + matte_data = bytearray() + if im.format == 'BMP': + + #write matte data. Taken from imagemagick + scanline_pad = (((im.size[0]+31) & ~31)-im.size[0]) >> 3 + row_len = im.size[0]*4 + for y in reversed(xrange(im.size[1])): + d = data[40:] + #BGRA + row_pixels = d[row_len*y:row_len*y+row_len] + bit=0 + byte=0 + for x in xrange(im.size[0]): + p=row_pixels[x] + + byte<<=1 + bit+=1 + if bit == 8: + matte_data+=o8(byte) + bit=0 + byte=0 + if not bit == 0: + matte_data+=o8(byte<<(8-bit)) + for i in xrange(scanline_pad): + matte_data+=o8(0) + + fp.write(o8(im.size[0]) + # width + o8(im.size[1]) + # height + o8(0) + # color palette + o8(0) + # reserved + o16(1) + # planes + o16(bits) + # depth + o32(len(data+matte_data)) + # size of image in bytes + o32(current_offset) # offset + + ) + current_offset += len(data+matte_data) + + for im in images: + + data = get_data(im) + fp.write(data) + + if im.format == 'BMP': + + #write matte data. Taken from imagemagick + scanline_pad = (((im.size[0]+31) & ~31)-im.size[0]) >> 3 + row_len = im.size[0]*4 + for y in reversed(xrange(im.size[1])): + d = data[40:] + #BGRA + row_pixels = d[row_len*y:row_len*y+row_len] + bit=0 + byte=0 + for x in xrange(im.size[0]): + p=row_pixels[x] + + byte<<=1 + bit+=1 + if bit == 8: + fp.write(o8(byte)) + bit=0 + byte=0 + if not bit == 0: + fp.write(o8(byte<<(8-bit))) + for i in xrange(scanline_pad): + fp.write(o8(0)) + + + fp.flush() + + +# +# -------------------------------------------------------------------- + +Image.register_open(IcoFile.format, IcoImageFile, _accept) +Image.register_save(IcoFile.format, _save) + +Image.register_extension(IcoFile.format, '.ico') diff --git a/pe.py b/pe.py index 0a6cfcf..3e30222 100644 --- a/pe.py +++ b/pe.py @@ -1,11 +1,11 @@ import os import struct -from io import BytesIO +from cStringIO import StringIO -from PIL import Image +from ico_plugin import * def resize(image, size, format=None): - output = BytesIO() + output = StringIO() back = Image.new('RGBA', size, (0,0,0,0)) if image.size[0] < size[0] or image.size[1] < size[1]: @@ -28,7 +28,7 @@ def resize(image, size, format=None): back.paste(image, tuple(offset)) format = format or image.format - back.save(output, format, sizes=[size]) + back.save(output, format) contents = output.getvalue() output.close() return contents @@ -179,7 +179,7 @@ name_dictionary = {'PEHeader_Machine': { 0x10000000:'IMAGE_SCN_MEM_SHARED', 0x20000000:'IMAGE_SCN_MEM_EXECUTE', 0x40000000:'IMAGE_SCN_MEM_READ', - 0x80000000:'IMAGE_SCN_MEM_WRITE', + 0x80000000L:'IMAGE_SCN_MEM_WRITE', }, } @@ -208,8 +208,9 @@ def read_bytes(file_data, offset, number_of_bytes, endian=None, string_data=None endian = endian or DEFAULT_ENDIAN endian = endian_symbols[endian] - data = bytes(file_data[offset:offset+number_of_bytes]) + data = str(file_data[offset:offset+number_of_bytes]) if len(data) != number_of_bytes: + #print 'data out of bounds:', 'offset', hex(offset), 'data', data, 'data_len', len(data), 'num_bytes', number_of_bytes, 'total', hex(len(file_data)) return 0, u'' return struct.unpack(endian+struct_symbols[number_of_bytes], data)[0], data @@ -317,9 +318,12 @@ class Printable(object): return u', '.join(vals) def __repr__(self): - return str(self) + return unicode(self) def __str__(self): + return unicode(self).encode('utf-8') + + def __unicode__(self): return u'{} [{}]'.format(self.__class__.__name__, self._dict_string()) @@ -394,7 +398,7 @@ class Structure(Printable): bit_length = len(bin(int_value))-2 characteristics = {} - for i in range(bit_length): + for i in xrange(bit_length): set_bit = test_bit(int_value, i) char_name = field_name_dict.get(set_bit, '') if set_bit != 0 and char_name: @@ -735,14 +739,13 @@ class OptionalHeader(Structure): """Parses the Structure from the file data.""" self = cls(**cls_args) self._file_data = file_data - magic, x = read_bytes(file_data, self.absolute_offset, 2) + magic, _ = read_bytes(file_data, self.absolute_offset, 2) if magic == _32BIT_MAGIC: self._fields = self._fields_32 elif magic == _32BIT_PLUS_MAGIC: self._fields = self._fields_32_plus else: - print(magic, _32BIT_MAGIC, _32BIT_PLUS_MAGIC) raise PEFormatError('Magic for Optional Header is invalid.') for field_name, field_info in self._fields.items(): @@ -869,9 +872,9 @@ class ResourceDirectoryString(Structure): size = field_info['size'] self.size += size data = u'' - for i in range(size): + for i in xrange(size): val, dat = read_bytes(file_data, absolute_offset+i*2,2) - data += str(dat, 'utf-8') + data += dat setattr(self, field_name, Structure(offset=field_info['offset'], size=size, @@ -993,7 +996,7 @@ class IconHeader(Structure): self.entries = [] entry_offset = 0 self.total_size = self.size - for i in range(self.ImageCount.value): + for i in xrange(self.ImageCount.value): entry = IconEntry.parse_from_data(file_data, absolute_offset=self.absolute_offset+self.size+entry_offset, offset=entry_offset) entry.number = i + 1 self.entries.append(entry) @@ -1025,7 +1028,7 @@ class GroupHeader(Structure): entry_offset = 0 self.total_size = self.size for icon_entry in icon_header.entries: - group_entry = GroupEntry.parse_from_data(bytearray(b''), absolute_offset=self.absolute_offset+self.size+entry_offset, offset=entry_offset) + group_entry = GroupEntry.parse_from_data(bytearray(''), absolute_offset=self.absolute_offset+self.size+entry_offset, offset=entry_offset) group_entry._file_data = self._file_data group_entry.copy_from(icon_entry) group_entry.number = icon_entry.number @@ -1046,7 +1049,7 @@ class GroupHeader(Structure): self.entries = [] entry_offset = 0 self.total_size = self.size - for i in range(self.ResourceCount.value): + for i in xrange(self.ResourceCount.value): entry = GroupEntry.parse_from_data(file_data, absolute_offset=self.absolute_offset+self.size+entry_offset, offset=entry_offset) entry.number = i + 1 self.entries.append(entry) @@ -1088,7 +1091,7 @@ class IconEntry(Structure): offset = 6 #Default icon header size offset += self.size * len(group_entries) - for i in range(group_entry.number-1): + for i in xrange(group_entry.number-1): offset += group_entries[i].DataSize.value return offset @@ -1151,7 +1154,7 @@ class PEFile(Printable): Right now this only reads the .rsrc section. """ - signature = b'MZ' + signature = 'MZ' dos_header = None def __init__(self, file_path, endian='little'): @@ -1172,19 +1175,18 @@ class PEFile(Printable): section_offset = self.pe_header.size+self.pe_header.absolute_offset+self.pe_header.SizeOfOptionalHeader.value self.sections = {} - for section_number in range(number_of_sections): + for section_number in xrange(number_of_sections): section_header = SectionHeader.parse_from_data(self.pe_file_data, absolute_offset=section_offset) section_offset += section_size - header_name = str(section_header.Name.data, 'utf-8').strip('\x00') - self.sections[header_name] = section_header + self.sections[section_header.Name.data.strip('\x00')] = section_header if section_header.PointerToLineNumbers.value != 0: - print('{} section contains line number COFF table, which is not implemented yet.'.format(section_header.Name)) + print '{} section contains line number COFF table, which is not implemented yet.'.format(section_header.Name) if section_header.PointerToRelocations.value != 0: - print('{} section contains relocation table, which is not implemented yet.'.format(section_header.Name)) + print '{} section contains relocation table, which is not implemented yet.'.format(section_header.Name) - if section_header.Name.data == b'.rsrc\x00\x00\x00': + if section_header.Name.data == '.rsrc\x00\x00\x00': current_table_pointer = section_header.PointerToRawData.value current_resource_directory_table = ResourceDirectoryTable.parse_from_data(self.pe_file_data, absolute_offset=current_table_pointer, _section_header=section_header, type=None) self.resource_directory_table = current_resource_directory_table @@ -1199,7 +1201,7 @@ class PEFile(Printable): num_id_entries = resource_directory_table.NumberOfIDEntries.value current_offset = resource_directory_table.absolute_offset + resource_directory_table.size - for i in range(num_name_entries): + for i in xrange(num_name_entries): name_entry = ResourceDirectoryEntryName.parse_from_data(self.pe_file_data, absolute_offset=current_offset, _section_header=section_header) current_offset += name_entry.size @@ -1220,7 +1222,7 @@ class PEFile(Printable): resource_directory_table.name_entries.append(name_entry) - for i in range(num_id_entries): + for i in xrange(num_id_entries): id_entry = ResourceDirectoryEntryID.parse_from_data(self.pe_file_data, absolute_offset=current_offset, _section_header=section_header) current_offset += id_entry.size @@ -1279,7 +1281,6 @@ class PEFile(Printable): #9662 is the exact length of the icon in nw.exe extra_size = icon_file_size-new_icon_size - if extra_size < 0: extra_size = 0 icon_data = bytearray(i_data) + bytearray(extra_size)