As presented here, this function is pretty much impossible to decipher—it’s
very difficult to differentiate between the different symbols. Still, it clearly
shouldn’t be very difficult for a decompiler to overcome this problem—it
would simply have to identify such symbol names and arbitrarily rename
them to make the code more readable. The following sample demonstrates this
solution on the same DotFuscated assembly that contains the unprintable
names; it was produced by the Spices.Net decompiler, which appears to do
this automatically.
public virtual void \u1700(\u1703 A_0)
{
A_0.\u1701 = \u1700;
if (\u1700 != null)
{
\u1700.\u1700 = A_0;
}
\u1700 = A_0;
}
With Spices.Net automatically renaming those unreadable symbols, this
method becomes more readable. This is true for many of the other, less aggres-
sive renaming schemes as well. A decompiler can always just rename every
symbol during the decompilation stage to make the code as readable as possi-
ble. For example, the repeated use of a, b, and c, as discussed earlier, could be
replaced with unique names. The conclusion is that many of the transforma-
tions performed by obfuscators can be partially undone with the right auto-
mated tools. This is the biggest vulnerability of these tools: As long as it is
possible to partially or fully undo the effects of their transformations, they
become worthless. The challenge for developers of obfuscators is to create irre-
versible transformations.
Remotesoft Obfuscator and Linker
The Remotesoft Obfuscator (Remotesoft, http://www.remotesoft.com)) product is
based on concepts similar to the other obfuscators I’ve discussed, with the dif-
ference that it also includes a Linker component, which can add another layer
of security to obfuscated assemblies. The linker can join several assemblies
into a single file. This feature is useful in several different cases, but it is inter-
esting from the reverse-engineering perspective because it can provide an
additional layer of protection against reverse engineering.
As I have demonstrated more than once throughout this book, in situations
where very little information is available about a code snippet being analyzed,
system calls can provide much needed information. In my Defender sample
from Chapter 11, I demonstrated a special obfuscated operating system inter-
face for native programs that made it very difficult to identify system calls,
Reversing .NET 451