You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Just a sidenote, pickle was unable to dump the ircfg because of the nbsi in cpu.py. _pickle.PicklingError: Can't pickle <class 'miasm.core.cpu.nbsi'>: attribute lookup nbsi on miasm.core.cpu failed
Also, Dill doesn't save the ircfg correctly but still allows me to demonstrate the bug so proceed with caution when performing analysis on the incorrect_ssa.dat
Hi @user1342234
It normal that the 'unssa' can produce multiple write to the same register, even if it's a R14.0.
When you do un ssa algorithm, any register is selected selected to represent the 'representing' register of an equivalent class, and that can be a R14.0.
But if you recall ssa algorithm on such a graph, there may be interferences between the new ssa and the old unssa'ed register.
A way to 'survive' this is to keep the metadata of ssa'ed register (in the ssa class) and pass this to the future ssa pass.
Hi @serpilliere
Thanks for the response and clarification!
I just realized that I can use the ssa.graph as the ircfg and not continuously call ssa_to_unssa. Is this a better way for iteratively reconstructing the CFG of the function? If so, what would be ssa_to_unssa's main purpose?
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.
incorrect_ssa -> https://filebin.net/12aiter0nj97sgbh
The text was updated successfully, but these errors were encountered: