BoomerangDecompiler / boomerang

Boomerang Decompiler - Fighting the code-rot :)
Other
370 stars 59 forks source link

Segfault on NULL `redundant` with a 32-bit Linux executable #261

Open fabzzap opened 4 years ago

fabzzap commented 4 years ago

OS:

Ubuntu 18.10 64 bit Boomerang version or git hash:

509e4cce0

Steps to reproduce:

  1. Download the 32-bit Linux program csw from http://ramsoft.bbk.org.omegahg.com/software/csw130.tgz
  2. Use an old version of UPX, e.g. https://master.dl.sourceforge.net/project/upx/upx/1.20/upx-1.20-linux.tar.gz , to extract the actual executable of csw from the downloaded one, that is UPX-compressed
  3. Run <install path>/bin/boomerang-cli csw

Expected behaviour/output: The program is decompiled

Actual behaviour/output: Segmentation fault. When run under gdb, the stack trace is also printed

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ccbafc in __gnu_cxx::__normal_iterator<IRFragment**, std::vector<IRFragment*, std::allocator<IRFragment*> > >::__normal_iterator (
    this=0x7fffffffd560, __i=<error reading variable>)
    at /usr/include/c++/9/bits/stl_iterator.h:807
807       : _M_current(__i) { }
(gdb) ba
#0  0x00007ffff7ccbafc in __gnu_cxx::__normal_iterator<IRFragment**, std::vector<IRFragment*, std::allocator<IRFragment*> > >::__normal_iterator (
    this=0x7fffffffd560, __i=<error reading variable>)
    at /usr/include/c++/9/bits/stl_iterator.h:807
#1  0x00007ffff7cc83ae in std::vector<IRFragment*, std::allocator<IRFragment*> >::begin (this=0x0) at /usr/include/c++/9/bits/stl_vector.h:809
#2  0x00007ffff7ce77b4 in GraphNode<IRFragment>::removePredecessor (this=0x0, 
    pred=0x55555b87f700)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/db/GraphNode.h:88
#3  0x00007ffff7ce535c in IRFragment::simplify (this=0x55555b87f700)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/db/IRFragment.cpp:582
#4  0x00007ffff7dad9e3 in FragSimplifyPass::execute (this=0x555555596c30, proc=
    0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/passes/early/FragSimplifyPass.cpp:28
#5  0x00007ffff7d993a0 in PassManager::executePass (
    this=0x7ffff7fc9d90 <g_passManager>, pass=0x555555596c30, 
    proc=0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/passes/PassManager.cpp:111
#6  0x00007ffff7d9928e in PassManager::executePass (
    this=0x7ffff7fc9d90 <g_passManager>, passID=PassID::FragSimplify, 
    proc=0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/passes/PassManager.cpp:102
#7  0x00007ffff7db01df in StatementPropagationPass::execute (
    this=0x555555596bc0, proc=0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/passes/early/StatementPropagationPass.cpp:62
#8  0x00007ffff7d993a0 in PassManager::executePass (
    this=0x7ffff7fc9d90 <g_passManager>, pass=0x555555596bc0, 
    proc=0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/passes/PassManager.cpp:111
#9  0x00007ffff7d9928e in PassManager::executePass (
    this=0x7ffff7fc9d90 <g_passManager>, passID=PassID::StatementPropagation, 
    proc=0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/passes/PassManager.cpp:102
#10 0x00007ffff7d70870 in ProcDecompiler::earlyDecompile (this=0x7fffffffdb30, 
    proc=0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/decomp/ProcDecompiler.cpp:273
#11 0x00007ffff7d6f512 in ProcDecompiler::tryDecompileRecursive (
    this=0x7fffffffdb30, proc=0x555555c82960)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/decomp/ProcDecompiler.cpp:80
#12 0x00007ffff7d73243 in ProcDecompiler::decompileCallee (
    this=0x7fffffffdb30, callee=0x555555c82960, proc=0x555555bb6590)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/decomp/ProcDecompiler.cpp:727
#13 0x00007ffff7d6f79f in ProcDecompiler::tryDecompileRecursive (
    this=0x7fffffffdb30, proc=0x555555bb6590)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/decomp/ProcDecompiler.cpp:115
#14 0x00007ffff7d6f153 in ProcDecompiler::decompileRecursive (
    this=0x7fffffffdb30, proc=0x555555bb6590)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/decomp/ProcDecompiler.cpp:35
#15 0x00007ffff7d1a8cb in UserProc::decompileRecursive (this=0x555555bb6590)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/db/proc/UserProc.cpp:129
#16 0x00007ffff7d77ed6 in ProgDecompiler::decompile (this=0x7fffffffdca0)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/decomp/ProgDecompiler.cpp:63
#17 0x00007ffff7ca8dfa in Project::decompileBinaryFile (this=0x55555559ff00)
    at /home/fabrizio/dev/boomerangfork/src/boomerang/core/Project.cpp:222
#18 0x000055555556c136 in CommandlineDriver::decompile (this=0x7fffffffdde0, 
    fname=..., pname=...)
    at /home/fabrizio/dev/boomerangfork/src/boomerang-cli/CommandlineDriver.cpp:558
#19 0x000055555556bcd7 in CommandlineDriver::decompile (this=0x7fffffffdde0)
    at /home/fabrizio/dev/boomerangfork/src/boomerang-cli/CommandlineDriver.cpp:512
#20 0x0000555555570350 in main (argc=2, argv=0x7fffffffdf38)
    at /home/fabrizio/dev/boomerangfork/src/boomerang-cli/Main.cpp:28

Additional comments:

[...]

ceeac commented 4 years ago

Thanks for the report! The bug is triggered because the executable contains a conditional jump to another function. I'll investigate how to best solve this.

fabzzap commented 4 years ago

Interesting, maybe that's a tail call optimisation?

ceeac commented 4 years ago

Yes, kind of; the code is reusing a part of another function:

shared-epilogue

Boomerang does not recognize that the jae instructions are conditional calls and that 0x806a060 is a separate function.