Converting from SSA to UnSSA gives redefinitions of SSA variables
Hello! A little background: I am currently using Miasm for deobfuscation of virtualized functions. These functions have many **CMOV**'s and **Loop based constant obfuscation**. In my example below, I've been iteratively reconstructing the control flow graph one block at a time (not using dis_multiblock) and applying do_simplify_loop on the ircfg. As you know, do_simplify_loop eventually calls ssa_to_unssa which produces a new ircfg after optimizations. For some reason, the new UnSSA'd graph (ircfg) now has R14.0 defined twice! (Note: the variable defined twice will change sometimes)
In this SSA graph. At the first block R14.2=R14 and at the last block, R14.1=(RDI.5 & 0x1) | (R14.0 ^ R8) . Here, everything is correct.

After the UnSSA pass, we have our ircfg:
In the first block, R14.0=R14
But in the last block, R14.0=(RDI.4 & 0x1) | (R14.0 ^ R8.2)
**So it's defined twice!**

Since they're defined twice, it causes an assert in [outofssa.py](https://github.com/cea-sec/miasm/blob/2a15c60712b326b541d42ac48f372f97023547e7/miasm/analysis/outofssa.py#L178)
Here is my code for producing this issue along with the ssa file (incorrect_ssa.dat) that, when put through ssa_to_unssa, produces the incorrect redefinitions of SSA variables.
```python
from miasm.analysis.simplifier import IRCFGSimplifierSSA
from miasm.core.locationdb import LocationDB
from miasm.analysis.machine import Machine
import dill
from graphviz import Source
if __name__ == '__main__':
machine = Machine('x86_64')
loc_db = LocationDB()
lifter = machine.lifter_model_call(loc_db)
simplifier = IRCFGSimplifierSSA(lifter)
fl = open("incorrect_ssa.dat", "rb")
ssa = dill.load(fl)
loc_key_0 = list(ssa.graph.blocks.keys())[0]
ircfg = simplifier.ssa_to_unssa(ssa, loc_key_0)
print("Done")
```
incorrect_ssa -> https://filebin.net/12aiter0nj97sgbh
3 条评论