Decompilation Anakrino Test

Program-Transformation.Org: The Program Transformation Wiki

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