fkie-cad / dewolf

A research decompiler implemented as a Binary Ninja plugin.
GNU Lesser General Public License v2.1
176 stars 9 forks source link

[Lifter] Lift MediumLevelILConstPtr as None #127

Closed ebehner closed 1 year ago

ebehner commented 2 years ago

What happened?

Depending on the properties of a MediumLevelILConstPtr we lift it as None (see function lift_constant_pointer in handlers/constants.py). If it is the RHS of an assignment, then we call the update function of the basic block when inserting the node. This function tries to update the definitions and dependencies of the basic block. Thus, it calls requirements on the RHS of the instruction leading to an error, since None does not have the attribute requirements.

How to reproduce?

Ask for the sample, it is malware (shadowbot.exe, sha1-sum: 8f19c2139a6de10c363816b0f7bccd6203c38257).

The following pointer is lifted as None: pointer

When trying to debug it, set a conditional break-point at line https://github.com/fkie-cad/dewolf/blob/94681ba95d1753c6cbe7e443bb38233e5be972e2/decompiler/frontend/binaryninja/parser.py#L77 with the condition "dest" in instruction.__dir__() and str(instruction.dest) == '<ssa ecx_1 version 26>'

The problem occurs when lifting the RHS of this instruction.

Affected Binary Ninja Version(s)

3.1.3469

jnhols commented 1 year ago

I think I got the same problem:

Traceback (most recent call last):
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompile.py"", line 80, in <module>
main(Decompiler)
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompiler/util/commandline.py"", line 65, in main
task = decompiler.decompile(function_name, options)
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompile.py"", line 54, in decompile
task = self._frontend.create_task(function, task_options)
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompiler/frontend/binaryninja/frontend.py"", line 57, in create_task
cfg = self._extract_cfg(function, options)
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompiler/frontend/binaryninja/frontend.py"", line 83, in _extract_cfg
return parser.parse(function)
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompiler/frontend/binaryninja/parser.py"", line 34, in parse
index_to_BasicBlock[basic_block.index] = BasicBlock(basic_block.index, instructions=list(self._lift_instructions(basic_block)))
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompiler/structures/graphs/basicblock.py"", line 38, in __init__
self._update()
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompiler/structures/graphs/basicblock.py"", line 183, in _update
for dependency in instruction.requirements:
    File ""/home/ubuntu/.binaryninja/plugins/dewolf/decompiler/structures/pseudo/instructions.py"", line 141, in requirements
return self._value.requirements
AttributeError: 'NoneType' object has no attribute 'requirements'

I get this error while decompiling main in one of the samples given below.

constant_pointer_error.zip

Binaryninja version: 3.2.3814

mm4rks commented 1 year ago

/cib

github-actions[bot] commented 1 year ago

Branch issue-127-_Lifter_Lift_MediumLevelILConstPtr_as_None created!

ebehner commented 1 year ago

More and smaller samples where the same problem occurs (always test17): test_condition.zip

mm4rks commented 1 year ago

Blocked by #150

mm4rks commented 1 year ago

test with samples:

7923f949e7422ac02c2dc5148950861f8102c83859f00b7d09857b95f16f7caf b167ee40ae39cfd7cfe3667dc366bd5d46810aa46ff1cdbce004aef5268c482b

NeoQuix commented 1 year ago

With the updated lifter from #150 all binaries will work.

The problematic points will be lifted incorrectly, as the type of the variables are wrong in BNinja (CONST_PTR for what should be a CONST).

Therefore the lifter will lift the wrongly typed local variables as:

extern void * data_1 = ???;
... func(...){
...
var_x = data_1;
...

instead of:

... func(...){
...
var_x = 1;
...

The problem in Bninja only applies to small values (<=10), so maybe the address itself should be checked before lifting. Nevertheless fixed with #150, will do a follow up for incorrect type.