shellphish/driller

UnsupportedIROpError: floating point support disabled

92wyunchao opened this issue · 5 comments

When I run driller to test one of cgc binary named NRFIN_00017 with the command "shellphuzz -c 2 -d 2 -C NRFIN_00017 ", I get the following error, could you tell me what is wrong here? Thank you.
Traceback (most recent call last):
File "/home/administrator/clark/driller/angr-dev/angr/angr/engines/vex/irop.py", line 926, in translate_inner
raise UnsupportedIROpError("floating point support disabled")
UnsupportedIROpError: floating point support disabled

Floating point support in angr has been disabled in the CGC analyses for a tight-knit nebula of reasons:

  • libvex's representation of floating point numbers is imprecise - it converts the 80-bit extended precision format used by the x87 for computation to 64-bit doubles, making it impossible to get precise results
  • There is very limited implementation support in angr for the actual primitive operations themselves as reported by libvex, so you will often get a less friendly "unsupported operation" error if you go too much further
  • For what operations are implemented, the basic optimizations that allow tractability during symbolic computation (AST deduplication, operation collapsing) are not implemented for floating point ops, leading to gigantic ASTs
  • there are memory corruption bugs in z3 that get triggered frighteningly easily when you're using huge workloads of mixed floating point and bitvector ops. We haven't been able to get a testcase that doesn't involve "just run angr" for the z3 guys to investigate.

HOWEVER, this is supposed to be mitigated by a technique called the https://github.com/angr/angr/blob/master/angr/exploration_techniques/oppologist.py that is supposed to catch these issues, concretize their inputs, and run the problematic instructions through qemu via uniciorn engine, allowing execution to continue. The intuition is that the specific values of floating point operations don't typically affect the exploitation process.

I'm unable to reproduce your issue, but I don't know if I have driller set up correctly. If you're seeing this issue and it's terminating the analysis, it's probably because you don't have unicorn installed or configured correctly. If you're seeing this issue just in a log somewhere, it's just the oppologist kicking in and you have nothing to worry about.

I appreciate it. Here is another problem when I try to run a linux binary with the same command, then it is stuck there.
ERROR | 2018-01-04 14:37:50,127 | angr.exploration_techniques.oppologist | Original block hit an error.
Traceback (most recent call last):
File "/home/administrator/clark/driller/angr-dev/angr/angr/exploration_techniques/oppologist.py", line 83, in step_state
ss = self.project.factory.successors(state, throw=True, **kwargs)
File "/home/administrator/clark/driller/angr-dev/angr/angr/factory.py", line 77, in successors
r = engine.process(state, inline=inline,**kwargs)
File "/home/administrator/clark/driller/angr-dev/angr/angr/engines/vex/engine.py", line 101, in process
opt_level=opt_level)
File "/home/administrator/clark/driller/angr-dev/angr/angr/engines/engine.py", line 54, in process
self._process(new_state, successors, *args, **kwargs)
File "/home/administrator/clark/driller/angr-dev/angr/angr/engines/vex/engine.py", line 125, in _process
opt_level=opt_level)
File "/home/administrator/clark/driller/angr-dev/angr/angr/engines/vex/engine.py", line 461, in lift
raise SimEngineError("No bytes in memory for block starting at %#x." % addr)
SimEngineError: No bytes in memory for block starting at 0x0.

That just means one of the states jumped to 0. I don't know whether this is a bug in driller or a bug in your target binary that's been found. I also don't know enough about driller (yes you are getting support for driller from someone who doesn't understand driller because nobody else cares enough) to tell you why driller might hang after a bug about that.

If you can give me more information or a testcase to reproduce it I'll look into it.

@rhelmot I upload the binary as an attachment for your reproduce to check whether you have the same problem. Thank you anyway.
88_pwn08.zip

The problem is that there's different auxiliary vectors between angr's simulation and the execution environment. In the part of __libc_start_main that parses auxv, angr and qemu diverge, of course, but our concolic tracer is designed to force execution to continue down the unsatisfiable path. This, of course, leads to disaster. The parser function loads the first auxv value, checks if it's not zero, and tries to exit, but continues down the path anyway as if the value it compared against was not zero. Then, it does this:

image

The qemu emulation clearly went down the path going through the jump, so that's where driller is going to drag the simulated state. However, by the time we get to a jump, edx is going to be negative, and we're going to be loading from an address that contains... zero apparently. So the best thing driller can do is just try to execute this one successor state and hope to god that everything works out in the end. It does not, and you get the error above.

This is but a drop in the bucket of horrifying, monstrous things that will happen when you try to run driller on linux binaries, especially if they're statically linked. Probably the best fix is to have a huge symbolic auxv, but for arguments that are pointers... lol