def select(fn, *tags, **boolean): '''Fetch a list of addresses within the function that contain the specified tags''' boolean = dict((k, set(v) if type(v) is tuple else set((v, ))) for k, v in boolean.viewitems()) if tags: boolean.setdefault( 'And', set(boolean.get( 'And', set())).union(set(tags) if len(tags) > 1 else set(tags, ))) if not boolean: for ea in iterate(fn): res = database.tag(ea) if res: yield ea, res return for ea in iterate(fn): res, d = {}, database.tag(ea) Or = boolean.get('Or', set()) res.update((k, v) for k, v in d.iteritems() if k in Or) And = boolean.get('And', set()) if And: if And.intersection(d.viewkeys()) == And: res.update((k, v) for k, v in d.iteritems() if k in And) else: continue if res: yield ea, res return
def select(fn, *tags, **boolean): '''Fetch a list of addresses within the function that contain the specified tags''' boolean = dict((k,set(v) if type(v) is tuple else set((v,))) for k,v in boolean.viewitems()) if tags: boolean.setdefault('And', set(boolean.get('And',set())).union(set(tags) if len(tags) > 1 else set(tags,))) if not boolean: for ea in iterate(fn): res = database.tag(ea) if res: yield ea, res return for ea in iterate(fn): res,d = {},database.tag(ea) Or = boolean.get('Or', set()) res.update((k,v) for k,v in d.iteritems() if k in Or) And = boolean.get('And', set()) if And: if And.intersection(d.viewkeys()) == And: res.update((k,v) for k,v in d.iteritems() if k in And) else: continue if res: yield ea,res return
def set_func_end(pfn, new_end): global State if State != state.ready: return # new_end has added addresses to function # replace globals with contents if new_end > pfn.endEA: for ea in database.address.iterate(pfn.endEA, new_end): for k in database.tag(ea): internal.comment.globals.dec(ea, k) internal.comment.contents.inc(ea, k, target=pfn.startEA) logging.debug( "{:s}.set_func_end({:#x}, {:#x}) : Decreasing refcount for global tag {!r} and increasing refcount for contents tag {!r}" .format(__name__, pfn.startEA, new_end, k, k)) continue return # new_end has removed addresses from function # replace contents with globals elif new_end < pfn.endEA: for ea in database.address.iterate(new_end, pfn.endEA): for k in database.tag(ea): internal.comment.contents.dec(ea, k, target=pfn.startEA) internal.comment.globals.inc(ea, k) logging.debug( "{:s}.set_func_end({:#x}, {:#x}) : Decreasing refcount for contents tag {!r} and increasing refcount for globals tag {!r}" .format(__name__, pfn.startEA, new_end, k, k)) continue return return
def apply_dyn_calls(dyn_calls, delete=False): hex = '{:x}'.format for dyn_call in dyn_calls: print(dyn_call) for i, p in enumerate(dyn_call.parents): print(i, hex(p)) top = func.top(p) if 'dynamic_call' not in func.tag(top): fn.tag(top, 'dynamic_call', set()) if delete: fn.tag(top, 'dynamic_call', None) continue curr_tag = fn.tag(top, 'dynamic_call') print(type(curr_tag), hex(top)) try: curr_tag.add(dyn_call.parents[i + 1]) except IndexError: curr_tag.add(dyn_call.call) fn.tag(top, 'dynamic_call', curr_tag) # Be sure to tag the actual function containing the dynamic call top = fn.top(dyn_call.call) if delete: if 'dynamic_call' in fn.tag(top): fn.tag(top, 'dynamic_call', None) if 'dynamic_call' in fn.tag(dyn_call.call): fn.tag(dyn_call.call, 'dynamic_call', None) continue if 'dynamic_call' not in fn.tag(top): fn.tag(top, 'dynamic_call', set()) curr_tag = fn.tag(top, 'dynamic_call') curr_tag.add(dyn_call.call) fn.tag(top, 'dynamic_call', curr_tag) db.tag(dyn_call.call, 'dynamic_call', 'here')
async def tag(request): try: request_body = request.json except Exception as e: return error(TMVException.ID_PARSE_JSON, 'Couldn\'t parse request body as JSON') try: verify_input(request_body, [{ 'name': 'value', 'required': True, 'type': 'str', }, { 'name': 'multi_tags', 'required': False, 'type': 'str[]', 'empty': False }, { 'name': 'value_tags', 'required': False, 'type': 'val[]', 'empty': False }]) value_tags = request_body[ 'value_tags'] if 'value_tags' in request_body else [] multi_tags = request_body[ 'multi_tags'] if 'multi_tags' in request_body else [] database.tag(request_body['value'], value_tags, multi_tags) return json({'success': True}) except TMVException as e: return error(e.error_id, e.error_msg) except Exception as e: return unknown_error(e)
def set_func_end(pfn, new_end): global State if State != state.ready: return # new_end has added addresses to function # replace globals with contents if new_end > interface.range.end(pfn): for ea in database.address.iterate(interface.range.end(pfn), new_end): for k in database.tag(ea): internal.comment.globals.dec(ea, k) internal.comment.contents.inc( ea, k, target=interface.range.start(pfn)) logging.debug( u"{:s}.set_func_end({:#x}, {:#x}) : Exchanging (decreasing) refcount for global tag {!s} and (increasing) refcount for contents tag {!s}." .format(__name__, interface.range.start(pfn), new_end, utils.string.repr(k), utils.string.repr(k))) continue return # new_end has removed addresses from function # replace contents with globals elif new_end < interface.range.end(pfn): for ea in database.address.iterate(new_end, interface.range.end(pfn)): for k in database.tag(ea): internal.comment.contents.dec( ea, k, target=interface.range.start(pfn)) internal.comment.globals.inc(ea, k) logging.debug( u"{:s}.set_func_end({:#x}, {:#x}) : Exchanging (increasing) refcount for global tag {!s} and (decreasing) refcount for contents tag {!s}." .format(__name__, interface.range.start(pfn), new_end, utils.string.repr(k), utils.string.repr(k))) continue return return
def __process_functions(): p = ui.progress() globals = internal.comment.globals.address() funcs = list(database.functions()) p.update(current=0, max=len(funcs), title="Pre-building tagcache...") p.open() for i, fn in enumerate(funcs): chunks = list(function.chunks(fn)) text = functools.partial("{:x} : Processing function {:d} of {:d} : ({:d} chunk{:s})".format, fn, i, len(funcs)) p.update(current=i) contents = set(internal.comment.contents.address(fn)) for ci, (l, r) in enumerate(chunks): p.update(text=text(len(chunks), 's' if len(chunks) != 1 else ''), tooltip="Chunk #{:d} : {:x} - {:x}".format(ci, l, r)) for ea in database.iterate(l, r): # FIXME: no need to iterate really since we should have # all of the addresses for k, v in database.tag(ea).iteritems(): if ea in globals: internal.comment.globals.dec(ea, k) if ea not in contents: internal.comment.contents.inc(ea, k, target=fn) continue continue continue p.close()
def __process_functions(percentage=0.10): p = ui.Progress() globals = set(internal.comment.globals.address()) total = 0 funcs = list(database.functions()) p.update(current=0, max=len(funcs), title=u"Pre-building tagcache...") p.open() six.print_(u"Pre-building tagcache for {:d} functions.".format(len(funcs))) for i, fn in enumerate(funcs): chunks = list(function.chunks(fn)) text = functools.partial(u"Processing function {:#x} ({chunks:d} chunk{plural:s}) -> {:d} of {:d}".format, fn, i + 1, len(funcs)) p.update(current=i) ui.navigation.procedure(fn) if i % (int(len(funcs) * percentage) or 1) == 0: six.print_(u"Processing function {:#x} -> {:d} of {:d} ({:.02f}%)".format(fn, i+1, len(funcs), i / float(len(funcs)) * 100.0)) contents = set(internal.comment.contents.address(fn)) for ci, (l, r) in enumerate(chunks): p.update(text=text(chunks=len(chunks), plural='' if len(chunks) == 1 else 's'), tooltip="Chunk #{:d} : {:#x} - {:#x}".format(ci, l, r)) ui.navigation.analyze(l) for ea in database.address.iterate(l, r): # FIXME: no need to iterate really since we should have # all of the addresses for k, v in six.iteritems(database.tag(ea)): if ea in globals: internal.comment.globals.dec(ea, k) if ea not in contents: internal.comment.contents.inc(ea, k, target=fn) total += 1 continue continue continue six.print_(u"Successfully built tag-cache composed of {:d} tag{:s}.".format(total, '' if total == 1 else 's')) p.close()
def breakMallocs(addr): breaks = '' mallocs = findMallocs(addr) for m in mallocs: db.tag( m, 'break', '.printf "{} - {} - malloc(0x%x) - ",poi(esp);g {};.printf "0x%x\\n",@eax;g' .format(hex(m), db.disasm(m), hex(db.next(m))[:-1])) # db.tag(m, 'break', '.printf "{} - {} - malloc(0x%x) - ",poi(esp);'.format(hex(m), db.disasm(m))) breaks += dump_breaks(m, stdout=False) db.tag(m, 'break', None) print('Writing breaks to F:\\bps') with open('F:\\bps', 'wb') as f: f.write(breaks)
def del_func(pfn): global State if State != state.ready: return # convert all contents into globals for l, r in function.chunks(pfn): for ea in database.address.iterate(l, r): for k in database.tag(ea): internal.comment.contents.dec( ea, k, target=interface.range.start(pfn)) internal.comment.globals.inc(ea, k) logging.debug( u"{:s}.del_func({:#x}) : Exchanging (increasing) refcount for global tag {!s} and (decreasing) refcount for contents tag {!s}." .format(__name__, interface.range.start(pfn), utils.string.repr(k), utils.string.repr(k))) continue continue # remove all function tags for k in function.tag(interface.range.start(pfn)): internal.comment.globals.dec(interface.range.start(pfn), k) logging.debug( u"{:s}.del_func({:#x}) : Removing (global) tag {!s} from function." .format(__name__, interface.range.start(pfn), utils.string.repr(k))) return
def func_tail_removed(pfn, ea): # XXX: this is for older versions of IDA global State if State != state.ready: return # first we'll grab the addresses from our refs res = internal.comment.contents.address(ea, target=interface.range.start(pfn)) # these are sorted, so first we'll filter out what doesn't belong missing = [item for item in res if idaapi.get_func(item) != pfn] # now iterate through the min/max of the list as hopefully this is # our event. for ea in database.address.iterate(min(missing), max(missing)): for k in database.tag(ea): internal.comment.contents.dec(ea, k, target=interface.range.start(pfn)) internal.comment.globals.inc(ea, k) logging.debug( u"{:s}.func_tail_removed({:#x}, {:#x}) : Exchanging (increasing) refcount for global tag {!s} and (decreasing) refcount for contents tag {!s}." .format(__name__, interface.range.start(pfn), ea, utils.string.repr(k), utils.string.repr(k))) continue return
def colormarks(color=0x7f007f): '''Iterate through all database marks and tag+color their address''' # tag and color f = set() for ea, m in database.marks(): database.tag(ea, 'mark', m) database.color(ea, color) try: f.add(function.top(ea)) except (LookupError, ValueError): pass # tag the functions too for ea in list(f): m = function.marks(ea) function.tag(ea, 'marks', [ea for ea, _ in m]) return
def __select(fn, q): for start,end in chunks(fn): for ea in database.iterate(start, end): d = database.tag(ea) # FIXME: bmn noticed .select yielding empty records if d and q.has(d): yield ea continue continue return
def colormarks(color=0x7f007f): '''Iterate through all database marks and tag+color their address''' # tag and color f = set() for ea,m in database.marks(): database.tag(ea, 'mark', m) database.color(ea, color) try: f.add(function.top(ea)) except ValueError: pass continue # tag the functions too for ea in list(f): m = function.marks(ea) function.tag(ea, 'marks', [ea for ea,_ in m]) return
def removing_func_tail(pfn, tail): global State if State != state.ready: return # tail = area_t for ea in database.iterate(tail.startEA, tail.endEA): for k in database.tag(ea): internal.comment.contents.dec(ea, k, target=pfn.startEA) internal.comment.globals.inc(ea, k) continue return
def removing_func_tail(pfn, tail): global State if State != state.ready: return # tail = area_t for ea in database.address.iterate(tail.startEA, tail.endEA): for k in database.tag(ea): internal.comment.contents.dec(ea, k, target=pfn.startEA) internal.comment.globals.inc(ea, k) logging.debug("{:s}.removing_func_tail({:#x}, {:#x}) : Decreasing refcount for contents tag {!r} and increasing refcount for global tag {!r}".format(__name__, pfn.startEA, tail.startEA, k, k)) continue return
def removing_func_tail(pfn, tail): global State if State != state.ready: return # tail = range_t for ea in database.address.iterate(*interface.range.unpack(tail)): for k in database.tag(ea): internal.comment.contents.dec(ea, k, target=interface.range.start(pfn)) internal.comment.globals.inc(ea, k) logging.debug(u"{:s}.removing_func_tail({:#x}, {:#x}) : Exchanging (increasing) refcount for global tag {!s} and (decreasing) refcount for contents tag {!s}.".format(__name__, interface.range.start(pfn), interface.range.start(tail), utils.string.repr(k), utils.string.repr(k))) continue return
def content(cls, ea): '''Iterate through every tag belonging to the contents of the function at `ea`.''' F = func.by(ea) # iterate through every address in the function for ea in func.iterate(F): ui.navigation.set(ea) # yield the tags res = db.tag(ea) if res: yield ea, res return
def fetch_function(f): addr, tags = {}, {} for ea in fn.iterate(f): res = db.tag(ea) #res.pop('name', None) for k, v in res.iteritems(): addr[ea] = addr.get(ea, 0) + 1 tags[k] = tags.get(k, 0) + 1 continue ea = f return fn.top(ea), addr, tags
def add_func(pfn): global State if State != state.ready: return # convert all globals into contents for (l,r) in function.chunks(pfn): for ea in database.iterate(l, r): for k in database.tag(ea): internal.comment.globals.dec(ea, k) internal.comment.contents.inc(ea, k, target=pfn.startEA) continue continue return
def add_func(pfn): global State if State != state.ready: return # convert all globals into contents for l, r in function.chunks(pfn): for ea in database.address.iterate(l, r): for k in database.tag(ea): internal.comment.globals.dec(ea, k) internal.comment.contents.inc(ea, k, target=pfn.startEA) logging.debug("{:s}.add_func({:#x}) : Decreasing refcount for global tag {!r} and increasing refcount for contents tag {!r}".format(__name__, pfn.startEA, k, k)) continue continue return
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 do_data(): addr, tags = {}, {} left, right = db.range() print 'fetching global tags' for ea in db.iterate(left, right - 1): f = idaapi.get_func(ea) if f is not None: continue res = db.tag(ea) #res.pop('name', None) for k, v in res.iteritems(): addr[ea] = addr.get(ea, 0) + 1 tags[k] = tags.get(k, 0) + 1 continue return addr, tags
def set_func_end(pfn, new_end): global State if State != state.ready: return # new_end has added addresses to function # replace globals with contents if new_end > pfn.endEA: for ea in database.iterate(pfn.endEA, new_end): for k in database.tag(ea): internal.comment.globals.dec(ea, k) internal.comment.contents.inc(ea, k, target=pfn.startEA) continue return # new_end has removed addresses from function # replace contents with globals elif new_end < pfn.endEA: for ea in database.iterate(new_end, pfn.endEA): for k in database.tag(ea): internal.comment.contents.dec(ea, k, target=pfn.startEA) internal.comment.globals.inc(ea, k) continue return return
def globals(): '''Yields all the global tags.''' ea, sentinel = db.range() while ea < sentinel: f = idaapi.get_func(ea) if f: t = fn.tag(ea) if t: yield ea, t ea = f.endEA continue t = db.tag(ea) if t: yield ea, t ea = db.a.next(ea) return
def colormarks(color=0x7f007f): """Walk through the current list of marks whilst coloring them with the specified `color`. Each mark's address is tagged with its description, and if the address belongs to a function, the function is also tagged with the address of the marks that it contains. """ # tag and color f = set() for ea, m in database.marks(): database.tag(ea, 'mark', m) if database.color(ea) is None: database.color(ea, color) try: f.add(func.top(ea)) except internal.exceptions.FunctionNotFoundError: pass continue # tag the functions too for ea in list(f): m = func.marks(ea) func.tag(ea, 'marks', [ea for ea, _ in m]) return
def del_func(pfn): global State if State != state.ready: return # convert all contents into globals for (l,r) in function.chunks(pfn): for ea in database.iterate(l, r): for k in database.tag(ea): internal.comment.contents.dec(ea, k, target=pfn.startEA) internal.comment.globals.inc(ea, k) continue continue # remove all function tags for k in function.tag(pfn.startEA): internal.comment.globals.dec(pfn.startEA, k) return
def tail_owner_changed(tail, owner_func): # XXX: this is for older versions of IDA global State if State != state.ready: return # this is easy as we just need to walk through tail and add it # to owner_func for ea in database.address.iterate(*interface.range.unpack(tail)): for k in database.tag(ea): internal.comment.contents.dec(ea, k) internal.comment.contents.inc(ea, k, target=owner_func) logging.debug( u"{:s}.tail_owner_changed({:#x}, {:#x}) : Exchanging (increasing) refcount for contents tag {!s} and (decreasing) refcount for contents tag {!s}." .format(__name__, interface.range.start(tail), owner_func, utils.string.repr(k), utils.string.repr(k))) continue return
def fetch_contents(fn): """Fetch the reference count for the contents of function `fn` in the database. Returns the tuple `(func, address, tags)` where the `address` and `tags` fields are both dictionaries containing the reference count for the addresses and tag names. The field `func` contains the address of the function. """ addr, tags = {}, {} for ea in func.iterate(fn): 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 func.address(fn), 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 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 function(ea): '''Yield each tag defined within a function.''' for ea in fn.iterate(ea): t = db.tag(ea) if t: yield ea, t return
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 print >> output, "--> Writing function contents... ({:d} entr{:s})".format( len(f), 'y' if len(f) == 1 else 'ies') for ea, d in sorted(f.items(), key=first): state = db.tag(ea) for k in state.viewkeys() & d.viewkeys(): if state[k] == d[k]: continue print >> output, "{:x} : {!r} : Overwriting contents tag with new value. : {!r} : {!r}".format( ea, k, state[k], d[k]) try: [db.tag(ea, tagmap.get(k, k), v) for k, v in d.iteritems()] except: logging.warn( "{:s}.load : {:x} : Unable to apply tags to contents. : {!r}". format(__name__, ea, d), exc_info=True) continue print >> output, "--> Applying frames to each function... ({:d} entr{:s})".format(
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