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
评论列表
文章目录