Anakrino .NET to C# Decompiler Tests
Anakrino is a .NET to C# decompiler,
released under a BSD-like license. These tests refer to "Interim #9" (Anakrino9.zip).
Anakrino 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.
The distributed binaries require Windows XP (or perhaps another Windows based .NET JIT).
It would not run under Mono version 0.20 (current in early March 2003).
Fibo
For source, see
DecompilerFiboDotNetSource. Decompiled source from Anakrino:
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 local0;
int local1;
Exception local2;
int local3;
local1 = 0;
try {
local1 = Convert.ToInt32(args[0]);
}
catch (Exception local2) {
Console.WriteLine("Input error");
local3 = 1;
<{ class ILEngineer::Ops::MSIL::Leave }>
}
local0 = Fibo.fib(local1);
Console.WriteLine("fibonacci({0}) = {1}", local1, local0);
return 0;
return local3;
}
}
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) {
Console.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() {
Console.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) {
Console.WriteLine(local1.GetType());
Console.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) {
Console.WriteLine("\nUSAGE: ImageViewer.exe <filename>\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 = ImageViewer.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