コード例 #1
0
ファイル: exif.py プロジェクト: eduardoburgoa/hachoir_parser
 def createFields(self):
     # Headers
     yield String(self, "header", 6, "Header (Exif\\0\\0)", charset="ASCII")
     if self["header"].value != "Exif\0\0":
         raise ParserError("Invalid EXIF signature!")
     yield String(self, "byte_order", 2, "Byte order", charset="ASCII")
     if self["byte_order"].value not in ("II", "MM"):
         raise ParserError("Invalid endian!")
     if self["byte_order"].value == "II":
         self.endian = LITTLE_ENDIAN
     else:
         self.endian = BIG_ENDIAN
     yield UInt16(self, "version", "TIFF version number")
     yield UInt32(self, "img_dir_ofs", "Next image directory offset")
     while not self.eof:
         addr = self.absolute_address + self.current_size
         tag = self.stream.readBits(addr, 16, NETWORK_ENDIAN)
         if tag == 0xFFD8:
             size = (self._size - self.current_size) // 8
             yield SubFile(self,
                           "thumbnail",
                           size,
                           "Thumbnail (JPEG file)",
                           mime_type="image/jpeg")
             break
         elif tag == 0xFFFF:
             break
         yield ExifIFD(self, "ifd[]", "IFD")
     padding = self.seekBit(self._size)
     if padding is not None:
         yield padding
コード例 #2
0
 def createFields(self):
     addr = self.absolute_address
     len = self.stream.searchBytesLength(':', False, addr,
                                         addr + (MAX_STRING_LENGTH + 1) * 8)
     if len is None:
         raise ParserError("Torrent: unable to find string separator (':')")
     if not len:
         raise ParserError("Torrent: error: no string length!")
     val = String(self, "length", len, "String length")
     yield val
     try:
         len = int(val.value)
     except ValueError:
         len = -1
     if len < 0:
         raise ParserError(
             "Invalid string length (%s)" %
             makePrintable(val.value, "ASCII", to_unicode=True))
     yield String(self, "separator", 1, "String length/value separator")
     if not len:
         self.info("Empty string: len=%i" % len)
         return
     if len < 512:
         yield String(self,
                      "value",
                      len,
                      "String value",
                      charset="ISO-8859-1")
     else:
         # Probably raw data
         yield RawBytes(self, "value", len, "Raw data")
コード例 #3
0
ファイル: ole2.py プロジェクト: eduardoburgoa/hachoir_parser
 def getChain(self, start, use_sfat=False):
     if use_sfat:
         fat = self.ss_fat
         items_per_fat = self.items_per_ssfat
         err_prefix = "SFAT chain"
     else:
         fat = self.bb_fat
         items_per_fat = self.items_per_bbfat
         err_prefix = "BFAT chain"
     block = start
     block_set = set()
     previous = block
     while block != SECT.END_OF_CHAIN:
         if block in SECT.SPECIALS:
             raise ParserError(
                 "%s: Invalid block index (0x%08x), previous=%s" %
                 (err_prefix, block, previous))
         if block in block_set:
             raise ParserError("%s: Found a loop (%s=>%s)" %
                               (err_prefix, previous, block))
         block_set.add(block)
         yield block
         previous = block
         index = block // items_per_fat
         try:
             block = fat[index]["index[%u]" % block].value
         except LookupError:
             break
コード例 #4
0
    def _addField(self, field):
        """
        Add a field to the field set:
        * add it into _fields
        * update _current_size

        May raise a StopIteration() on error
        """
        if not issubclass(field.__class__, Field):
            raise ParserError("Field type (%s) is not a subclass of 'Field'!"
                % field.__class__.__name__)
        assert isinstance(field._name, str)
        if field._name.endswith("[]"):
            self.setUniqueFieldName(field)
        if config.debug:
            self.info("[+] DBG: _addField(%s)" % field.name)

        # required for the msoffice parser
        if field._address != self._current_size:
            self.warning("Fix address of %s to %s (was %s)" %
                (field.path, self._current_size, field._address))
            field._address = self._current_size

        ask_stop = False
        # Compute field size and check that there is enough place for it
        self.__is_feeding = True
        try:
            field_size = field.size
        except HACHOIR_ERRORS as err:
            if field.is_field_set and field.current_length and field.eof:
                self.warning("Error when getting size of '%s': %s" % (field.name, err))
                field._stopFeeding()
                ask_stop = True
            else:
                self.warning("Error when getting size of '%s': delete it" % field.name)
                self.__is_feeding = False
                raise
        self.__is_feeding = False

        # No more place?
        dsize = self._checkSize(field._address + field.size, False)
        if (dsize is not None and dsize < 0) or (field.is_field_set and field.size <= 0):
            if self.autofix and self._current_size:
                self._fixFieldSize(field, field.size + dsize)
            else:
                raise ParserError("Field %s is too large!" % field.path)

        self._current_size += field.size
        try:
            self._fields.append(field._name, field)
        except UniqKeyError as err:
            self.warning("Duplicate field name " + unicode(err))
            field._name += "[]"
            self.setUniqueFieldName(field)
            self._fields.append(field._name, field)
        if ask_stop:
            raise StopIteration()
コード例 #5
0
 def seekBit(self, address, relative=True):
     if not relative:
         address -= self.absolute_address
     if address < 0:
         raise ParserError("Seek below field set start (%s.%s)" %
                           divmod(address, 8))
     if not self._checkAddress(address):
         raise ParserError("Seek above field set end (%s.%s)" %
                           divmod(address, 8))
     self._offset = address
     return None
コード例 #6
0
 def createFields(self):
     yield Enum(UInt8(self, "tag"), self.root.CONSTANT_TYPES)
     if self["tag"].value not in self.root.CONSTANT_TYPES:
         raise ParserError("Java: unknown constant type (%s)" %
                           self["tag"].value)
     self.constant_type = self.root.CONSTANT_TYPES[self["tag"].value]
     if self.constant_type == "Utf8":
         yield PascalString16(self, "bytes", charset="UTF-8")
     elif self.constant_type == "Integer":
         yield Int32(self, "bytes")
     elif self.constant_type == "Float":
         yield Float32(self, "bytes")
     elif self.constant_type == "Long":
         yield Int64(self, "bytes")
     elif self.constant_type == "Double":
         yield Float64(self, "bytes")
     elif self.constant_type == "Class":
         yield CPIndex(self,
                       "name_index",
                       "Class or interface name",
                       target_types="Utf8")
     elif self.constant_type == "String":
         yield CPIndex(self, "string_index", target_types="Utf8")
     elif self.constant_type == "Fieldref":
         yield CPIndex(self,
                       "class_index",
                       "Field class or interface name",
                       target_types="Class")
         yield CPIndex(self,
                       "name_and_type_index",
                       target_types="NameAndType")
     elif self.constant_type == "Methodref":
         yield CPIndex(self,
                       "class_index",
                       "Method class name",
                       target_types="Class")
         yield CPIndex(self,
                       "name_and_type_index",
                       target_types="NameAndType")
     elif self.constant_type == "InterfaceMethodref":
         yield CPIndex(self,
                       "class_index",
                       "Method interface name",
                       target_types="Class")
         yield CPIndex(self,
                       "name_and_type_index",
                       target_types="NameAndType")
     elif self.constant_type == "NameAndType":
         yield CPIndex(self, "name_index", target_types="Utf8")
         yield CPIndex(self, "descriptor_index", target_types="Utf8")
     else:
         raise ParserError("Not a valid constant pool element type: " +
                           self["tag"].value)
コード例 #7
0
ファイル: ttf.py プロジェクト: hacker4help/The-Auto-Pentest
def parseFontHeader(self):
    yield UInt16(self, "maj_ver", "Major version")
    yield UInt16(self, "min_ver", "Minor version")
    yield UInt16(self, "font_maj_ver", "Font major version")
    yield UInt16(self, "font_min_ver", "Font minor version")
    yield textHandler(UInt32(self, "checksum"), hexadecimal)
    yield Bytes(self, "magic", 4, r"Magic string (\x5F\x0F\x3C\xF5)")
    if self["magic"].value != "\x5F\x0F\x3C\xF5":
        raise ParserError("TTF: invalid magic of font header")

    # Flags
    yield Bit(self, "y0", "Baseline at y=0")
    yield Bit(self, "x0", "Left sidebearing point at x=0")
    yield Bit(self, "instr_point", "Instructions may depend on point size")
    yield Bit(self, "ppem", "Force PPEM to integer values for all")
    yield Bit(self, "instr_width", "Instructions may alter advance width")
    yield Bit(self, "vertical", "e laid out vertically?")
    yield PaddingBits(self, "reserved[]", 1)
    yield Bit(self, "linguistic", "Requires layout for correct linguistic rendering?")
    yield Bit(self, "gx", "Metamorphosis effects?")
    yield Bit(self, "strong", "Contains strong right-to-left glyphs?")
    yield Bit(self, "indic", "contains Indic-style rearrangement effects?")
    yield Bit(self, "lossless", "Data is lossless (Agfa MicroType compression)")
    yield Bit(self, "converted", "Font converted (produce compatible metrics)")
    yield Bit(self, "cleartype", "Optimised for ClearType")
    yield Bits(self, "adobe", 2, "(used by Adobe)")

    yield UInt16(self, "unit_per_em", "Units per em")
    if not(16 <= self["unit_per_em"].value <= 16384):
        raise ParserError("TTF: Invalid unit/em value")
    yield UInt32(self, "created_high")
    yield TimestampMac32(self, "created")
    yield UInt32(self, "modified_high")
    yield TimestampMac32(self, "modified")
    yield UInt16(self, "xmin")
    yield UInt16(self, "ymin")
    yield UInt16(self, "xmax")
    yield UInt16(self, "ymax")

    # Mac style
    yield Bit(self, "bold")
    yield Bit(self, "italic")
    yield Bit(self, "underline")
    yield Bit(self, "outline")
    yield Bit(self, "shadow")
    yield Bit(self, "condensed", "(narrow)")
    yield Bit(self, "expanded")
    yield PaddingBits(self, "reserved[]", 9)

    yield UInt16(self, "lowest", "Smallest readable size in pixels")
    yield Enum(UInt16(self, "font_dir", "Font direction hint"), DIRECTION_NAME)
    yield Enum(UInt16(self, "ofst_format"), {0: "short offsets", 1: "long"})
    yield UInt16(self, "glyph_format", "(=0)")
コード例 #8
0
    def createFields(self):
        group = self["../group_desc/group[%u]" % self.uniq_id]
        superblock = self["/superblock"]
        block_size = self["/"].block_size

        # Read block bitmap
        addr = self.absolute_address + 56 * 8
        self.superblock_copy = (self.stream.readBytes(addr, 2) == "\x53\xEF")
        if self.superblock_copy:
            yield SuperBlock(self, "superblock_copy")

        # Compute number of block and inodes
        block_count = superblock["blocks_per_group"].value
        inode_count = superblock["inodes_per_group"].value
        block_index = self.uniq_id * block_count
        inode_index = self.uniq_id * inode_count
        if (block_count % 8) != 0:
            raise ParserError("Invalid block count")
        if (inode_count % 8) != 0:
            raise ParserError("Invalid inode count")
        block_count = min(block_count,
                          superblock["blocks_count"].value - block_index)
        inode_count = min(inode_count,
                          superblock["inodes_count"].value - inode_index)

        # Read block bitmap
        field = self.seekByte(group["block_bitmap"].value * block_size,
                              relative=False,
                              null=True)
        if field:
            yield field
        yield BlockBitmap(self, "block_bitmap", block_index, block_count,
                          "Block bitmap")

        # Read inode bitmap
        field = self.seekByte(group["inode_bitmap"].value * block_size,
                              relative=False)
        if field:
            yield field
        yield InodeBitmap(self, "inode_bitmap", inode_index, inode_count,
                          "Inode bitmap")

        # Read inode table
        field = self.seekByte(alignValue(self.current_size // 8, block_size))
        if field:
            yield field
        yield InodeTable(self, "inode_table", inode_index, inode_count)

        # Add padding if needed
        addr = min(self.parent.size / 8, (self.uniq_id + 1) *
                   superblock["blocks_per_group"].value * block_size)
        yield self.seekByte(addr, "data", relative=False)
コード例 #9
0
    def createFields(self):
        yield String(self, "start", 1, "Integer start delimiter (i)", charset="ASCII")

        # Find integer end
        addr = self.absolute_address+self.current_size
        len = self.stream.searchBytesLength('e', False, addr, addr+(MAX_INTEGER_SIZE+1)*8)
        if len is None:
            raise ParserError("Torrent: Unable to find integer end delimiter (e)!")
        if not len:
            raise ParserError("Torrent: error, empty integer!")

        yield String(self, "value", len, "Integer value", charset="ASCII")
        yield String(self, "end", 1, "Integer end delimiter")
コード例 #10
0
    def createFields(self):
        yield Bits(self, "sync[]", 2)  # =2
        if self["sync[0]"].value != 2:
            raise ParserError("Unknown video elementary data")
        yield Bits(self, "is_scrambled", 2)
        yield Bits(self, "priority", 1)
        yield Bit(self, "alignment")
        yield Bit(self, "is_copyrighted")
        yield Bit(self, "is_original")
        yield Bit(self, "has_pts", "Presentation Time Stamp")
        yield Bit(self, "has_dts", "Decode Time Stamp")
        yield Bit(self, "has_escr", "Elementary Stream Clock Reference")
        yield Bit(self, "has_es_rate", "Elementary Stream rate")
        yield Bit(self, "dsm_trick_mode")
        yield Bit(self, "has_copy_info")
        yield Bit(self, "has_prev_crc",
                  "If True, previous PES packet CRC follows")
        yield Bit(self, "has_extension")
        yield UInt8(self, "size")

        # Time stamps
        if self["has_pts"].value:
            yield Bits(self, "sync[]", 4)  # =2, or 3 if has_dts=True
            yield Timestamp(self, "pts")
        if self["has_dts"].value:
            if not (self["has_pts"].value):
                raise ParserError("Invalid PTS/DTS values")
            yield Bits(self, "sync[]", 4)  # =1
            yield Timestamp(self, "dts")

        if self["has_escr"].value:
            yield Bits(self, "sync[]", 2)  # =0
            yield SCR(self, "escr")

        if self["has_es_rate"].value:
            yield Bit(self, "sync[]")  # =True
            yield Bits(self, "es_rate", 14)  # in units of 50 bytes/second
            yield Bit(self, "sync[]")  # =True

        if self["has_copy_info"].value:
            yield Bit(self, "sync[]")  # =True
            yield Bits(self, "copy_info", 7)

        if self["has_prev_crc"].value:
            yield textHandler(UInt16(self, "prev_crc"), hexadecimal)

        # --- Extension ---
        if self["has_extension"].value:
            yield VideoExtension1(self, "extension")
            if self["extension/has_extension2"].value:
                yield VideoExtension2(self, "extension2")
コード例 #11
0
ファイル: ttf.py プロジェクト: hacker4help/The-Auto-Pentest
def parseNames(self):
    # Read header
    yield UInt16(self, "format")
    if self["format"].value != 0:
        raise ParserError("TTF (names): Invalid format (%u)" % self["format"].value)
    yield UInt16(self, "count")
    yield UInt16(self, "offset")
    if MAX_NAME_COUNT < self["count"].value:
        raise ParserError("Invalid number of names (%s)"
            % self["count"].value)

    # Read name index
    entries = []
    for index in xrange(self["count"].value):
        entry = NameHeader(self, "header[]")
        yield entry
        entries.append(entry)

    # Sort names by their offset
    entries.sort(key=lambda field: field["offset"].value)

    # Read name value
    last = None
    for entry in entries:
        # Skip duplicates values
        new = (entry["offset"].value, entry["length"].value)
        if last and last == new:
            self.warning("Skip duplicate %s %s" % (entry.name, new))
            continue
        last = (entry["offset"].value, entry["length"].value)

        # Skip negative offset
        offset = entry["offset"].value + self["offset"].value
        if offset < self.current_size//8:
            self.warning("Skip value %s (negative offset)" % entry.name)
            continue

        # Add padding if any
        padding = self.seekByte(offset, relative=True, null=True)
        if padding:
            yield padding

        # Read value
        size = entry["length"].value
        if size:
            yield String(self, "value[]", size, entry.description, charset=entry.getCharset())

    padding = (self.size - self.current_size) // 8
    if padding:
        yield NullBytes(self, "padding_end", padding)
コード例 #12
0
    def createFields(self):
        yield Header(self, "header")

        if MAX_NAME_PER_HEADER < self["header/nb_name"].value:
            raise ParserError("EXE resource: invalid number of name (%s)"
                % self["header/nb_name"].value)
        if MAX_INDEX_PER_HEADER < self["header/nb_index"].value:
            raise ParserError("EXE resource: invalid number of index (%s)"
                % self["header/nb_index"].value)

        hdr = self["header"]
        for index in xrange(hdr["nb_name"].value):
            yield NameOffset(self, "name[]")
        for index in xrange(hdr["nb_index"].value):
            yield IndexOffset(self, "index[]", self.res_type)
コード例 #13
0
ファイル: asn1.py プロジェクト: hacker4help/The-Auto-Pentest
 def __init__(self, parent, name, description=None):
     Field.__init__(self, parent, name, 8, description)
     stream = self._parent.stream
     addr = self.absolute_address
     value = stream.readBits(addr, 8, BIG_ENDIAN)
     if 128 <= value:
         nbits = (value & 127) * 8
         if not nbits:
             raise ParserError("ASN.1: invalid ASN integer size (zero)")
         if 64 < nbits:
             # Arbitrary limit to catch errors
             raise ParserError("ASN.1: ASN integer is limited to 64 bits")
         self._size = 8 + nbits
         value = stream.readBits(addr + 8, nbits, BIG_ENDIAN)
     self.createValue = lambda: value
コード例 #14
0
ファイル: asn1.py プロジェクト: hacker4help/The-Auto-Pentest
 def __init__(self, *args, **kw):
     FieldSet.__init__(self, *args, **kw)
     key = self["type"].value & 31
     if self['class'].value == 0:
         # universal object
         if key in self.TYPE_INFO:
             self._name, self._handler, self._description, create_desc = self.TYPE_INFO[
                 key]
             if create_desc:
                 self.createDescription = lambda: "%s: %s" % (
                     self.TYPE_INFO[key][2], create_desc(self))
                 self._description = None
         elif key == 31:
             raise ParserError(
                 "ASN.1 Object: tag bigger than 30 are not supported")
         else:
             self._handler = None
     elif self['form'].value:
         # constructed: treat as sequence
         self._name = 'seq[]'
         self._handler = readSequence
         self._description = 'constructed object type %i' % key
     else:
         # primitive, context/private
         self._name = 'raw[]'
         self._handler = readASCIIString
         self._description = '%s object type %i' % (self['class'].display,
                                                    key)
     field = self["size"]
     self._size = field.address + field.size + field.value * 8
コード例 #15
0
def parseTuple(parent):
    yield Int32(parent, "count", "Item count")
    count = parent["count"].value
    if count < 0:
        raise ParserError("Invalid tuple/list count")
    for index in xrange(count):
        yield Object(parent, "item[]")
コード例 #16
0
 def __init__(self, parent, name, **kw):
     FieldSet.__init__(self, parent, name, **kw)
     code = self["bytecode"].value
     if code not in self.bytecode_info:
         raise ParserError('Unknown bytecode: "%s"' % code)
     self.code_info = self.bytecode_info[code]
     if not name:
         self._name = self.code_info[0]
     if code == "l":
         self.createValue = self.createValueLong
     elif code in ("i", "I", "f", "g"):
         self.createValue = lambda: self["value"].value
     elif code == "T":
         self.createValue = lambda: True
     elif code == "F":
         self.createValue = lambda: False
     elif code in ("x", "y"):
         self.createValue = self.createValueComplex
     elif code in ("s", "t", "u"):
         self.createValue = self.createValueString
         self.createDisplay = self.createDisplayString
         if code == 't':
             if not hasattr(self.root, 'string_table'):
                 self.root.string_table = []
             self.root.string_table.append(self)
     elif code == 'R':
         if hasattr(self.root, 'string_table'):
             self.createValue = self.createValueStringRef
コード例 #17
0
    def createFields(self):
        yield Bytes(self, "header", 4, r"PE header signature (PE\0\0)")
        if self["header"].value != "PE\0\0":
            raise ParserError("Invalid PE header signature")
        yield Enum(UInt16(self, "cpu", "CPU type"), self.cpu_name)
        yield UInt16(self, "nb_section", "Number of sections")
        yield TimestampUnix32(self, "creation_date", "Creation date")
        yield UInt32(self, "ptr_to_sym", "Pointer to symbol table")
        yield UInt32(self, "nb_symbols", "Number of symbols")
        yield UInt16(self, "opt_hdr_size", "Optional header size")

        yield Bit(self, "reloc_stripped",
                  "If true, don't contain base relocations.")
        yield Bit(self, "exec_image", "Executable image?")
        yield Bit(self, "line_nb_stripped", "COFF line numbers stripped?")
        yield Bit(self, "local_sym_stripped",
                  "COFF symbol table entries stripped?")
        yield Bit(self, "aggr_ws", "Aggressively trim working set")
        yield Bit(self, "large_addr",
                  "Application can handle addresses greater than 2 GB")
        yield NullBits(self, "reserved", 1)
        yield Bit(self, "reverse_lo",
                  "Little endian: LSB precedes MSB in memory")
        yield Bit(self, "32bit", "Machine based on 32-bit-word architecture")
        yield Bit(self, "is_stripped", "Debugging information removed?")
        yield Bit(
            self, "swap",
            "If image is on removable media, copy and run from swap file")
        yield PaddingBits(self, "reserved2", 1)
        yield Bit(self, "is_system", "It's a system file")
        yield Bit(self, "is_dll", "It's a dynamic-link library (DLL)")
        yield Bit(self, "up", "File should be run only on a UP machine")
        yield Bit(self, "reverse_hi", "Big endian: MSB precedes LSB in memory")
コード例 #18
0
    def createFields(self):
        # Choose the right endian depending on endian specified in header
        if self.stream.readBits(5 * 8, 8,
                                BIG_ENDIAN) == ElfHeader.BIG_ENDIAN_ID:
            self.endian = BIG_ENDIAN
        else:
            self.endian = LITTLE_ENDIAN

        # Parse header and program headers
        yield ElfHeader(self, "header", "Header")
        for index in xrange(self["header/phnum"].value):
            yield ProgramHeader32(self, "prg_header[]")

        if False:
            raise ParserError("TODO: Parse sections...")
            #sections = self.array("prg_header")
            #size = self["header/shoff"].value - self.current_size//8
            #chunk = self.doRead("data", "Data", (DeflateFilter, stream, size, Sections, sections))
            #chunk.description = "Sections (use an evil hack to manage share same data on differents parts)"
            #assert self.current_size//8 == self["header/shoff"].value
        else:
            raw = self.seekByte(self["header/shoff"].value,
                                "raw[]",
                                relative=False)
            if raw:
                yield raw

        for index in xrange(self["header/shnum"].value):
            yield SectionHeader32(self, "section_header[]")
コード例 #19
0
 def __init__(self, *args, **kw):
     FieldSet.__init__(self, *args, **kw)
     if not self._size:
         frame_size = self.getFrameSize()
         if not frame_size:
             raise ParserError("MPEG audio: Invalid frame %s" % self.path)
         self._size = min(frame_size * 8, self.parent.size - self.address)
コード例 #20
0
ファイル: mkv.py プロジェクト: richardsonlima/Raspberry-Pwn
    def __init__(self, parent, ids):
        FieldSet.__init__(self, parent, "?[]")

        # Set name
        id = self['id'].value
        self.val = ids.get(id)
        if not self.val:
            if id == 0xBF:
                self.val = 'CRC-32[]', Binary
            elif id == 0xEC:
                self.val = 'Void[]', Binary
            elif id == 0x1B538667:
                self.val = 'SignatureSlot[]', signature
            else:
                self.val = 'Unknown[]', Binary
        self._name = self.val[0]

        # Compute size
        size = self['size']
        if size.value is not None:
            self._size = size.address + size.size + size.value * 8
        elif self._parent._parent:
            raise ParserError(
                "Unknown length (only allowed for the last Level 0 element)")
        elif self._parent._size is not None:
            self._size = self._parent._size - self.address
コード例 #21
0
ファイル: rpm.py プロジェクト: hacker4help/The-Auto-Pentest
    def createFields(self):
        # Read chunk header
        yield Bytes(self, "signature", 3, r"Property signature (\x8E\xAD\xE8)")
        if self["signature"].value != "\x8E\xAD\xE8":
            raise ParserError("Invalid property signature")
        yield UInt8(self, "version", "Signature version")
        yield NullBytes(self, "reserved", 4, "Reserved")
        yield UInt32(self, "count", "Count")
        yield UInt32(self, "size", "Size")

        # Read item header
        items = []
        for i in range(0, self["count"].value):
            item = ItemHeader(self, "item[]")
            yield item
            items.append(item)

        # Sort items by their offset
        items.sort(sortRpmItem)

        # Read item content
        start = self.current_size / 8
        for item in items:
            offset = item["offset"].value
            diff = offset - (self.current_size / 8 - start)
            if 0 < diff:
                yield NullBytes(self, "padding[]", diff)
            yield ItemContent(self, "content[]", item)
        size = start + self["size"].value - self.current_size / 8
        if 0 < size:
            yield NullBytes(self, "padding[]", size)
コード例 #22
0
 def __str__(self):
     """
     Returns a human-readable string representation of the constant pool
     entry.  It is used for pretty-printing of the CPIndex fields pointing
     to it.
     """
     if self.constant_type == "Utf8":
         return self["bytes"].value
     elif self.constant_type in ("Integer", "Float", "Long", "Double"):
         return self["bytes"].display
     elif self.constant_type == "Class":
         class_name = str(self["name_index"].get_cp_entry())
         return class_name.replace("/", ".")
     elif self.constant_type == "String":
         return str(self["string_index"].get_cp_entry())
     elif self.constant_type == "Fieldref":
         return "%s (from %s)" % (self["name_and_type_index"],
                                  self["class_index"])
     elif self.constant_type == "Methodref":
         return "%s (from %s)" % (self["name_and_type_index"],
                                  self["class_index"])
     elif self.constant_type == "InterfaceMethodref":
         return "%s (from %s)" % (self["name_and_type_index"],
                                  self["class_index"])
     elif self.constant_type == "NameAndType":
         return parse_any_descriptor(
             str(self["descriptor_index"].get_cp_entry()),
             name=str(self["name_index"].get_cp_entry()))
     else:
         # FIXME: Return "<error>" instead of raising an exception?
         raise ParserError("Not a valid constant pool element type: " +
                           self["tag"].value)
コード例 #23
0
def Entry(parent, name):
    addr = parent.absolute_address + parent.current_size
    tag = parent.stream.readBytes(addr, 1)
    if tag not in TAGS:
        raise ParserError("Torrent: Entry of type %r not handled" % type)
    cls = TAGS[tag]
    return cls(parent, name)
コード例 #24
0
    def createFields(self):
        # First kilobyte: boot sectors
        yield RawBytes(self, "boot", 1024, "Space for disklabel etc.")

        # Header
        yield UInt32(self, "version")
        yield UInt32(self, "last_page")
        yield UInt32(self, "nb_badpage")
        yield UUID(self, "sws_uuid")
        yield UUID(self, "sws_volume")
        yield NullBytes(self, "reserved", 117 * 4)

        # Read bad pages (if any)
        count = self["nb_badpage"].value
        if count:
            if MAX_SWAP_BADPAGES < count:
                raise ParserError("Invalid number of bad page (%u)" % count)
            yield GenericVector(self, "badpages", count, UInt32, "badpage")

        # Read magic
        padding = self.seekByte(PAGE_SIZE - 10, "padding", null=True)
        if padding:
            yield padding
        yield String(self, "magic", 10, charset="ASCII")

        # Read all pages
        yield GenericVector(self, "pages", self["last_page"].value, Page,
                            "page")

        # Padding at the end
        padding = self.seekBit(self.size, "end_padding", null=True)
        if padding:
            yield padding
コード例 #25
0
    def seekBit(self,
                address,
                name="padding[]",
                description=None,
                relative=True,
                null=False):
        """
        Create a field to seek to specified address,
        or None if it's not needed.

        May raise an (ParserError) exception if address is invalid.
        """
        if relative:
            nbits = address - self._current_size
        else:
            nbits = address - (self.absolute_address + self._current_size)
        if nbits < 0:
            raise ParserError("Seek error, unable to go back!")
        if 0 < nbits:
            if null:
                return createNullField(self, nbits, name, description)
            else:
                return createPaddingField(self, nbits, name, description)
        else:
            return None
コード例 #26
0
ファイル: png.py プロジェクト: hacker4help/The-Auto-Pentest
def paletteParse(parent):
    size = parent["size"].value
    if (size % 3) != 0:
        raise ParserError("Palette have invalid size (%s), should be 3*n!" % size)
    nb_colors = size // 3
    for index in xrange(nb_colors):
        yield RGB(parent, "color[]")
コード例 #27
0
    def createFields(self):
        yield textHandler(UInt32(self, "magic", "File information magic (0xFEEF04BD)"), hexadecimal)
        if self["magic"].value != 0xFEEF04BD:
            raise ParserError("EXE resource: invalid file info magic")
        yield Version(self, "struct_ver", "Structure version (1.0)")
        yield Version(self, "file_ver_ms", "File version MS")
        yield Version(self, "file_ver_ls", "File version LS")
        yield Version(self, "product_ver_ms", "Product version MS")
        yield Version(self, "product_ver_ls", "Product version LS")
        yield textHandler(UInt32(self, "file_flags_mask"), hexadecimal)

        yield Bit(self, "debug")
        yield Bit(self, "prerelease")
        yield Bit(self, "patched")
        yield Bit(self, "private_build")
        yield Bit(self, "info_inferred")
        yield Bit(self, "special_build")
        yield NullBits(self, "reserved", 26)

        yield Enum(textHandler(UInt16(self, "file_os_major"), hexadecimal), MAJOR_OS_NAME)
        yield Enum(textHandler(UInt16(self, "file_os_minor"), hexadecimal), MINOR_OS_NAME)
        yield Enum(textHandler(UInt32(self, "file_type"), hexadecimal), FILETYPE_NAME)
        field = textHandler(UInt32(self, "file_subfile"), hexadecimal)
        if field.value == FILETYPE_DRIVER:
            field = Enum(field, DRIVER_SUBTYPE_NAME)
        elif field.value == FILETYPE_FONT:
            field = Enum(field, FONT_SUBTYPE_NAME)
        yield field
        yield TimestampUnix32(self, "date_ms")
        yield TimestampUnix32(self, "date_ls")
コード例 #28
0
ファイル: exif.py プロジェクト: eduardoburgoa/hachoir_parser
    def createFields(self):
        offset_diff = 6
        yield UInt16(self, "count", "Number of entries")
        entries = []
        next_chunk_offset = None
        count = self["count"].value
        if not count:
            return
        while count:
            addr = self.absolute_address + self.current_size
            next = self.stream.readBits(addr, 32, NETWORK_ENDIAN)
            if next in (0, 0xF0000000):
                break
            entry = ExifEntry(self, "entry[]")
            yield entry
            if entry["tag"].value in (ExifEntry.EXIF_IFD_POINTER,
                                      ExifEntry.OFFSET_JPEG_SOI):
                next_chunk_offset = entry["value"].value + offset_diff
            if 32 < entry.getSizes()[0]:
                entries.append(entry)
            count -= 1
        yield UInt32(self, "next", "Next IFD offset")
        try:
            entries.sort(sortExifEntry)
        except TypeError:
            raise ParserError("Unable to sort entries!")
        value_index = 0
        for entry in entries:
            padding = self.seek(entry["offset"].value + offset_diff)
            if padding is not None:
                yield padding

            value_size, array_size = entry.getSizes()
            if not array_size:
                continue
            cls = entry.value_cls
            if 1 < array_size:
                name = "value_%s[]" % entry.name
            else:
                name = "value_%s" % entry.name
            desc = "Value of \"%s\"" % entry["tag"].display
            if cls is String:
                for index in xrange(array_size):
                    yield cls(self,
                              name,
                              value_size / 8,
                              desc,
                              strip=" \0",
                              charset="ISO-8859-1")
            elif cls is Bytes:
                for index in xrange(array_size):
                    yield cls(self, name, value_size / 8, desc)
            else:
                for index in xrange(array_size):
                    yield cls(self, name, desc)
            value_index += 1
        if next_chunk_offset is not None:
            padding = self.seek(next_chunk_offset)
            if padding is not None:
                yield padding
コード例 #29
0
ファイル: zip.py プロジェクト: hacker4help/The-Auto-Pentest
 def createFields(self):
     # File data
     self.signature = None
     self.central_directory = []
     while not self.eof:
         header = textHandler(UInt32(self, "header[]", "Header"), hexadecimal)
         yield header
         header = header.value
         if header == FileEntry.HEADER:
             yield FileEntry(self, "file[]")
         elif header == ZipDataDescriptor.HEADER:
             yield ZipDataDescriptor(self, "spanning[]")
         elif header == 0x30304b50:
             yield ZipDataDescriptor(self, "temporary_spanning[]")
         elif header == ZipCentralDirectory.HEADER:
             yield ZipCentralDirectory(self, "central_directory[]")
         elif header == ZipEndCentralDirectory.HEADER:
             yield ZipEndCentralDirectory(self, "end_central_directory", "End of central directory")
         elif header == Zip64EndCentralDirectory.HEADER:
             yield Zip64EndCentralDirectory(self, "end64_central_directory", "ZIP64 end of central directory")
         elif header == ZipSignature.HEADER:
             yield ZipSignature(self, "signature", "Signature")
         elif header == Zip64EndCentralDirectoryLocator.HEADER:
             yield Zip64EndCentralDirectoryLocator(self, "end_locator", "ZIP64 Enf of central directory locator")
         else:
             raise ParserError("Error, unknown ZIP header (0x%08X)." % header)
コード例 #30
0
ファイル: gif.py プロジェクト: richardsonlima/Raspberry-Pwn
    def createFields(self):
        # Header
        yield String(self, "magic", 3, "File magic code", charset="ASCII")
        yield String(self, "version", 3, "GIF version", charset="ASCII")

        yield ScreenDescriptor(self, "screen")
        if self["screen/global_map"].value:
            bpp = (self["screen/bpp"].value+1)
            yield PaletteRGB(self, "color_map", 1 << bpp, "Color map")
            self.color_map = self["color_map"]
        else:
            self.color_map = None

        self.images = []
        while True:
            code = Enum(Character(self, "separator[]", "Separator code"), self.separator_name)
            yield code
            code = code.value
            if code == "!":
                yield Extension(self, "extensions[]")
            elif code == ",":
                yield Image(self, "image[]")
            elif code == ";":
                # GIF Terminator
                break
            else:
                raise ParserError("Wrong GIF image separator: 0x%02X" % ord(code))