Say I have an arbitrary address and I want to find out which basic block (i.e. area_t structure) corresponds to it. How would I do that?
Edit: more specifically, I want to know the beginning / end of the basic block to which a given address belongs.
Say I have an arbitrary address and I want to find out which basic block (i.e. area_t structure) corresponds to it. How would I do that?
Edit: more specifically, I want to know the beginning / end of the basic block to which a given address belongs.
As suggested by DCoder, I use the following helper class to efficiently resolve addresses to basic blocks:
# Wrapper to operate on sorted basic blocks.
class BBWrapper(object):
def __init__(self, ea, bb):
self.ea_ = ea
self.bb_ = bb
def get_bb(self):
return self.bb_
def __lt__(self, other):
return self.ea_ < other.ea_
# Creates a basic block cache for all basic blocks in the given function.
class BBCache(object):
def __init__(self, f):
self.bb_cache_ = []
for bb in idaapi.FlowChart(f):
self.bb_cache_.append(BBWrapper(bb.startEA, bb))
self.bb_cache_ = sorted(self.bb_cache_)
def find_block(self, ea):
i = bisect_right(self.bb_cache_, BBWrapper(ea, None))
if i:
return self.bb_cache_[i-1].get_bb()
else:
return None
It can be used like this:
bb_cache = BBCache(idaapi.get_func(here()))
found = bb_cache.find_block(here())
if found:
print "found: %X - %X" % (found.startEA, found.endEA)
else:
print "No basic block found that contains %X" % here()
I put this together quickly in the File > Python command... dialog:
tgtEA = idaapi.askaddr(0, "Enter target address")
if tgtEA is None:
exit
f = idaapi.get_func(tgtEA)
if not f:
print "No function at 0x%x" % (tgtEA)
exit
fc = idaapi.FlowChart(f)
for block in fc:
if block.startEA <= tgtEA:
if block.endEA > tgtEA:
print "0x%x is part of block [0x%x - 0x%x)" % (tgtEA, block.startEA, block.endEA)
Keep in mind that IDA's basic block addresses are "startEA inclusive, endEA exclusive".