def search(cls, **type):
"""Search through all of the functions within the database and return the first result.
Please review the help for functions.list for the definition of ``type``.
"""
query_s = ', '.join("{:s}={!r}".format(k,v) for k,v in type.iteritems())
res = __builtin__.list(cls.iterate(**type))
if len(res) > 1:
__builtin__.map(logging.info, (("[{:d}] {:s}".format(i, function.name(ea))) for i,ea in enumerate(res)))
f = utils.compose(function.by,function.name)
logging.warn("{:s}.search({:s}) : Found {:d} matching results, returning the first one. : {!r}".format('.'.join((__name__, cls.__name__)), query_s, len(res), f(res[0])))
res = __builtin__.next(iter(res), None)
if res is None:
raise LookupError("{:s}.search({:s}) : Found 0 matching results.".format('.'.join((__name__, cls.__name__)), query_s))
return res
python类next()的实例源码
def disasm(ea, **options):
"""Disassemble the instructions at the address ``ea``.
If the integer ``count`` is specified, then return ``count`` number of instructions.
If the bool ``comments`` is True, then return the comments for each instruction as well.
"""
ea = interface.address.inside(ea)
res,count = [], options.get('count',1)
while count > 0:
insn = idaapi.generate_disasm_line(ea)
unformatted = idaapi.tag_remove(insn)
nocomment = unformatted[:unformatted.rfind(';')] if ';' in unformatted and not options.get('comments',False) else unformatted
res.append("{:x}: {:s}".format(ea, reduce(lambda t,x: t + (('' if t.endswith(' ') else ' ') if x == ' ' else x), nocomment, '')) )
ea = address.next(ea)
count -= 1
return '\n'.join(res)
def search(cls, **type):
"""Search through all of the names within the database and return the first result.
Please review the help for names.list for the definition of ``type``.
"""
query_s = ', '.join("{:s}={!r}".format(k,v) for k,v in type.iteritems())
res = __builtin__.list(cls.__iterate__(**type))
if len(res) > 1:
__builtin__.map(logging.info, (("[{:d}] {:x} {:s}".format(idx, idaapi.get_nlist_ea(idx), idaapi.get_nlist_name(idx))) for idx in res))
f1, f2 = idaapi.get_nlist_ea, idaapi.get_nlist_name
logging.warn("{:s}.search({:s}) : Found {:d} matching results, returning the first one. : {:x} {!r}".format('.'.join((__name__, cls.__name__)), query_s, len(res), f1(res[0]), f2(res[0])))
res = __builtin__.next(iter(res), None)
if res is None:
raise LookupError("{:s}.search({:s}) : Found 0 matching results.".format('.'.join((__name__, cls.__name__)), query_s))
return idaapi.get_nlist_ea(res)
def blocks(start, end):
'''Returns each block between the addresses ``start`` and ``end``.'''
block, _ = start, end = interface.address.head(start), address.tail(end)+1
for ea in iterate(start, end):
nextea = address.next(ea)
if _instruction.is_call(ea):
continue
if _instruction.is_return(ea):
yield block,nextea
block = ea
elif cxdown(ea):
yield block,nextea
block = nextea
elif cxup(ea) and block != ea:
yield block,ea
block = ea
continue
return
# FIXME: The idaapi.is_basic_block_end api has got to be faster than doing it
# with ida's xrefs in python..
def search(cls, **type):
"""Search through all of the entry-points within the database and return the first result.
Please review the help for entry.list for the definition of ``type``.
"""
query_s = ', '.join("{:s}={!r}".format(k,v) for k,v in type.iteritems())
res = __builtin__.list(cls.__iterate__(**type))
if len(res) > 1:
__builtin__.map(logging.info, (("[{:d}] {:x} : ({:x}) {:s}".format(idx, cls.__address__(idx), cls.__entryordinal__(idx), cls.__entryname__(idx))) for idx in res))
f = utils.compose(idaapi.get_entry_ordinal, idaapi.get_entry)
logging.warn("{:s}.search({:s}) : Found {:d} matching results, returning the first one. : {:x}".format('.'.join((__name__,cls.__name__)), query_s, len(res), f(res[0])))
res = __builtin__.next(iter(res), None)
if res is None:
raise LookupError("{:s}.search({:s}) : Found 0 matching results.".format('.'.join((__name__,cls.__name__)), query_s))
return cls.__address__(res)
def search(cls, **type):
"""Search through all of the imports within the database and return the first result.
Please review the help for imports.list for the definition of ``type``.
"""
query_s = ', '.join("{:s}={!r}".format(k,v) for k,v in type.iteritems())
res = __builtin__.list(cls.iterate(**type))
if len(res) > 1:
__builtin__.map(logging.info, ("{:x} {:s}<{:d}> {:s}".format(ea, module, ordinal, name) for ea,(module,name,ordinal) in res))
f = utils.compose(utils.second, cls.__formatl__)
logging.warn("{:s}.search({:s}) : Found {:d} matching results, returning the first one. : {!r}".format('.'.join((__name__,cls.__name__)), query_s, len(res), f(res[0])))
res = __builtin__.next(iter(res), None)
if res is None:
raise LookupError("{:s}.search({:s}) : Found 0 matching results.".format('.'.join((__name__,cls.__name__)), query_s))
return res[0]
def handle_nextarg(self, span, name):
'''Should be called to signalize a nextarg directive.
Args:
span (tuple of int): Start and end line of the directive.
name (str or None): Name of the argument following next or
None if it should be the next positional argument.
'''
self._check_for_open_block(span, 'nextarg')
block = self._open_blocks[-1]
directive, fname, spans = block[0:3]
self._check_if_matches_last(
directive, 'call', spans[-1], span, 'nextarg')
args, argnames = block[5:7]
args.append(self._curnode)
spans.append(span)
if name is not None:
argnames.append(name)
elif argnames:
msg = 'non-keyword argument following keyword argument'
raise FyppFatalError(msg, fname, span)
self._curnode = []
def next(itr, default=_undef):
"""compat wrapper for next()"""
if default is _undef:
return itr.next()
try:
return itr.next()
except StopIteration:
return default
def iterate(start, end, step=None):
'''Iterate through all of the instruction and data boundaries from address ``start`` to ``end``.'''
step = step or (address.prev if start > end else address.next)
start, end = __builtin__.map(interface.address.head, (start, end))
op = operator.gt if start > end else operator.lt
while start != idaapi.BADADDR and op(start,end):
yield start
start = step(start)
_, right = config.bounds()
if end < right: yield end
def __index__(cls, ea):
'''Returns the index of the entry-point at the specified ``address``.'''
f = utils.compose(idaapi.get_entry_ordinal, idaapi.get_entry)
iterable = itertools.imap(utils.compose(utils.fap(f, lambda n:n), __builtin__.tuple), __builtin__.range(idaapi.get_entry_qty()))
filterable = itertools.ifilter(utils.compose(utils.first, functools.partial(operator.eq, ea)), iterable)
result = itertools.imap(utils.second, filterable)
return __builtin__.next(result, None)
def new(cls, name):
'''Adds an entry-point to the database with the ``name`` using the next available index as the ordinal.'''
return cls.new(ui.current.address(), name, idaapi.get_entry_qty())
def get(cls, ea):
'''Return the import at the address ``ea``.'''
ea = interface.address.inside(ea)
res = itertools.ifilter(utils.compose(utils.first, functools.partial(operator.eq, ea)), cls.__iterate__())
try:
return utils.second(__builtin__.next(res))
except StopIteration:
pass
raise LookupError("{:s}.get({:x}) : Unable to determine import at specified address.".format('.'.join((__name__, cls.__name__)), ea))
def iterate(cls):
'''Return an iterator that walks forward through the database from the current address.'''
return cls.iterate(ui.current.address(), cls.next)
def iterate(cls, ea):
'''Return an iterator that walks forward through the database starting at the address ``ea``.'''
return cls.iterate(ea, cls.next)
def iterate(cls, ea, next):
'''Return an iterator that walks through the database starting at the address ``ea``. Use ``next`` to determine the next address.'''
ea = interface.address.inside(ea)
while ea not in (None,idaapi.BADADDR):
yield ea
ea = next(ea)
return
def next(cls):
'''Return the next defined address from the current one.'''
return cls.next(ui.current.address(), 1)
def next(cls, ea):
'''Return the next defined address from the address ``ea``.'''
return cls.next(ea, 1)
def nextdata(cls):
'''Returns the next address that has data referencing it.'''
return cls.nextdata(ui.current.address(), 1)
def nextdata(cls, ea):
'''Returns the next address from ``ea`` that has data referencing it.'''
return cls.nextdata(ea, 1)
def nextdata(cls, ea, count):
'''Returns the next address from ``ea`` that has data referencing it. Skip ``count`` results before returning.'''
res = cls.walk(ea, cls.next, lambda n: len(xref.data_up(n)) == 0)
return cls.nextdata(cls.next(res), count-1) if count > 1 else res
def nextcode(cls):
'''Returns the next address that has code referencing it.'''
return cls.nextcode(ui.current.address(), 1)
def nextcode(cls, ea):
'''Returns the next address from ``ea`` that has code referencing it.'''
return cls.nextcode(ea, 1)
def nextref(cls):
'''Returns the next address that has anything referencing it.'''
return cls.nextref(ui.current.address(), 1)
def nextref(cls, ea):
'''Returns the next address from ``ea`` that has anything referencing it.'''
return cls.nextref(ea, 1)
def nextref(cls, ea, count):
'''Returns the next address from ``ea`` that has anything referencing it. Skip ``count`` references before returning.'''
res = cls.walk(ea, cls.next, lambda n: len(xref.up(n)) == 0)
return cls.nextref(cls.next(res), count-1) if count > 1 else res
def nextreg(cls, ea, reg, *regs, **modifiers):
regs = (reg,) + regs
count = modifiers.get('count',1)
args = ', '.join(["{:x}".format(ea)] + __builtin__.map("\"{:s}\"".format, regs) + __builtin__.map(utils.unbox("{:s}={!r}".format), modifiers.items()))
# generate each helper using the regmatch class
iterops = interface.regmatch.modifier(**modifiers)
uses_register = interface.regmatch.use(regs)
# if within a function, then sure we're within the chunk's bounds.
if function.within(ea):
(_,end) = function.chunk(ea)
fwithin = functools.partial(operator.gt, end)
# otherwise ensure that we're not in a function and we're a code type.
else:
fwithin = utils.compose(utils.fap(utils.compose(function.within, operator.not_), type.is_code), all)
end = cls.walk(ea, cls.next, fwithin)
end = bottom() if end == idaapi.BADADDR else end
# define a function for cls.walk to continue looping while
F = lambda ea: fwithin(ea) and not any(uses_register(ea, opnum) for opnum in iterops(ea))
# skip the current address
nextea = cls.next(ea)
if nextea is None:
# FIXME: include registers in message
logging.fatal("{:s}.nextreg({:s}) : Unable to start walking from next address. : {:x}".format('.'.join((__name__, cls.__name__)), args, ea))
return ea
# now walk while none of our registers match
res = cls.walk(nextea, cls.next, F)
if res == idaapi.BADADDR or (cls == address and res >= end):
# FIXME: include registers in message
raise ValueError("{:s}.nextreg({:s}, ...) : Unable to find register{:s} within chunk {:x}:{:x} : {:x}".format('.'.join((__name__, cls.__name__)), args, ('s','')[len(regs)>1], end, ea, res))
# recurse if the user specified it
modifiers['count'] = count - 1
return cls.nextreg(cls.next(res), *regs, **modifiers) if count > 1 else res
def nextreg(cls, reg, *regs, **modifiers):
'''Return the next address containing an instruction that uses one of the specified registers ``regs``.'''
return cls.nextreg(ui.current.address(), reg, *regs, **modifiers)
def nextstack(cls, ea, delta):
'''Return the next instruction from ``ea`` that is past the sp delta ``delta``.'''
fn,sp = function.top(ea), function.get_spdelta(ea)
_,end = function.chunk(ea)
res = cls.walk(ea, cls.next, lambda ea: ea < end and abs(function.get_spdelta(ea) - sp) < delta)
if res == idaapi.BADADDR or res >= end:
raise ValueError("{:s}.nextstack({:x}, {:+x}) : Unable to locate instruction matching contraints due to walking outside the bounds of the function {:x} : {:x} >= {:x}".format('.'.join((__name__,cls.__name__)), ea, delta, fn, res, end))
return res
def nextcall(cls):
'''Return the next call instruction.'''
return cls.nextcall(ui.current.address(), 1)
def nextcall(cls, ea):
'''Return the next call instruction from the address ``ea``.'''
return cls.nextcall(ea, 1)