fkie-cad / dewolf

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

Headless decompilation of a complete binary fails #111

Closed mari-mari closed 1 year ago

mari-mari commented 2 years ago

What happened?

When decompiling a complete binary from the command line, we output decompiled code for each of the functions in that binary.

In case decompilation of even a single function fails, dewolf crashes completely. Does not happen when decompiling each function separately (passing function name).

What we actually want is decompiler output for all successfully decompiled functions. Error message should be printed in case dewolf fails to decompile that function.

For instance, something like this should be great:

python decompile.py gradebook
long sub_1030() {}

unsigned long lookup(char * arg1) {
   ....
}

long add_student() {
    ....
}

long close_gradebook() {
...
}

Failed to decompile UPDATE_GRADE function

int lookup() {
...
}

int main() {
...
}

How to reproduce?

Decompilation of a complete binary fails:

python decompile.py test.exe         
[lifter.py:34 lift_unknown()] WARNING - Can not lift LSTATUS __stdcall (HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult) (<class 'binaryninja.types.FunctionType'>
[lifter.py:34 lift_unknown()] WARNING - Can not lift LSTATUS __stdcall (HKEY hKey, LPCWSTR lpSubKey, LPCWSTR
 ...
Traceback (most recent call last):
  File "decompile.py", line 80, in <module>
    main(Decompiler)
  File "/home/mry/.binaryninja/plugins/dewolf/decompiler/util/commandline.py", line 59, in main
    undecorated_code = decompiler.decompile_all(options)
  File "decompile.py", line 69, in decompile_all
    task = self._frontend.create_task(function, task_options)
  File "/home/mry/.binaryninja/plugins/dewolf/decompiler/frontend/binaryninja/frontend.py", line 57, in create_task
    cfg = self._extract_cfg(function, options)
  File "/home/mry/.binaryninja/plugins/dewolf/decompiler/frontend/binaryninja/frontend.py", line 83, in _extract_cfg
    return parser.parse(function)
  File "/home/mry/.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/mry/.binaryninja/plugins/dewolf/decompiler/structures/graphs/basicblock.py", line 38, in __init__
    self._update()
  File "/home/mry/.binaryninja/plugins/dewolf/decompiler/structures/graphs/basicblock.py", line 183, in _update
    for dependency in instruction.requirements:
  File "/home/mry/.binaryninja/plugins/dewolf/decompiler/structures/pseudo/instructions.py", line 141, in requirements
    return self._value.requirements
AttributeError: 'NoneType' object has no attribute 'requirements'

Decompilation of a single function from that binary succeeds:

 python decompile.py test.exe 0x401865
[lifter.py:34 lift_unknown()] WARNING - Can not lift HMODULE __stdcall (LPCWSTR lpModuleName) (<class 'binaryninja.types.FunctionType'>
[dead_path_elimination.py:73 _get_invalid_branch_edge()] WARNING - [DeadPathElimination] Could not convert operation *(((char *) eax#1) + 0x0) into z3 logic.
...
extern HMODULE __stdcall (LPCWSTR lpModuleName) * GetModuleHandleW_1 = NULL;

HMODULE sub_401865() {
    HMODULE var_0;
    struct HINSTANCE__ * var_1;
...
}

[test.exe.zip](https://github.com/fkie-cad/dewolf/files/9380913/test.exe.zip)

Affected Binary Ninja Version(s)

3.0.3233

0x6e62 commented 2 years ago
  File "/home/mry/.binaryninja/plugins/dewolf/decompiler/structures/pseudo/instructions.py", line 141, in requirements
    return self._value.requirements
AttributeError: 'NoneType' object has no attribute 'requirements'

seems like a lifter issue. Let me know if you can pinpoint the function in question.

mari-mari commented 2 years ago

Solving that particular crash is another issue by itself. The subject of the current one is to prevent the complete binary decompilation crash due to crash when decompiling single function.

mari-mari commented 2 years ago

Still reproducible for the latest version, 3.1.3469.

mari-mari commented 2 years ago

/cib

github-actions[bot] commented 2 years ago

Branch issue-111-Headless_decompilation_of_a_complete_binary_fails created!