Reflector .NET to C# Decompiler Tests
Reflector is a .NET browser with an integrated C# decompiler. It will also display the code "translated" into Visual Basic or Delphi, or disassembled as IL. Reflector does not save an entire file of code to write to a source file; I had to add the text in bold to the given output.
Fibo
For source, see
DecompilerFiboDotNetSource. Decompiled source from Reflector:
using System;
class Fibo {
private static int fib(int x)
{
if (x > 1)
{
return (Fibo.fib((x - 1)) + Fibo.fib((x - 2)));
}
return x;
}
public static int Main(string[] args)
{
int num2 = 0;
try
{
num2 = Convert.ToInt32(args[0]);
}
catch (Exception)
{
Console.WriteLine("Input error");
return 1;
}
int num1 = Fibo.fib(num2);
Console.WriteLine("fibonacci({0}) = {1}", num2, num1);
return 0;
}
}
!!!!!!!!!!!!!!!!!! NOTE: NOT COMPLETED FROM HERE DOWN! !!!!!!!!!!!!!!!!!!!!!!
There are several errors in this output. Most obviously, there is the Leave code which should be return local3. The return local3; at the end should be removed. Finally, local2 is declared twice. When all these changes are made, the result compiles and runs correctly.
Casting
For source, see
DecompilerCastingDotNetSource. Here is the output from Anakrino:
using System;
class Casting {
public static void Main(string[] args) {
char local0;
char local1;
local0 = '';
while (local0 < 128) {
WriteLine?("ascii {0} character {1}", local0, local0);
local1 = local0 + 1;
local0 = local1;
}
}
}
The main cast is missing in the
WriteLine? statement. The character constant for character 0 is '\0' , not '' as given. The line local1 = local0 + 1; needs to be replaced with local1 = (char) (((int)local0)+1);. When all these changes are made, the program compiles and is correct.
Inner Classes
For source, see
DecompilerInnerClassesDotNetSource. When decompiled with Anakrino, the result appears correct, but tedious to piece together from the individual functions (and constructors). The print_names function decompiles as follows:
public void print_names() {
WriteLine?(this.name);
}
The this. is not needed.
Sable Test Program
For source, see
DecompilerSableDotNetSource. The decompiler exited with a runtime fault when this program was loaded.
Simple Control Flow
For source, see
DecompilerControlFlowDotNetSource. The decompiler exited with a runtime fault when this program was loaded.
Image Viewer
For source, see
DecompilerImageViewerDotNetSource. This program was compiled with a Microsoft compiler, and so should be easy to decompile. Unfortunately, it had problems with the same method that caused problems for Salamander:
private static Pixbuf
GetPixbufFromFile?(string filename) {
Pixbuf local0;
GException local1;
Pixbuf local2;
try {
local0 = new Pixbuf(filename);
local2 = local0;
<{ class ILEngineer::Ops::MSIL::Leave }>;
}
catch (GException local1) {
WriteLine?(local1.GetType());
WriteLine?("Cannot Open file.");
Environment.Exit(1);
local2 = null;
<{ class ILEngineer::Ops::MSIL::Leave }>;
}
return local2;
}
Also, local1 is declared twice.
For completeness, here is the main function.
public static void Main(string[] args) {
string local0;
ScrolledWindow? local1;
VBox local2;
VBox local3;
MenuBar? local4;
Menu local5;
MenuItem? local6;
MenuItem? local7;
MenuItem? local8;
Toolbar local9;
Pixbuf local10;
if (args.Length > 0 == 0) {
WriteLine?("\nUSAGE:
ImageViewer?.exe
\n");
return;
}
local0 = args[0];
Application.Init();
ImageViewer?.window = new Window("File Viewer");
ImageViewer?.window.SetDefaultSize(200, 200);
ImageViewer?.window.add_DeleteEvent(new EventHandler?(null,
ImageViewer?.Window_Delete));
local1 = new ScrolledWindow?(new Adjustment(IntPtr?.Zero),
new Adjustment(IntPtr?.Zero));
local2 = new VBox(0, 2);
local3 = new VBox(0, 0);
local4 = new MenuBar?();
local5 = new Menu();
local6 = new ImageMenuItem?("gtk-close", new AccelGroup?(IntPtr?.Zero));
local7 = new ImageMenuItem?("gtk-open", new AccelGroup?(IntPtr?.Zero));
local6.add_Activated(new EventHandler?(null, ImageViewer?.Window_Delete));
local7.add_Activated(new EventHandler?(null, ImageViewer?.Window_Open));
local5.Append(local7);
local5.Append(new SeparatorMenuItem?());
local5.Append(local6);
local8 = new MenuItem?("_File");
local8.Submenu = local5;
local4.Append(local8);
local3.PackStart(local4, false, false, 0);
local9 = new Toolbar();
local9.InsertStock("gtk-open", "Open", String.Empty,
new SignalFunc?(null, ImageViewer?.Window_Open), IntPtr?.Zero, 0);
local9.InsertStock("gtk-close", "Close", String.Empty,
new SignalFunc?(null, ImageViewer?.Window_Delete), IntPtr?.Zero, 1);
local3.PackStart(local9, false, false, 0);
local2.PackStart(local3, false, false, 0);
local10 = GetPixbufFromFile?(local0);
ImageViewer?.image = new Image(local10);
ImageViewer?.Refresh(local0, local10);
local1.AddWithViewport(ImageViewer?.image);
local2.PackStart(local1, true, true, 0);
local1.SetPolicy(1, 1);
ImageViewer?.window.Add(local2);
ImageViewer?.window.ShowAll();
Application.Run();
}
The translation "if (args.Length > 0 == 0)" seems clumsy and confusing.
Conclusion
As of early March 2003, Anakrino is not a mature decompiler. It may be useful for examining snippets of code here and there, or even for decompiling small assemblies if you have a fair bit of time spare.
-- MikeVanEmmerik - 07 Mar 2003
CategoryDecompilation