Exemplo n.º 1
0
    def iterate(self):
        '''[(hint, importentry_name, importentry_offset, importentry_value),...]'''
        Header = headers.locateHeader(self)
        int, iat = self['INT'], self['IAT']

        cache, sections = {}, Header['Sections']
        for entry, address in itertools.izip(int.d.li[:-1], iat.d.li[:-1]):
            if entry.OrdinalQ():
                ordinal = entry['Ordinal']
                hint = ordinal['Ordinal Number'] & 0xffff
                yield hint, "Ordinal{:d}".format(
                    hint), address.getoffset(), address.int()
                continue
            name = entry['Name']
            va = name['Name']
            section = sections.getsectionbyaddress(va)
            sectionofs = section.getoffset()
            if sectionofs in cache:
                sectionva, data = cache[sectionofs]
            else:
                sectionva, data = cache.setdefault(
                    sectionofs, (section['VirtualAddress'].int(),
                                 array.array('B',
                                             section.data().li.serialize())))
            hintofs = va - sectionva
            hint = data[hintofs] | data[hintofs + 1] * 0x100
            yield hint, utils.strdup(
                data[hintofs +
                     2:].tostring()), address.getoffset(), address.int()
        return
Exemplo n.º 2
0
    def iterate(self):
        '''[(hint,importname,importtableaddress),...]'''
        address = self['IAT'].num()
        header = self.getparent(Header)
        section = header['Sections'].getsectionbyaddress(address)
        data = array.array('c',section.data().l.serialize())

        sectionva = section['VirtualAddress'].num()
        nametable = self['INT'].num()-sectionva

        while nametable < len(data):
            # get name
            name = reduce(lambda total,x: ord(x) + total*0x100, reversed(data[nametable:nametable+4]), 0)
            nametable += 4

            # if end of names
            if name == 0:
                return

            # ordinal
            if name & 0x80000000:
                hint = name & 0xffff
                yield (hint, 'Ordinal%d'% hint, address)
                address += 4
                continue

            # string
            p = (name & 0x7fffffff) - sectionva
            hint = reduce(lambda total,x: ord(x) + total*0x100, reversed(data[p:p+2]), 0)
            yield (hint, utils.strdup(data[p+2:].tostring()), address)
            address += 4

        raise ValueError("Terminated reading imports due to being out of input at %x"% address)
Exemplo n.º 3
0
    def GetNames(self):
        """Returns a list of all the export names"""
        Header = headers.locateHeader(self)
        cache, sections = {}, Header['Sections']

        res = []
        for va in self['AddressOfNames'].d.l:
            section = sections.getsectionbyaddress(va.int())
            sectionva, data = cache[section.getoffset()] if section.getoffset() in cache else cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))
            nameofs = va.int() - sectionva
            res.append(utils.strdup(data[nameofs:].tostring()))
        return res
Exemplo n.º 4
0
    def GetNames(self):
        """Returns a list of all the export names"""
        Header = LocateHeader(self)
        cache, sections = {}, Header['Sections']

        res = []
        for va in self['AddressOfNames'].d.l:
            section = sections.getsectionbyaddress(va.int())
            sectionva, data = cache[section.getoffset()] if section.getoffset() in cache else cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))
            nameofs = va.int() - sectionva
            res.append(utils.strdup(data[nameofs:].tostring()))
        return res
Exemplo n.º 5
0
    def getNames(self):
        """Returns a list of all the export names"""
        Header = headers.locateHeader(self)
        section = Header['Sections'].getsectionbyaddress(self['AddressOfNames'].int())

        sectionva = section['VirtualAddress'].int()
        offsets = [ (x.int()-sectionva) for x in self['AddressOfNames'].d.load() ]
        data = section.data().load().serialize()

        names = []
        for x in offsets:
            names.append(utils.strdup(data[x:]))
        return names
Exemplo n.º 6
0
    def getExportAddressTable(self):
        """Returns (export address table offset,[virtualaddress of each export]) from the export address table"""
        Header = headers.locateHeader(self)
        exportdirectory = self.parent.parent

        address = self['AddressOfFunctions'].int()
        section = Header['Sections'].getsectionbyaddress(address)

        sectionva = section['VirtualAddress'].int()
        offset = address - sectionva
        data = section.data().load().serialize()

        block = data[offset: offset + 4*self['NumberOfFunctions'].int()]
        addresses = ( struct.unpack_from('L', block, offset)[0] for offset in xrange(0, len(block), 4) )

        result = []
        for i,va in enumerate(addresses):
            result.append( utils.strdup(data[va-sectionva:]) if exportdirectory.contains(va) else va )
        return address,result
Exemplo n.º 7
0
 def str(self):
     s = builtins.unicode(self.value, 'utf-16-be').encode('utf-8')
     return utils.strdup(s)[:len(self)]
Exemplo n.º 8
0
    def iterate(self):
        """For each export, yields (rva offset, hint, name, ordinalname, entrypoint, forwardedrva)"""
        cls = self.__class__
        ExportDirectory = self.getparent(headers.IMAGE_DATA_DIRECTORY)
        Header, Base = headers.locateHeader(self), self['Base'].int()

        # our section data cache
        cache, sections = {}, Header['Sections']

        # grab everything that's important
        aof, aon, aono = self['AddressOfFunctions'], self['AddressOfNames'], self['AddressOfNameOrdinals']

        ## export address table
        if aof.int() > 0:
            # cache the section the eat is contained in since we need it anyways
            section = sections.getsectionbyaddress(aof.int())
            cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))

            # convert the aof into an array that's wikiwiki
            data = aof.d.l.cast(dyn.array(dword, len(aof.d)))
            eat = array.array('L', data.l.serialize())

            # check that the aof is within the bounds of the section, warn the user despite supporting it anyways
            if any(not section.containsaddress(ea) for ea in (aof.int(), aof.int() + 4*self['NumberOfFunctions'].int())):
                logging.warn("{:s} : Export Address Table goes outside bounds of designated section. ({:#x} <= {:#x}{:+#x} < {:#x})".format('.'.join((cls.__module__, cls.__name__)), section['VirtualAddress'].int(), aof.int(), aof.int() + 4*self['NumberOfFunctions'].int(), section['VirtualAddress'].int() + section['VirtualSize'].int()))
        else:
            logging.warn("{:s} : No export addresses found in IMAGE_EXPORT_DIRECTORY. ({:s})".format('.'.join((cls.__module__, cls.__name__)), aof.summary()))
            eat = array.array('L', [])

        ## name ordinal table
        if aono.int() > 0:
            # cache the section the aono is contained in since we need it anyways
            section = sections.getsectionbyaddress(aono.int())
            cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))

            # convert the aono into an array that's also quick
            data = aono.d.l.cast(dyn.array(word, len(aono.d)))
            no = array.array('H', data.l.serialize())

            # check that the aono is within the bounds of the section, warn the user despite supporting it anyways
            if any(not section.containsaddress(ea) for ea in (aono.int(), aono.int() + 2*self['NumberOfNames'].int())):
                logging.warn("{:s} : Export Name Ordinal Table goes outside bounds of designated section. ({:#x} <= {:#x}{:+#x} < {:#x})".format('.'.join((cls.__module__, cls.__name__)), section['VirtualAddress'].int(), aono.int(), aono.int() + 2*self['NumberOfNames'].int(), section['VirtualAddress'].int() + section['VirtualSize'].int()))
        else:
            logging.warn("{:s} : No Export Name Ordinal Table in IMAGE_EXPORT_DIRECTORY. ({:s})".format('.'.join((cls.__module__, cls.__name__)), aono.summary()))
            no = array.array('H', [])

        # check the name table
        if aon.int() == 0:
            logging.warn("{:s} : No Export Name Table in IMAGE_EXPORT_DIRECTORY. ({:s})".format('.'.join((cls.__module__, cls.__name__)), aon.summary()))
            nt = []
        else:
            nt = aon.d.l

        # now we can start returning things to the user
        va = headers.calculateRelativeOffset(self, aof.int())
        for nameva, ordinal in map(None, nt, no):

            # grab the name if we can
            if nameva is None:
                name = None
            else:
                section = sections.getsectionbyaddress(nameva.int())
                sectionva, data = cache[section.getoffset()] if section.getoffset() in cache else cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))
                nameofs = nameva.int() - sectionva
                name = utils.strdup(data[nameofs:].tostring())

            # grab the ordinal if we can
            if ordinal is None:
                forwarded, value = None, None

            elif 0 <= ordinal <= len(eat):
                # this is inside the export directory, so it's a forwardedrva
                if ExportDirectory.containsaddress(eat[ordinal]):
                    section = sections.getsectionbyaddress(eat[ordinal])
                    sectionva, data = cache[section.getoffset()] if section.getoffset() in cache else cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))
                    forwarded, value = utils.strdup(data[eat[ordinal] - sectionva:].tostring()), None

                # otherwise, it's a valid address
                else:
                    forwarded, value = None, eat[ordinal]

            # this ordinal is outside the export address table, although
            # we can read from the file to deal with these sort of fuxed
            # things... this is currently unsupported by pecoff
            else:
                logging.warning("{:s} : Error resolving export address for {:s} : !({:d} <= {:d} < {:d})".format('.'.join((cls.__module__, cls.__name__)), name, 0, ordinal, len(eat)))
                forwarded, value = None, None

            ordinalstring = None if ordinal is None else "Ordinal{:d}".format(ordinal + Base)
            yield va, ordinal, name, ordinalstring, value, forwarded
            va += 4
        return
Exemplo n.º 9
0
    def iterate(self):
        """For each export, yields (rva offset, hint, name, ordinalname, entrypoint, forwardedrva)"""
        cls = self.__class__
        ExportDirectory = self.getparent(headers.IMAGE_DATA_DIRECTORY)
        Header, Base = LocateHeader(self), self['Base'].int()

        # our section data cache
        cache, sections = {}, Header['Sections']

        # grab everything that's important
        aof, aon, aono = self['AddressOfFunctions'], self['AddressOfNames'], self['AddressOfNameOrdinals']

        ## export address table
        if aof.int() > 0:
            # cache the section the eat is contained in since we need it anyways
            section = sections.getsectionbyaddress(aof.int())
            cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))

            # convert the aof into an array that's wikiwiki
            data = aof.d.l.cast(dyn.array(dword, len(aof.d)))
            eat = array.array('I', data.serialize())

            # check that the aof is within the bounds of the section, warn the user despite supporting it anyways
            if any(not section.containsaddress(ea) for ea in (aof.int(), aof.int() + 4*self['NumberOfFunctions'].int())):
                logging.warn("{:s} : Export Address Table goes outside bounds of designated section. ({:#x} <= {:#x}{:+#x} < {:#x})".format('.'.join((cls.__module__, cls.__name__)), section['VirtualAddress'].int(), aof.int(), aof.int() + 4*self['NumberOfFunctions'].int(), section['VirtualAddress'].int() + section['VirtualSize'].int()))
        else:
            logging.warn("{:s} : No export addresses found in IMAGE_EXPORT_DIRECTORY. ({:s})".format('.'.join((cls.__module__, cls.__name__)), aof.summary()))
            eat = array.array('I', [])

        ## name ordinal table
        if aono.int() > 0:
            # cache the section the aono is contained in since we need it anyways
            section = sections.getsectionbyaddress(aono.int())
            cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))

            # convert the aono into an array that's also quick
            data = aono.d.l.cast(dyn.array(word, len(aono.d)))
            no = array.array('H', data.l.serialize())

            # check that the aono is within the bounds of the section, warn the user despite supporting it anyways
            if any(not section.containsaddress(ea) for ea in (aono.int(), aono.int() + 2*self['NumberOfNames'].int())):
                logging.warn("{:s} : Export Name Ordinal Table goes outside bounds of designated section. ({:#x} <= {:#x}{:+#x} < {:#x})".format('.'.join((cls.__module__, cls.__name__)), section['VirtualAddress'].int(), aono.int(), aono.int() + 2*self['NumberOfNames'].int(), section['VirtualAddress'].int() + section['VirtualSize'].int()))
        else:
            logging.warn("{:s} : No Export Name Ordinal Table in IMAGE_EXPORT_DIRECTORY. ({:s})".format('.'.join((cls.__module__, cls.__name__)), aono.summary()))
            no = array.array('H', [])

        # check the name table
        if aon.int() == 0:
            logging.warn("{:s} : No Export Name Table in IMAGE_EXPORT_DIRECTORY. ({:s})".format('.'.join((cls.__module__, cls.__name__)), aon.summary()))
            nt = []
        else:
            nt = aon.d.l

        # now we can start returning things to the user
        va = CalculateRelativeOffset(self, aof.int())
        for nameva, ordinal in map(None, nt, no):

            # grab the name if we can
            if nameva is None:
                name = None
            else:
                section = sections.getsectionbyaddress(nameva.int())
                sectionva, data = cache[section.getoffset()] if section.getoffset() in cache else cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))
                nameofs = nameva.int() - sectionva
                name = utils.strdup(data[nameofs:].tostring())

            # grab the ordinal if we can
            if ordinal is None:
                forwarded, value = None, None

            elif 0 <= ordinal <= len(eat):
                # this is inside the export directory, so it's a forwardedrva
                if ExportDirectory.containsaddress(eat[ordinal]):
                    section = sections.getsectionbyaddress(eat[ordinal])
                    sectionva, data = cache[section.getoffset()] if section.getoffset() in cache else cache.setdefault(section.getoffset(), (section['VirtualAddress'].int(), array.array('B', section.data().l.serialize())))
                    forwarded, value = utils.strdup(data[eat[ordinal] - sectionva:].tostring()), None

                # otherwise, it's a valid address
                else:
                    forwarded, value = None, eat[ordinal]

            # this ordinal is outside the export address table, although
            # we can read from the file to deal with these sort of fuxed
            # things... this is currently unsupported by pecoff
            else:
                logging.warning("{:s} : Error resolving export address for {:s} : !({:d} <= {:d} < {:d})".format('.'.join((cls.__module__, cls.__name__)), name, 0, ordinal, len(eat)))
                forwarded, value = None, None

            ordinalstring = None if ordinal is None else "Ordinal{:d}".format(ordinal + Base)
            yield va, ordinal, name, ordinalstring, value, forwarded
            va += 4
        return
Exemplo n.º 10
0
 def str(self):
     s = self.value.decode('utf-16-be')
     return utils.strdup(s)[:len(self)]
Exemplo n.º 11
0
 def str(self):
     s = builtins.unicode(self.value, 'utf-16-be').encode('utf-8')
     return utils.strdup(s)[:len(self)]