Vector35 / binaryninja-api

Public API, examples, documentation and issues for Binary Ninja
https://binary.ninja/
MIT License
941 stars 213 forks source link

Need `BNGetLiftedlILBasicBlockForInstruction` to ensure `il_basic_block` will return successfully on lifted_il APIs #1320

Open ElykDeer opened 5 years ago

ElykDeer commented 5 years ago

On any sufficiently large binary, /bin/ls for example, the following code will not complete without generating an exception.

for func in bv.functions:
  for bb in func.lifted_il:
    for inst in bb:
      inst.il_basic_block

When replacing func.lifted_il with either func.llil or func.mlil, it seems to work fine.

The exception generated is:

Exception AttributeError: "'LowLevelILBasicBlock' object has no attribute 'handle'" in <object repr() failed> ignored
Traceback (most recent call last):
  File "<console>", line 4, in <module>
  File "/home/kyle/binaryninja/plugins/../python/binaryninja/lowlevelil.py", line 537, in il_basic_block
    return LowLevelILBasicBlock(view, core.BNGetLowLevelILBasicBlockForInstruction(self.function.handle, self.instr_index), self.function)
  File "/home/kyle/binaryninja/plugins/../python/binaryninja/lowlevelil.py", line 2413, in __init__
    super(LowLevelILBasicBlock, self).__init__(handle, view)
  File "/home/kyle/binaryninja/plugins/../python/binaryninja/basicblock.py", line 62, in __init__
    self.handle = core.handle_of_type(handle, core.BNBasicBlock)
  File "/home/kyle/binaryninja/plugins/../python/binaryninja/_binaryninjacore.py", line 13434, in handle_of_type
    raise ValueError('expected pointer to %s' % str(handle_type))
ValueError: expected pointer to <class 'binaryninja._binaryninjacore.BNBasicBlock'>

Later, when closing ipython or waiting an arbitrary amount of time, the following exception is generated:

Exception ignored in: <object repr() failed>
Traceback (most recent call last):
  File "/home/kyle/binaryninja/python/binaryninja/basicblock.py", line 69, in __del__
AttributeError: 'LowLevelILBasicBlock' object has no attribute 'handle'

Nearly identical blocks/instructions are affected, does seem to break consistently on the same block in the same binary, but I I think that's more happenstance than anything.

Present in both Python2 and Python3, sorta seems like a dangling pointer issue to me.

ElykDeer commented 3 years ago

Still repros on 2.4.3060-dev.

Throws assertion:

Traceback (most recent call last):
  File "<console>", line 4, in <module>
  File "/home/kyle/binaryninja-dev/plugins/../python/binaryninja/lowlevelil.py", line 540, in il_basic_block
    assert core_block is not None, "BNGetLowLevelILBasicBlockForInstruction returned None"
AssertionError: BNGetLowLevelILBasicBlockForInstruction returned None
plafosse commented 2 weeks ago

The underlying issue here is that we don't have a BNGetLiftedlILBasicBlockForInstruction and we're just counting lifted and llil being roughly equal when they aren't.