-
Notifications
You must be signed in to change notification settings - Fork 483
Description
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
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.
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