diff --git a/bin/Debug/output.cs b/bin/Debug/output.cs new file mode 100644 index 000000000..09edc1aad --- /dev/null +++ b/bin/Debug/output.cs @@ -0,0 +1,88 @@ +using System; +namespace Reversi +{ + public class AboutDialog : System.Windows.Forms.Form + { + private System.Windows.Forms.PictureBox iconPictureBox; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.Label titleLabel; + private System.Windows.Forms.Label versionLabel; + private System.Windows.Forms.Label copyrightLabel; + private System.ComponentModel.Container components; + protected virtual void Dispose(bool disposing) + { + if (!(!disposing)) { + if (!(!(IL__ldfld(components, @this)))) { + IL__callvirt(Dispose(), (IL__ldfld(components, @this))); + goto BasicBlock_4; + } + else { + goto BasicBlock_4; + } + } + BasicBlock_4: + @this.Dispose(disposing); + } + private void InitializeComponent() + { + System.Resources.ResourceManager V_0 = (IL__newobj(.ctor(), Type.GetTypeFromHandle((IL__ldtoken(Reversi.AboutDialog))))); + IL__stfld(iconPictureBox, @this, (IL__newobj(.ctor()))); + IL__stfld(titleLabel, @this, (IL__newobj(.ctor()))); + IL__stfld(versionLabel, @this, (IL__newobj(.ctor()))); + IL__stfld(okButton, @this, (IL__newobj(.ctor()))); + IL__stfld(copyrightLabel, @this, (IL__newobj(.ctor()))); + @this.SuspendLayout(); + IL__callvirt(set_Location(), (IL__ldfld(iconPictureBox, @this)), (IL__newobj(.ctor(), 77, 56))); + IL__callvirt(set_Name(), (IL__ldfld(iconPictureBox, @this)), "iconPictureBox"); + IL__callvirt(set_Size(), (IL__ldfld(iconPictureBox, @this)), (IL__newobj(.ctor(), 96, 96))); + IL__callvirt(set_TabIndex(), (IL__ldfld(iconPictureBox, @this)), 0); + IL__callvirt(set_TabStop(), (IL__ldfld(iconPictureBox, @this)), 0); + IL__callvirt(set_AutoSize(), (IL__ldfld(titleLabel, @this)), 1); + IL__callvirt(set_Font(), (IL__ldfld(titleLabel, @this)), (IL__newobj(.ctor(), "Microsoft Sans Serif", 8.25f, 1, 3, 0))); + IL__callvirt(set_Location(), (IL__ldfld(titleLabel, @this)), (IL__newobj(.ctor(), 103, 16))); + IL__callvirt(set_Name(), (IL__ldfld(titleLabel, @this)), "titleLabel"); + IL__callvirt(set_Size(), (IL__ldfld(titleLabel, @this)), (IL__newobj(.ctor(), 44, 16))); + IL__callvirt(set_TabIndex(), (IL__ldfld(titleLabel, @this)), 0); + IL__callvirt(set_Text(), (IL__ldfld(titleLabel, @this)), "Reversi"); + IL__callvirt(set_TextAlign(), (IL__ldfld(titleLabel, @this)), 32); + IL__callvirt(set_AutoSize(), (IL__ldfld(versionLabel, @this)), 1); + IL__callvirt(set_Location(), (IL__ldfld(versionLabel, @this)), (IL__newobj(.ctor(), 95, 32))); + IL__callvirt(set_Name(), (IL__ldfld(versionLabel, @this)), "versionLabel"); + IL__callvirt(set_Size(), (IL__ldfld(versionLabel, @this)), (IL__newobj(.ctor(), 61, 16))); + IL__callvirt(set_TabIndex(), (IL__ldfld(versionLabel, @this)), 1); + IL__callvirt(set_Text(), (IL__ldfld(versionLabel, @this)), "Version 2.0"); + IL__callvirt(set_TextAlign(), (IL__ldfld(versionLabel, @this)), 32); + IL__callvirt(set_DialogResult(), (IL__ldfld(okButton, @this)), 1); + IL__callvirt(set_Location(), (IL__ldfld(okButton, @this)), (IL__newobj(.ctor(), 88, 192))); + IL__callvirt(set_Name(), (IL__ldfld(okButton, @this)), "okButton"); + IL__callvirt(set_TabIndex(), (IL__ldfld(okButton, @this)), 3); + IL__callvirt(set_Text(), (IL__ldfld(okButton, @this)), "OK"); + IL__callvirt(set_AutoSize(), (IL__ldfld(copyrightLabel, @this)), 1); + IL__callvirt(set_Location(), (IL__ldfld(copyrightLabel, @this)), (IL__newobj(.ctor(), 36, 160))); + IL__callvirt(set_Name(), (IL__ldfld(copyrightLabel, @this)), "copyrightLabel"); + IL__callvirt(set_Size(), (IL__ldfld(copyrightLabel, @this)), (IL__newobj(.ctor(), 178, 16))); + IL__callvirt(set_TabIndex(), (IL__ldfld(copyrightLabel, @this)), 2); + IL__callvirt(set_Text(), (IL__ldfld(copyrightLabel, @this)), "Copyright 2003-2005 by Mike Hall."); + IL__callvirt(set_TextAlign(), (IL__ldfld(copyrightLabel, @this)), 32); + @this.set_AcceptButton((IL__ldfld(okButton, @this))); + IL__callvirt(set_AutoScaleBaseSize(), @this, (IL__newobj(.ctor(), 5, 13))); + @this.set_CancelButton((IL__ldfld(okButton, @this))); + @this.set_ClientSize((IL__newobj(.ctor(), 250, 224))); + @this.set_ControlBox(0); + IL__callvirt(Add(), @this.get_Controls(), (IL__ldfld(copyrightLabel, @this))); + IL__callvirt(Add(), @this.get_Controls(), (IL__ldfld(versionLabel, @this))); + IL__callvirt(Add(), @this.get_Controls(), (IL__ldfld(titleLabel, @this))); + IL__callvirt(Add(), @this.get_Controls(), (IL__ldfld(okButton, @this))); + IL__callvirt(Add(), @this.get_Controls(), (IL__ldfld(iconPictureBox, @this))); + @this.set_FormBorderStyle(3); + @this.set_Icon((IL__castclass(System.Drawing.Icon, (IL__callvirt(GetObject(), V_0, "$this.Icon"))))); + @this.set_MaximizeBox(0); + @this.set_MinimizeBox(0); + @this.set_Name("AboutDialog"); + @this.set_ShowInTaskbar(0); + @this.set_StartPosition(4); + IL__callvirt(set_Text(), @this, "About Reversi"); + @this.ResumeLayout(0); + } + } +} diff --git a/src/AstBuilder.cs b/src/AstBuilder.cs index df8178dea..0ea653050 100644 --- a/src/AstBuilder.cs +++ b/src/AstBuilder.cs @@ -47,8 +47,8 @@ namespace Decompiler // code = code.Replace(":\r\n\t", ": "); // code = code.Replace(": }", ":\r\n\t}"); code = code.Replace("\t", " "); - code = code.Replace("\"/*", ""); - code = code.Replace("*/\";", ""); + code = code.Replace("\"/***", ""); + code = code.Replace("***/\";", ""); // Post processing commands while(true) { @@ -111,7 +111,7 @@ namespace Decompiler public void AddType(TypeDefinition typeDef) { - if (Options.TypeFilter != null && !typeDef.Name.EndsWith(Options.TypeFilter)) return; + if (Options.TypeFilter != null && typeDef.Name != Options.TypeFilter) return; TypeDeclaration astType = CreateType(typeDef); NamespaceDeclaration astNS = GetCodeNamespace(typeDef.Namespace); diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs index 7ba2178f1..0b8c97ca7 100644 --- a/src/AstMetodBodyBuilder.cs +++ b/src/AstMetodBodyBuilder.cs @@ -119,7 +119,10 @@ namespace Decompiler lastStatement = TransformExpression(expr); yield return lastStatement; } - Ast.IfElseStatement ifElseStmt = (Ast.IfElseStatement)lastStatement; + Ast.IfElseStatement ifElseStmt = lastStatement as Ast.IfElseStatement; + if (ifElseStmt == null) { + ifElseStmt = new IfElseStatement(Ast.Expression.Null, Ast.Statement.Null, Ast.Statement.Null); + } Ast.Statement oldTrueBody = ifElseStmt.TrueStatement[0]; ifElseStmt.TrueStatement.Clear(); // Swap the method bodies @@ -152,35 +155,31 @@ namespace Decompiler Ast.Statement TransformExpression(StackExpression expr) { Ast.Statement astStatement = null; - try { - List args = new List(); - foreach(CilStackSlot stackSlot in expr.StackBefore.PeekCount(expr.PopCount)) { - string name = string.Format("expr{0:X2}", stackSlot.AllocadedBy.Offset); - args.Add(new Ast.IdentifierExpression(name)); - } - object codeExpr = MakeCodeDomExpression(methodDef, expr, args.ToArray()); - if (codeExpr is Ast.Expression) { - if (expr.PushCount == 1) { - string type = expr.LastByteCode.Type.FullName; - string name = string.Format("expr{0:X2}", expr.LastByteCode.Offset); - Ast.LocalVariableDeclaration astLocal = new Ast.LocalVariableDeclaration(new Ast.TypeReference(type.ToString())); - astLocal.Variables.Add(new Ast.VariableDeclaration(name, (Ast.Expression)codeExpr)); - astStatement = astLocal; - } else { - astStatement = new ExpressionStatement((Ast.Expression)codeExpr); - } - } else if (codeExpr is Ast.Statement) { - astStatement = (Ast.Statement)codeExpr; + List args = new List(); + foreach(CilStackSlot stackSlot in expr.StackBefore.PeekCount(expr.PopCount)) { + string name = string.Format("expr{0:X2}", stackSlot.AllocadedBy.Offset); + args.Add(new Ast.IdentifierExpression(name)); + } + object codeExpr = MakeCodeDomExpression(methodDef, expr, args.ToArray()); + if (codeExpr is Ast.Expression) { + if (expr.PushCount == 1) { + string type = expr.LastByteCode.Type.FullName; + string name = string.Format("expr{0:X2}", expr.LastByteCode.Offset); + Ast.LocalVariableDeclaration astLocal = new Ast.LocalVariableDeclaration(new Ast.TypeReference(type.ToString())); + astLocal.Variables.Add(new Ast.VariableDeclaration(name, (Ast.Expression)codeExpr)); + astStatement = astLocal; + } else { + astStatement = new ExpressionStatement((Ast.Expression)codeExpr); } - } catch (NotImplementedException) { - astStatement = MakeComment(expr.LastByteCode.Description); + } else if (codeExpr is Ast.Statement) { + astStatement = (Ast.Statement)codeExpr; } return astStatement; } static Ast.ExpressionStatement MakeComment(string text) { - text = "/*" + text + "*/"; + text = "/***" + text + "***/"; return new Ast.ExpressionStatement(new PrimitiveExpression(text, text)); } @@ -215,7 +214,14 @@ namespace Decompiler allArgs.Add(astExpr); } } - return MakeCodeDomExpression(methodDef, expr.LastByteCode, allArgs.ToArray()); + try { + return MakeCodeDomExpression(methodDef, expr.LastByteCode, allArgs.ToArray()); + } catch (NotImplementedException) { + if (expr.LastByteCode.Operand != null) { + allArgs.Insert(0, new IdentifierExpression(expr.LastByteCode.FormatedOperand)); + } + return new Ast.InvocationExpression(new IdentifierExpression("IL__" + expr.LastByteCode.OpCode.Name), allArgs); + } } static object MakeCodeDomExpression(MethodDefinition methodDef, ByteCode byteCode, params Ast.Expression[] args) diff --git a/src/ByteCode.Type.cs b/src/ByteCode.Type.cs index f27adbb6b..a48602aba 100644 --- a/src/ByteCode.Type.cs +++ b/src/ByteCode.Type.cs @@ -110,7 +110,7 @@ namespace Decompiler case Code.Stelem_R4: case Code.Stelem_R8: case Code.Stelem_Ref: - case Code.Stelem_Any: return null; + case Code.Stelem_Any: return TypeVoid; #endregion #region Branching case Code.Br: @@ -125,7 +125,7 @@ namespace Decompiler case Code.Ble_Un: case Code.Blt: case Code.Blt_Un: - case Code.Bne_Un: return null; + case Code.Bne_Un: return TypeVoid; #endregion #region Comparison case Code.Ceq: @@ -211,7 +211,10 @@ namespace Decompiler case Code.Initobj: throw new NotImplementedException(); case Code.Isinst: throw new NotImplementedException(); case Code.Jmp: throw new NotImplementedException(); - case Code.Ldarg: return ((ParameterDefinition)operand).ParameterType; + case Code.Ldarg: + Cecil.TypeReference typeRef = ((ParameterDefinition)operand).ParameterType; + // 'this' returns null; TODO: Return proper type of this + return typeRef ?? TypeObject; case Code.Ldarga: throw new NotImplementedException(); case Code.Ldc_I4: return TypeInt32; case Code.Ldc_I8: throw new NotImplementedException(); @@ -234,18 +237,18 @@ namespace Decompiler case Code.Mkrefany: throw new NotImplementedException(); case Code.Newobj: throw new NotImplementedException(); case Code.No: throw new NotImplementedException(); - case Code.Nop: return null; + case Code.Nop: return TypeVoid; case Code.Or: throw new NotImplementedException(); case Code.Pop: throw new NotImplementedException(); case Code.Readonly: throw new NotImplementedException(); case Code.Refanytype: throw new NotImplementedException(); case Code.Refanyval: throw new NotImplementedException(); - case Code.Ret: return null; + case Code.Ret: return TypeVoid; case Code.Rethrow: throw new NotImplementedException(); case Code.Sizeof: throw new NotImplementedException(); case Code.Starg: throw new NotImplementedException(); case Code.Stfld: throw new NotImplementedException(); - case Code.Stloc: return null; + case Code.Stloc: return TypeVoid; case Code.Stobj: throw new NotImplementedException(); case Code.Stsfld: throw new NotImplementedException(); case Code.Switch: throw new NotImplementedException(); diff --git a/src/ByteCode.cs b/src/ByteCode.cs index 77ac28e89..0c4504ca5 100644 --- a/src/ByteCode.cs +++ b/src/ByteCode.cs @@ -69,6 +69,11 @@ namespace Decompiler this.operand = inst.Operand; } + public override string ToString() + { + return this.OpCode + " " + FormatByteCodeOperand(this.Operand); + } + public string Description { get { return string.Format( @@ -83,7 +88,13 @@ namespace Decompiler } } - static object FormatByteCodeOperand(object operand) + public string FormatedOperand { + get { + return FormatByteCodeOperand(this.Operand); + } + } + + static string FormatByteCodeOperand(object operand) { if (operand == null) { return string.Empty; @@ -97,12 +108,14 @@ namespace Decompiler return ((VariableDefinition)operand).Name; } else if (operand is ParameterDefinition) { return ((ParameterDefinition)operand).Name; + } else if (operand is FieldReference) { + return ((FieldReference)operand).Name; } else if (operand is string) { return "\"" + operand + "\""; } else if (operand is int) { return operand.ToString(); } else { - return "(" + operand.GetType() + ")"; + return operand.ToString(); } } } diff --git a/src/CilStack.cs b/src/CilStack.cs index f4d066e97..6f4cc87e0 100644 --- a/src/CilStack.cs +++ b/src/CilStack.cs @@ -25,6 +25,9 @@ namespace Decompiler public CilStackSlot(ByteCode allocadedBy, Cecil.TypeReference type) { + if (allocadedBy == null) throw new ArgumentNullException(); + if (type == null) throw new ArgumentNullException(); + this.allocadedBy = allocadedBy; this.type = type; } diff --git a/src/MainForm.cs b/src/MainForm.cs index ff0e6f991..ec631e601 100644 --- a/src/MainForm.cs +++ b/src/MainForm.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Collections.Generic; using System.Drawing; using System.Reflection; @@ -38,8 +39,8 @@ namespace Decompiler x += checkBox.Width + 10; } } - collapseCount.Value = 0; - reduceCount.Value = 0; + collapseCount.Value = 10000; + reduceCount.Value = 10000; filter.Text = "AboutDialog"; } @@ -64,6 +65,8 @@ namespace Decompiler AstBuilder codeDomBuilder = new AstBuilder(); codeDomBuilder.AddAssembly(assembly); SourceCode = codeDomBuilder.GenerateCode(); + + File.WriteAllText("output.cs", SourceCode); } void CollapseBtnClick(object sender, EventArgs e) diff --git a/src/StackExpression.cs b/src/StackExpression.cs index 2e11a4d86..65797d83b 100644 --- a/src/StackExpression.cs +++ b/src/StackExpression.cs @@ -138,6 +138,11 @@ namespace Decompiler this.lastByteCode.Expression = this; } + public override string ToString() + { + return this.LastByteCode.ToString(); + } + public bool MustBeParenthesized { get { switch(this.LastByteCode.OpCode.Code) {