def globals(): '''Iterate through all of the tags defined globally witin the database.''' ea, sentinel = db.config.bounds() # loop till we hit the end of the database while ea < sentinel: ui.navigation.auto(ea) funcQ = func.within(ea) # figure out which tag function to use f = func.tag if funcQ else db.tag # grab the tag and yield it res = f(ea) if res: yield ea, res # if we're in a function, then seek to the next chunk if funcQ: _, ea = func.chunk(ea) continue # otherwise, try the next address till we hit a sentinel value try: ea = db.a.next(ea) except internal.exceptions.OutOfBoundsError: ea = sentinel return
def globals(Globals, **tagmap): '''Apply the tags in `Globals` back into the database.''' global apply cls, tagmap_output = apply.__class__, u", {:s}".format(u', '.join(u"{:s}={:s}".format(internal.utils.string.escape(oldtag), internal.utils.string.escape(newtag)) for oldtag, newtag in six.iteritems(tagmap))) if tagmap else '' count = 0 for ea, res in Globals: ns = func if func.within(ea) else db # grab the current (old) tag state state = ns.tag(ea) # transform the new tag state using the tagmap new = { tagmap.get(name, name) : value for name, value in six.viewitems(res) } # check if the tag mapping resulted in the deletion of a tag if len(new) != len(res): for name in six.viewkeys(res) - six.viewkeys(new): logging.warn(u"{:s}.globals(...{:s}) : Refusing requested tag mapping as it results in the tag \"{:s}\" overwriting the tag \"{:s}\" in the global {:#x}. The value {!s} would be replaced with {!s}.".format('.'.join((__name__, cls.__name__)), tagmap_output, internal.utils.string.escape(name, '"'), internal.utils.string.escape(tagmap[name], '"'), ea, internal.utils.string.repr(res[name]), internal.utils.string.repr(res[tagmap[name]]))) pass # check what's going to be overwritten with different values prior to doing it for name in six.viewkeys(state) & six.viewkeys(new): if state[name] == new[name]: continue logging.warn(u"{:s}.globals(...{:s}) : Overwriting tag \"{:s}\" for global at {:#x} with new value {!s}. Old value was {!s}.".format('.'.join((__name__, cls.__name__)), tagmap_output, internal.utils.string.escape(name, '"'), ea, internal.utils.string.repr(new[name]), internal.utils.string.repr(state[name]))) # now we can apply the tags to the global address try: [ ns.tag(ea, name, value) for name, value in six.iteritems(new) if state.get(name, dummy) != value ] except: logging.warn(u"{:s}.globals(...{:s}) : Unable to apply tags ({!s}) to global {:#x}.".format('.'.join((__name__, cls.__name__)), tagmap_output, internal.utils.string.repr(new), ea), exc_info=True) # increase our counter count += 1 return count
def function(ea): '''Iterate through all addresses in the function ``ea`` and it's tagcache with any found tags.''' try: fn.top(ea) except LookupError: return {}, {} f, addr, tags = fetch_function(ea) for k in set(tags.keys()): if k in ('__tags__', '__address__'): if f in addr: addr[f] -= 1 if addr[f] == 0: addr.pop(f) if k in tags: tags[k] -= 1 if tags[k] == 0: tags.pop(k) continue for k, v in tags.iteritems(): internal.comment.contents.set_name(f, k, v) for k, v in addr.iteritems(): if not fn.within(k): continue internal.comment.contents.set_address(k, v) return addr, tags
def fetch_globals_data(): """Fetch the reference count for the global tags (non-function) in the database. Returns the tuple `(address, tags)` where the `address` and `tags` fields are both dictionaries containing the reference count for the addresses and tag names. """ addr, tags = {}, {} left, right = db.config.bounds() six.print_(u'globals: fetching tags from data', file=output) for ea in db.address.iterate(left, right): if func.within(ea): continue ui.navigation.auto(ea) # grab both comment types and decode them. after they've been decoded, # then iterate through all of their keys and tally up their counts. repeatable, nonrepeatable = (db.comment(ea, repeatable=item) for item in [True, False]) for items in map(internal.comment.decode, [repeatable, nonrepeatable]): #items.pop('name', None) for name in items: addr[ea] = addr.get(ea, 0) + 1 tags[name] = tags.get(name, 0) + 1 continue continue return addr, tags
def below(ea, includeSegment=False): '''Return all of the function names and their offset that are called by the function at `ea`.''' tryhard = lambda ea: "{:s}{:+x}".format(func.name(func.top( ea)), ea - func.top(ea)) if func.within(ea) else "{:+x}".format( ea) if func.name(ea) is None else func.name(ea) return '\n'.join(':'.join( [segment.name(ea), tryhard(ea)] if includeSegment else [tryhard(ea)]) for ea in func.down(ea))
def above(ea, includeSegment=False): '''Return all of the function names and their offset that calls the function at `ea`.''' tryhard = lambda ea: "{:s}{:+x}".format(func.name(func.top( ea)), ea - func.top(ea)) if func.within(ea) else "{:+x}".format( ea) if func.name(ea) is None else func.name(ea) return '\n'.join( ':'.join((segment.name(ea), tryhard(ea)) if includeSegment else (tryhard(ea), )) for ea in func.up(ea))
def customnames(): '''Iterate through all of the custom names defined in the database and update the cache with their reference counts.''' # FIXME: first delete all the custom names '__name__' tag left, right = db.config.bounds() for ea in db.address.iterate(left, right): ctx = internal.comment.contents if func.within(ea) and func.address(ea) != ea else internal.comment.globals if db.type.has_customname(ea): ctx.inc(ea, '__name__') continue return
def customnames(): '''Iterate through all of the custom names defined in the database and update the cache with their reference counts.''' # FIXME: first delete all the custom names '__name__' tag left, right = db.range() for ea in db.address.iterate(left, right): ctx = internal.comment.globals if not func.within(ea) or func.address(ea) == ea else internal.comment.contents if db.type.has_customname(ea): ctx.inc(ea, '__name__') continue return
def below(ea, includeSegment=False): '''Display all the functions that the function at /ea/ can call''' tryhard = lambda ea: "{:s}+{:x}".format(database.name(function.top( ea)), ea - function.top(ea)) if function.within( ea) else "+{:x}".format(ea) if database.name( ea) is None else database.name(ea) return '\n'.join( ':'.join((segment.name(ea), tryhard(ea)) if includeSegment else (tryhard(ea), )) for ea in function.down(ea))
def globals(Globals, **tagmap): '''Apply the tags in `Globals` back into the database.''' global apply cls, tagmap_output = apply.__class__, ", {:s}".format(', '.join( "{:s}={:s}".format(oldtag, newtag) for oldtag, newtag in six.iteritems(tagmap))) if tagmap else '' count = 0 for ea, res in Globals: ns = func if func.within(ea) else db # grab the current (old) tag state state = ns.tag(ea) # transform the new tag state using the tagmap new = { tagmap.get(name, name): value for name, value in six.viewitems(res) } # check if the tag mapping resulted in the deletion of a tag if len(new) != len(res): for name in six.viewkeys(res) - six.viewkeys(new): logging.warn( "{:s}.globals(...{:s}) : Refusing requested tag mapping as it results in the tag {!r} overwriting the tag {!r} in the global {:#x}. The value {!r} would be replaced with {!r}." .format('.'.join((__name__, cls.__name__)), tagmap_output, name, tagmap[name], ea, res[name], res[tagmap[name]])) pass # check what's going to be overwritten with different values prior to doing it for name in six.viewkeys(state) & six.viewkeys(new): if state[name] == new[name]: continue logging.warn( "{:s}.globals(...{:s}) : Overwriting tag {!r} for global at {:#x} with new value {!r}. Old value was {!r}." .format('.'.join((__name__, cls.__name__)), tagmap_output, name, ea, new[name], state[name])) # now we can apply the tags to the global address try: [ ns.tag(ea, name, value) for name, value in six.iteritems(new) if state.get(name, dummy) != value ] except: logging.warn( "{:s}.globals(...{:s}) : Unable to apply tags ({!r}) to global {:#x}." .format('.'.join((__name__, cls.__name__)), tagmap_output, new, ea), exc_info=True) # increase our counter count += 1 return count
def extracomments(): '''Iterate through all of the extra comments defined in the database and update the cache with their reference counts.''' left, right = db.range() for ea in db.address.iterate(left, right): ctx = internal.comment.contents if func.within(ea) else internal.comment.globals count = db.extra.__count__(ea, idaapi.E_PREV) if count: [ ctx.inc(ea, '__extra_prefix__') for i in six.moves.range(count) ] count = db.extra.__count__(ea, idaapi.E_NEXT) if count: [ ctx.inc(ea, '__extra_suffix__') for i in six.moves.range(count) ] return
def extracomments(): '''Iterate through all of the extra comments defined in the database and update the cache with their reference counts.''' left, right = db.config.bounds() for ea in db.address.iterate(left, right): ctx = internal.comment.contents if func.within(ea) else internal.comment.globals count = db.extra.__count__(ea, idaapi.E_PREV) if count: [ ctx.inc(ea, '__extra_prefix__') for i in range(count) ] count = db.extra.__count__(ea, idaapi.E_NEXT) if count: [ ctx.inc(ea, '__extra_suffix__') for i in range(count) ] return
def _collectcall(addr, result): process = set() for f in func.down(addr): if any(f in coll for coll in (result, sentinel)): continue if not func.within(f): logging.warn("{:s}.collectcall({:#x}, {!r}) : Adding non-function address {:#x} ({:s}).".format(__name__, ea, sentinel, f, database.name(f))) result.add(f) continue process.add(f) for addr in process: result |= _collectcall(addr, result | process) return result
def _collectcall(addr, result): process = {item for item in []} for f in func.down(addr): if any(f in coll for coll in [result, sentinel]): continue if not func.within(f): logging.warning("{:s}.collectcall({:#x}, {!r}) : Adding non-function address {:#x} ({:s}).".format(__name__, ea, sentinel, f, database.name(f))) result.add(f) continue process.add(f) for addr in process: result |= _collectcall(addr, result | process) return result
def contents(ea): '''Re-build the cache for the contents of the function `ea`.''' try: func.address(ea) except internal.exceptions.FunctionNotFoundError: return {}, {} # read addresses and tags from contents ui.navigation.auto(ea) logging.debug( u"{:s}.contents({:#x}): Fetching the contents from the function {:#x}." .format('.'.join([__name__]), ea, ea)) f, addr, tags = fetch_contents(ea) # clean out any hidden tag values for k in tags.keys(): if k in {'__tags__', '__address__'}: if f in addr: addr[f] -= 1 if addr[f] == 0: addr.pop(f) if k in tags: tags[k] -= 1 if tags[k] == 0: tags.pop(k) continue # update addresses and tags to contents ui.navigation.set(ea) logging.debug( u"{:s}.contents({:#x}): Updating the name reference cache for the contents of function {:#x}." .format('.'.join([__name__]), ea, ea)) for k, v in tags.items(): internal.comment.contents.set_name(f, k, v) logging.debug( u"{:s}.contents({:#x}): Updating the address reference cache for the contents of function {:#x}." .format('.'.join([__name__]), ea, ea)) for k, v in addr.items(): if not func.within(k): continue internal.comment.contents.set_address(k, v) return addr, tags
def check_global(ea): '''Validate the cache defined for the global at the address `ea`.''' if func.within(ea): return False cache = internal.comment.decode(db.comment(db.top())) cache.update(internal.comment.decode(db.comment(db.bottom()))) node = internal.netnode.get(internal.comment.tagging.node()) tag = internal.comment.decode(db.comment(ea)) if cache and '__address__' not in cache: return False if not cache and tag: return False count = internal.netnode.alt.get(node, ea) if tag and not count: return False if len(tag['__address__']) != count: return False keys = tag['__tags__'] if any(t not in cache for t in keys): return False return True
def check_global(ea): '''Validate the cache defined for the global at the address `ea`.''' if func.within(ea): return False cache = internal.comment.decode(db.comment(db.top())) cache.update( internal.comment.decode(db.comment(db.bottom())) ) node = internal.netnode.get(internal.comment.tagging.node()) tag = internal.comment.decode(db.comment(ea)) if cache and '__address__' not in cache: return False if not cache and tag: return False count = internal.netnode.alt.get(node, ea) if tag and not count: return False if len(tag['__address__']) != count: return False keys = tag['__tags__'] if any(t not in cache for t in keys): return False return True
def fetch_globals_data(): """Fetch the reference count for the global tags (non-function) in the database. Returns the tuple `(address, tags)` where the `address` and `tags` fields are both dictionaries containing the reference count for the addresses and tag names. """ addr, tags = {}, {} left, right = db.range() six.print_(u'globals: fetching tags from data', file=output) for ea in db.address.iterate(left, right): if func.within(ea): continue ui.navigation.auto(ea) res = db.tag(ea) #res.pop('name', None) for k, v in six.iteritems(res): addr[ea] = addr.get(ea, 0) + 1 tags[k] = tags.get(k, 0) + 1 continue return addr, tags
def fetch_globals_data(): """Fetch the reference count for the global tags (non-function) in the database. Returns the tuple `(address, tags)` where the `address` and `tags` fields are both dictionaries containing the reference count for the addresses and tag names. """ addr, tags = {}, {} left, right = db.range() print >> output, 'globals: fetching tags from data' for ea in db.address.iterate(left, right): if func.within(ea): continue ui.navigation.auto(ea) res = db.tag(ea) #res.pop('name', None) for k, v in six.iteritems(res): addr[ea] = addr.get(ea, 0) + 1 tags[k] = tags.get(k, 0) + 1 continue return addr, tags
def contents(Contents, **tagmap): '''Apply the tags in `Contents` back into each function within the database.''' global apply cls, tagmap_output = apply.__class__, u", {:s}".format(u', '.join(u"{:s}={:s}".format(internal.utils.string.escape(oldtag), internal.utils.string.escape(newtag)) for oldtag, newtag in six.iteritems(tagmap))) if tagmap else '' count = 0 for loc, res in Contents: ea = locationToAddress(loc) # warn the user if this address is not within a function if not func.within(ea): logging.warn(u"{:s}.contents(...{:s}) : Address {:#x} is not within a function. Using a global tag.".format('.'.join((__name__, cls.__name__)), tagmap_output, ea)) # grab the current (old) tag state state = db.tag(ea) # transform the new tag state using the tagmap new = { tagmap.get(name, name) : value for name, value in six.viewitems(res) } # check if the tag mapping resulted in the deletion of a tag if len(new) != len(res): for name in six.viewkeys(res) - six.viewkeys(new): logging.warn(u"{:s}.contents(...{:s}) : Refusing requested tag mapping as it results in the tag \"{:s}\" overwriting tag \"{:s}\" for the contents at {:#x}. The value {!s} would be overwritten by {!s}.".format('.'.join((__name__, cls.__name__)), tagmap_output, internal.utils.string.escape(name, '"'), internal.utils.string.escape(tagmap[name], '"'), ea, internal.utils.string.repr(res[name]), internal.utils.string.repr(res[tagmap[name]]))) pass # inform the user if any tags are being overwritten with different values for name in six.viewkeys(state) & six.viewkeys(new): if state[name] == new[name]: continue logging.warn(u"{:s}.contents(...{:s}) : Overwriting contents tag \"{:s}\" for address {:#x} with new value {!s}. Old value was {!s}.".format('.'.join((__name__, cls.__name__)), tagmap_output, internal.utils.string.escape(name, '"'), ea, internal.utils.string.repr(new[name]), internal.utils.string.repr(state[name]))) # write the tags to the contents address try: [ db.tag(ea, name, value) for name, value in six.iteritems(new) if state.get(name, dummy) != value ] except: logging.warn(u"{:s}.contents(...{:s}) : Unable to apply tags {!s} to location {:#x}.".format('.'.join((__name__, cls.__name__)), tagmap_output, internal.utils.string.repr(new), ea), exc_info=True) # increase our counter count += 1 return count
def contents(ea): '''Re-build the cache for the contents of the function `ea`.''' try: func.address(ea) except internal.exceptions.FunctionNotFoundError: return {}, {} # read addresses and tags from contents ui.navigation.auto(ea) logging.debug(u"{:s}.contents({:#x}): Fetching the contents from the function {:#x}.".format('.'.join(('custom', __name__)), ea, ea)) f, addr, tags = fetch_contents(ea) # clean out any hidden tag values for k in six.viewkeys(tags): if k in {'__tags__', '__address__'}: if f in addr: addr[f] -= 1 if addr[f] == 0: addr.pop(f) if k in tags: tags[k] -= 1 if tags[k] == 0: tags.pop(k) continue # update addresses and tags to contents ui.navigation.set(ea) logging.debug(u"{:s}.contents({:#x}): Updating the name reference cache for the contents of function {:#x}.".format('.'.join(('custom', __name__)), ea, ea)) for k, v in six.iteritems(tags): internal.comment.contents.set_name(f, k, v) logging.debug(u"{:s}.contents({:#x}): Updating the address reference cache for the contents of function {:#x}.".format('.'.join(('custom', __name__)), ea, ea)) for k, v in six.iteritems(addr): if not func.within(k): continue internal.comment.contents.set_address(k, v) return addr, tags
def above(ea): '''Display all the callers of the function at /ea/''' tryhard = lambda x: '%s+%x'%(database.name(function.top(x)),x-function.top(x)) if function.within(x) else hex(x) if database.name(x) is None else database.name(x) return '\n'.join(map(tryhard,function.up(ea)))
def below(ea, includeSegment=False): '''Return all of the function names and their offset that are called by the function at `ea`.''' tryhard = lambda ea: "{:s}{:+x}".format(func.name(func.top(ea)), ea - func.top(ea)) if func.within(ea) else "{:+x}".format(ea) if func.name(ea) is None else func.name(ea) return '\n'.join(':'.join((segment.name(ea), tryhard(ea)) if includeSegment else (tryhard(ea),)) for ea in func.down(ea))
def contents(Contents, **tagmap): '''Apply the tags in `Contents` back into each function within the database.''' global apply cls, tagmap_output = apply.__class__, ", {:s}".format(', '.join( "{:s}={:s}".format(oldtag, newtag) for oldtag, newtag in six.iteritems(tagmap))) if tagmap else '' count = 0 for loc, res in Contents: ea = locationToAddress(loc) # warn the user if this address is not within a function if not func.within(ea): logging.warn( "{:s}.contents(...{:s}) : Address {:#x} is not within a function. Using a global tag." .format('.'.join((__name__, cls.__name__)), tagmap_output, ea)) # grab the current (old) tag state state = db.tag(ea) # transform the new tag state using the tagmap new = { tagmap.get(name, name): value for name, value in six.viewitems(res) } # check if the tag mapping resulted in the deletion of a tag if len(new) != len(res): for name in six.viewkeys(res) - six.viewkeys(new): logging.warn( "{:s}.contents(...{:s}) : Refusing requested tag mapping as it results in the tag {!r} overwriting tag {!r} for the contents at {:#x}. The value {!r} would be overwritten by {!r}." .format('.'.join((__name__, cls.__name__)), tagmap_output, name, tagmap[name], ea, res[name], res[tagmap[name]])) pass # inform the user if any tags are being overwritten with different values for name in six.viewkeys(state) & six.viewkeys(new): if state[name] == new[name]: continue logging.warn( "{:s}.contents(...{:s}) : Overwriting contents tag {!r} for address {:#x} with new value {!r}. Old value was {!r}." .format('.'.join((__name__, cls.__name__)), tagmap_output, name, ea, new[name], state[name])) # write the tags to the contents address try: [ db.tag(ea, name, value) for name, value in six.iteritems(new) if state.get(name, dummy) != value ] except: logging.warn( "{:s}.contents(...{:s}) : Unable to apply tags {!r} to location {:#x}." .format('.'.join((__name__, cls.__name__)), tagmap_output, new, ea), exc_info=True) # increase our counter count += 1 return count
def contents(Contents, **tagmap): '''Apply the tags in `Contents` back into each function within the database.''' global apply cls, tagmap_output = apply.__class__, u", {:s}".format(u', '.join( u"{:s}={:s}".format(internal.utils.string.escape(oldtag), internal.utils.string.escape(newtag)) for oldtag, newtag in tagmap.items())) if tagmap else '' count = 0 for loc, res in Contents: ea = locationToAddress(loc) # warn the user if this address is not within a function if not func.within(ea): logging.warning( u"{:s}.contents(...{:s}) : Address {:#x} is not within a function. Using a global tag." .format('.'.join([__name__, cls.__name__]), tagmap_output, ea)) # grab the current (old) tag state state = db.tag(ea) # transform the new tag state using the tagmap new = { tagmap.get(name, name): value for name, value in res.items() } # check if the tag mapping resulted in the deletion of a tag if len(new) != len(res): reskeys, newkeys = ({item for item in items.keys()} for items in [res, new]) for name in reskeys - newkeys: logging.warning( u"{:s}.contents(...{:s}) : Refusing requested tag mapping as it results in the tag \"{:s}\" overwriting tag \"{:s}\" for the contents at {:#x}. The value {!s} would be overwritten by {!s}." .format( '.'.join([__name__, cls.__name__]), tagmap_output, internal.utils.string.escape(name, '"'), internal.utils.string.escape(tagmap[name], '"'), ea, internal.utils.string.repr(res[name]), internal.utils.string.repr(res[tagmap[name]]))) pass # inform the user if any tags are being overwritten with different values statekeys, newkeys = ({item for item in items.keys()} for items in [state, new]) for name in statekeys & newkeys: if state[name] == new[name]: continue logging.warning( u"{:s}.contents(...{:s}) : Overwriting contents tag \"{:s}\" for address {:#x} with new value {!s}. Old value was {!s}." .format('.'.join([__name__, cls.__name__]), tagmap_output, internal.utils.string.escape(name, '"'), ea, internal.utils.string.repr(new[name]), internal.utils.string.repr(state[name]))) # write the tags to the contents address try: [ db.tag(ea, name, value) for name, value in new.items() if state.get(name, dummy) != value ] except: logging.warning( u"{:s}.contents(...{:s}) : Unable to apply tags {!s} to location {:#x}." .format('.'.join([__name__, cls.__name__]), tagmap_output, internal.utils.string.repr(new), ea), exc_info=True) # increase our counter count += 1 return count
def below(ea): '''Display all the functions that the function at /ea/ can call''' tryhard = lambda x: '%s+%x' % (database.name(function.top( x)), x - function.top(x)) if function.within(x) else hex( x) if database.name(x) is None else database.name(x) return '\n'.join(map(tryhard, function.down(ea)))
def globals(Globals, **tagmap): '''Apply the tags in `Globals` back into the database.''' global apply cls, tagmap_output = apply.__class__, u", {:s}".format(u', '.join( u"{:s}={:s}".format(internal.utils.string.escape(oldtag), internal.utils.string.escape(newtag)) for oldtag, newtag in tagmap.items())) if tagmap else '' count = 0 for ea, res in Globals: ns = func if func.within(ea) else db # grab the current (old) tag state state = ns.tag(ea) # transform the new tag state using the tagmap new = { tagmap.get(name, name): value for name, value in res.items() } # check if the tag mapping resulted in the deletion of a tag if len(new) != len(res): reskeys, newkeys = ({item for item in items.keys()} for items in [res, new]) for name in reskeys - newkeys: logging.warning( u"{:s}.globals(...{:s}) : Refusing requested tag mapping as it results in the tag \"{:s}\" overwriting the tag \"{:s}\" in the global {:#x}. The value {!s} would be replaced with {!s}." .format( '.'.join([__name__, cls.__name__]), tagmap_output, internal.utils.string.escape(name, '"'), internal.utils.string.escape(tagmap[name], '"'), ea, internal.utils.string.repr(res[name]), internal.utils.string.repr(res[tagmap[name]]))) pass # check what's going to be overwritten with different values prior to doing it statekeys, newkeys = ({item for item in items.keys()} for items in [state, new]) for name in statekeys & newkeys: if state[name] == new[name]: continue logging.warning( u"{:s}.globals(...{:s}) : Overwriting tag \"{:s}\" for global at {:#x} with new value {!s}. Old value was {!s}." .format('.'.join([__name__, cls.__name__]), tagmap_output, internal.utils.string.escape(name, '"'), ea, internal.utils.string.repr(new[name]), internal.utils.string.repr(state[name]))) # now we can apply the tags to the global address try: [ ns.tag(ea, name, value) for name, value in new.items() if state.get(name, dummy) != value ] except: logging.warning( u"{:s}.globals(...{:s}) : Unable to apply tags ({!s}) to global {:#x}." .format('.'.join([__name__, cls.__name__]), tagmap_output, internal.utils.string.repr(new), ea), exc_info=True) # increase our counter count += 1 return count
def below(ea): '''Display all the functions that the function at /ea/ can call''' tryhard = lambda x: '%s+%x'%(database.name(function.top(x)),x-function.top(x)) if function.within(x) else hex(x) if database.name(x) is None else database.name(x) return '\n'.join(map(tryhard,function.down(ea)))
member.comment = internal.comment.encode(state) if type is not None: member.type = type continue return def load((g, f, h), **tagmap): '''Write all the tags from (g, f, h) into the database.''' first = operator.itemgetter(0) print >> output, "--> Writing globals... ({:d} entr{:s})".format( len(g), 'y' if len(g) == 1 else 'ies') for ea, d in sorted(g.items(), key=first): m = fn if fn.within(ea) else db state = m.tag(ea) for k in state.viewkeys() & d.viewkeys(): if state[k] == d[k]: continue print >> output, "{:x} : {!r} : Overwriting global tag with new value. : {!r} : {!r}".format( ea, k, state[k], d[k]) try: [m.tag(ea, tagmap.get(k, k), v) for k, v in d.iteritems()] except: logging.warn( "{:s}.load : {:x} : Unable to apply tags to global. : {!r}". format(__name__, ea, d), exc_info=True) continue
def above(ea): '''Display all the callers of the function at /ea/''' tryhard = lambda x: '%s+%x' % (database.name(function.top( x)), x - function.top(x)) if function.within(x) else hex( x) if database.name(x) is None else database.name(x) return '\n'.join(map(tryhard, function.up(ea)))