Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1

the original flow of LinkedList::Dump—DotFuscator can perform some
fairly aggressive control flow obfuscation, depending on user settings.
First of all, the loop’s condition has been moved up to the beginning of the
loop, and an unconditional jump back to the beginning of the loop has been
added at the end (at IL_001e). This structure in itself is essentially nothing
but a pretested loop, but there are additional elements here that are put in
place to confuse decompilers. If you look at the loop condition itself, it has
been rearranged in an unusual way: If the brtrueinstruction is satisfied, it
skips an unconditional jump instruction and jumps into the loop’s body. If it’s
not, the next instruction down is an unconditional jump that skips the loop’s
body and goes to the end of the method.
Before the loop’s condition there is an unusual sequence at IL_0007that
uses an unconditional branch instruction to simply skip to the next instruction
at IL_0009. IL_0009is the first instruction in the loop and the unconditional
branch instruction at the end of the loop jumps back to this instruction. It looks
like the idea with that unconditional branch at IL_0007is to complicate the
control flow graph and have two unconditional branches point to the same
place, which is likely to throw off the control flow analysis algorithms in some
decompilers.
Let’s run this method through a decompiler and see whether these aggres-
sive control flow obfuscation techniques impact the output from decompilers.
The following code is the output I got from the Spices.Net decompiler for the
routine from Listing 12.7:


public virtual void a()
{
d d = a;
d.a();
d = d.b;
while (d == null)
{
return;
}
}

Spices.Net is completely confused by the unusual control flow constructs of
this routine and generates incorrect code. It fails to properly identify the loop’s
body and actually places the returnstatement inside the loop, even though it
is executed after the loop. The d.a();and d = d.b;statements are placed
before the loop even though they are essentially the loop’s body. Finally, the
loop’s condition is reversed: The loop is supposed to keep running while dis
notnull, not the other way around.
Different decompilers employ different control flow analysis algorithms,
and they generally react differently to these types of control flow obfuscations.


Reversing .NET 449
Free download pdf