binaryninja-api icon indicating copy to clipboard operation
binaryninja-api copied to clipboard

BN does not propogate enum type from array member to constant values

Open reversing-dev opened this issue 2 years ago • 4 comments

Version and Platform (required):

  • Binary Ninja Version: 3.6.4709-dev Personal, 715fcd79
  • OS: windows
  • OS Version: 11
  • CPU Architecture: x86_64

Bug Description:

Initial analysis: image

After fixing the array size, the initial enum name is lost: image

Expected output: (I had to map each enum val to name manually) image

Also, if it's possible to default select the last used enum in the Select Enum dialogue box it will be useful in similar scenarios.

reversing-dev avatar Dec 08 '23 19:12 reversing-dev

Related to: https://github.com/Vector35/binaryninja-api/issues/4431

xusheng6 avatar Dec 12 '23 16:12 xusheng6

I have created a simpler binary to reproduce this:

test_enum_arrary.zip

Screenshot 2024-06-06 at 1 01 46 PM

Looking at the expression type, it seems that we correctly deduce the type of arr[0] is the enum, we just fail to propagate that to the right side of the comparison

xusheng6 avatar Jun 06 '24 05:06 xusheng6

If I look at the MLIL, if explains:

>>> current_il_instruction
<MediumLevelILSetVarField: arr[0] = 1>
>>> current_il_instruction.dest
<var enum foobar arr[0x3]>
>>> current_il_instruction.dest.type
<type: immutable:ArrayTypeClass 'enum foobar[0x3]'>

xusheng6 avatar Jun 06 '24 05:06 xusheng6

So this issue a bit trickier than I have expected. While at HLIL we correctly deduce the type of arr[1] is an enum (see the screenshot above) and we should be able to just do the type propagation easily, we are actually only doing the type propagation at MLIL. And unfortunately, the MLIL instruction is a MediumLevelILSetVarField, which means the operand arr[1] does not even exists:

Screenshot 2024-08-01 at 2 00 19 PM

In the above screenshot, we are unable to show the expression type of the var_28[1] on the left side because, well, it is not an expression.

>>> current_il_instruction
<MediumLevelILSetVarField: var_28[1] = 1>
>>> current_il_instruction.operands
[<var enum foobar var_28[0x3]>, 4, <MediumLevelILConst: 1>]

Similarly we are also missing the opportunity if we have an structure assignment like foo.bar = 0x123, where bar is an enum.

xusheng6 avatar Aug 01 '24 06:08 xusheng6