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
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)
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
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
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
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
def str(self): s = builtins.unicode(self.value, 'utf-16-be').encode('utf-8') return utils.strdup(s)[:len(self)]
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
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
def str(self): s = self.value.decode('utf-16-be') return utils.strdup(s)[:len(self)]