10

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.

15

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".

16

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()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.