Easy Way To Unpack DotNet Packed Programs
by CodeRipper / SND
Tools used: .NET Generic Unpacker
NETDeProtector 1.0
dotNetSniffer
CFF Explorer
Some defintions:
MSIL = Microsoft Intermediate Language
JIT = Just-In-Time
CPU = Central Processing Unit – or processor
Some intros:
This easy tutorial will teach you how to unpack Xenocode and some old version of .NET Reactor.
Important note: In the case of .NET packers is not necesary to stop at old entry point (OEP) as we used to do under the case of win32 packers!
Why we should stop at OEP in the case of win32 packers?
Under the case of win32 packers (Aspack, UPX ...) we stop at OEP to get a valid dump: if some instructions after OEP are executed some data will have wrong value when the program will start.
Example: A program which has a value intialized whit 1 and we also have some code which will add 3 to that value. If we make our dump after was added 3 to that value our dump will start whit the wrong value 4 and we will have only fatal errors.
Under the case of .NET things are different:
When you compile your code (in the case of a .NET program made under Visual C#, Visual C++, VB .NET ) the compiler translates your source code into Microsoft intermediate language (MSIL), which is a CPU-independent set of instructions that can be efficiently converted to native code. MSIL includes instructions for loading, storing, initializing, and calling methods on objects, as well as instructions for arithmetic and logical operations, control flow, direct memory access, exception handling, and other operations. Before code can be run, MSIL must be converted to CPU-specific code by a just-in-time (JIT) compiler. When a compiler produces MSIL, it also produces metadata. Metadata describes the types in your code, including the definition of each type, the signatures of each type's members, the members that your code references and other data used by runtime at execution time. Metadata will also include the values for intialized variables.
We have two different things: Microsoft Intermediate Language (MSIL) and native instructions (ASM) translated from MSIL at runtime. As you probable already know the CPU will execute only native instructions (ASM).
At runtime MSIL and metadata are loaded under the memory of program; MSIL is translated to native instructions (of course these instructions will be placed under a new memory area), for each variable from program is allocated a new memory area and also each intialized variables will be set whit the corresponding value from metadata.
At runtime runtime MSIL and metadata are not changed so as conclusion theoretical you could dump at any time after the program was started.
If you start a clean .NET program you could dump the program at any time and get a valid dump – of course doing this doesn’t have much sense if the program is not packed/protected.
I. For unpacking files we have some options:
A. Unpacking using .NET Generic Unpacker
We create a new directory named dumps for example. We start the program (the program and after that we start .NET Generic Unpacker, we select our program from list and we save all file to our directory.
B. Unpacking using NET DeProtector v1.0
Some time .NET Generic Unpacker can fail - very rare but it can hapend.
No much feature if we compare him whit .NET Generic Unpacker and also fails a lot of times 
C. Unpacking using dotNetSniffer by PV Logiciels
The cool feature of him is “Dump again at JIT” - always mark that option!
Dumping at JIT means dumping when the MSIL is compiled - then all information from metadata has right value!
Under some versions of .NET Reactor after you dissasemble some methods from dump using ILDASM you will have the error “******** ERROR: Bogus local variable signature (0xACBD0004) ***********”. If you try to dissasemble same methods whit Reflector you will get the error System.InvalidOperationException - InnerException: Index was outside the bounds of the array.
All of these can be avoided if you mark the option “Dump again at JIT” and you use the files from jit directory.
II. Renaming all files to their original name:
For doing this we simply load all files under CFF Explorer and we look at OriginalFilename property; this property will always tell as which is the right name. We simply rename all files to the right name.