def prevreg(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):
(start, _) = function.chunk(ea)
fwithin = functools.partial(operator.le, start)
# otherwise ensure that we're not in the function and we're a code type.
else:
fwithin = utils.compose(utils.fap(utils.compose(function.within, operator.not_), type.is_code), all)
start = cls.walk(ea, cls.prev, fwithin)
start = top() if start == idaapi.BADADDR else start
# 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
prevea = cls.prev(ea)
if prevea is None:
# FIXME: include registers in message
logging.fatal("{:s}.prevreg({:s}, ...) : Unable to start walking from previous address. : {:x}".format('.'.join((__name__, cls.__name__)), args, ea))
return ea
# now walk while none of our registers match
res = cls.walk(prevea, cls.prev, F)
if res == idaapi.BADADDR or (cls == address and res < start):
# FIXME: include registers in message
raise ValueError("{:s}.prevreg({:s}, ...) : Unable to find register{:s} within chunk. {:x}:{:x} : {:x}".format('.'.join((__name__, cls.__name__)), args, ('s','')[len(regs)>1], start, ea, res))
# recurse if the user specified it
modifiers['count'] = count - 1
return cls.prevreg( cls.prev(res), *regs, **modifiers) if count > 1 else res
评论列表
文章目录