|
|
|
@ -31,6 +31,14 @@ namespace Decompiler
@@ -31,6 +31,14 @@ namespace Decompiler
|
|
|
|
|
|
|
|
|
|
Ast.Statement astStatement = null; |
|
|
|
|
try { |
|
|
|
|
object type = null; |
|
|
|
|
try { |
|
|
|
|
type = GetType(methodDef, instr); |
|
|
|
|
if (type is Cecil.TypeReference) { |
|
|
|
|
type = ((Cecil.TypeReference)type).FullName; |
|
|
|
|
} |
|
|
|
|
} catch (NotImplementedException) { |
|
|
|
|
} |
|
|
|
|
object codeExpr = MakeCodeDomExpression( |
|
|
|
|
methodDef, |
|
|
|
|
instr, |
|
|
|
@ -39,13 +47,14 @@ namespace Decompiler
@@ -39,13 +47,14 @@ namespace Decompiler
|
|
|
|
|
new Ast.IdentifierExpression("arg3")); |
|
|
|
|
if (codeExpr is Ast.Expression) { |
|
|
|
|
if (GetNumberOfOutputs(methodDef, instr) == 1) { |
|
|
|
|
codeExpr = new Ast.AssignmentExpression( |
|
|
|
|
new Ast.IdentifierExpression(string.Format("expr{0:X2}", instr.Offset)), |
|
|
|
|
AssignmentOperatorType.Assign, |
|
|
|
|
(Ast.Expression)codeExpr |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
type = type ?? "object"; |
|
|
|
|
string name = string.Format("expr{0:X2}", instr.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; |
|
|
|
|
} |
|
|
|
@ -333,5 +342,216 @@ namespace Decompiler
@@ -333,5 +342,216 @@ namespace Decompiler
|
|
|
|
|
default: throw new Exception("Unknown OpCode: " + opCode); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static object GetType(MethodDefinition methodDef, Instruction inst, params Cecil.TypeReference[] args) |
|
|
|
|
{ |
|
|
|
|
OpCode opCode = inst.OpCode; |
|
|
|
|
object operand = inst.Operand; |
|
|
|
|
Ast.TypeReference operandAsTypeRef = operand is Cecil.TypeReference ? new Ast.TypeReference(((Cecil.TypeReference)operand).FullName) : null; |
|
|
|
|
Instruction operandAsInstruction = operand is Instruction ? (Instruction)operand : null; |
|
|
|
|
string operandAsInstructionLabel = operand is Instruction ? String.Format("IL_{0:X2}", ((Instruction)operand).Offset) : null; |
|
|
|
|
Cecil.TypeReference arg1 = args.Length >= 1 ? args[0] : null; |
|
|
|
|
Cecil.TypeReference arg2 = args.Length >= 2 ? args[1] : null; |
|
|
|
|
Cecil.TypeReference arg3 = args.Length >= 3 ? args[2] : null; |
|
|
|
|
|
|
|
|
|
switch(opCode.Code) { |
|
|
|
|
#region Arithmetic
|
|
|
|
|
case Code.Add: |
|
|
|
|
case Code.Add_Ovf: |
|
|
|
|
case Code.Add_Ovf_Un: |
|
|
|
|
case Code.Div: |
|
|
|
|
case Code.Div_Un: |
|
|
|
|
case Code.Mul: |
|
|
|
|
case Code.Mul_Ovf: |
|
|
|
|
case Code.Mul_Ovf_Un: |
|
|
|
|
case Code.Rem: |
|
|
|
|
case Code.Rem_Un: |
|
|
|
|
case Code.Sub: |
|
|
|
|
case Code.Sub_Ovf: |
|
|
|
|
case Code.Sub_Ovf_Un: |
|
|
|
|
case Code.And: |
|
|
|
|
case Code.Xor: |
|
|
|
|
case Code.Shl: |
|
|
|
|
case Code.Shr: |
|
|
|
|
case Code.Shr_Un: return Cecil.Constants.Int32; |
|
|
|
|
|
|
|
|
|
case Code.Neg: return Cecil.Constants.Int32; |
|
|
|
|
case Code.Not: return Cecil.Constants.Boolean; |
|
|
|
|
#endregion
|
|
|
|
|
#region Arrays
|
|
|
|
|
case Code.Newarr: throw new NotImplementedException(); |
|
|
|
|
|
|
|
|
|
case Code.Ldlen: return Cecil.Constants.Int32; |
|
|
|
|
|
|
|
|
|
case Code.Ldelem_I: |
|
|
|
|
case Code.Ldelem_I1: |
|
|
|
|
case Code.Ldelem_I2: |
|
|
|
|
case Code.Ldelem_I4: |
|
|
|
|
case Code.Ldelem_I8: return Cecil.Constants.Int32; |
|
|
|
|
case Code.Ldelem_U1: |
|
|
|
|
case Code.Ldelem_U2: |
|
|
|
|
case Code.Ldelem_U4: |
|
|
|
|
case Code.Ldelem_R4: |
|
|
|
|
case Code.Ldelem_R8: |
|
|
|
|
case Code.Ldelem_Ref: |
|
|
|
|
case Code.Ldelem_Any: |
|
|
|
|
case Code.Ldelema: throw new NotImplementedException(); |
|
|
|
|
|
|
|
|
|
case Code.Stelem_I: |
|
|
|
|
case Code.Stelem_I1: |
|
|
|
|
case Code.Stelem_I2: |
|
|
|
|
case Code.Stelem_I4: |
|
|
|
|
case Code.Stelem_I8: |
|
|
|
|
case Code.Stelem_R4: |
|
|
|
|
case Code.Stelem_R8: |
|
|
|
|
case Code.Stelem_Ref: |
|
|
|
|
case Code.Stelem_Any: return null; |
|
|
|
|
#endregion
|
|
|
|
|
#region Branching
|
|
|
|
|
case Code.Br: |
|
|
|
|
case Code.Brfalse: |
|
|
|
|
case Code.Brtrue: |
|
|
|
|
case Code.Beq: |
|
|
|
|
case Code.Bge: |
|
|
|
|
case Code.Bge_Un: |
|
|
|
|
case Code.Bgt: |
|
|
|
|
case Code.Bgt_Un: |
|
|
|
|
case Code.Ble: |
|
|
|
|
case Code.Ble_Un: |
|
|
|
|
case Code.Blt: |
|
|
|
|
case Code.Blt_Un: |
|
|
|
|
case Code.Bne_Un: return null; |
|
|
|
|
#endregion
|
|
|
|
|
#region Comparison
|
|
|
|
|
case Code.Ceq: |
|
|
|
|
case Code.Cgt: |
|
|
|
|
case Code.Cgt_Un: |
|
|
|
|
case Code.Clt: |
|
|
|
|
case Code.Clt_Un: return Cecil.Constants.Boolean; |
|
|
|
|
#endregion
|
|
|
|
|
#region Conversions
|
|
|
|
|
case Code.Conv_I: |
|
|
|
|
case Code.Conv_I1: |
|
|
|
|
case Code.Conv_I2: |
|
|
|
|
case Code.Conv_I4: |
|
|
|
|
case Code.Conv_I8: |
|
|
|
|
case Code.Conv_U: |
|
|
|
|
case Code.Conv_U1: |
|
|
|
|
case Code.Conv_U2: |
|
|
|
|
case Code.Conv_U4: |
|
|
|
|
case Code.Conv_U8: |
|
|
|
|
case Code.Conv_R4: |
|
|
|
|
case Code.Conv_R8: |
|
|
|
|
case Code.Conv_R_Un: |
|
|
|
|
|
|
|
|
|
case Code.Conv_Ovf_I: |
|
|
|
|
case Code.Conv_Ovf_I1: |
|
|
|
|
case Code.Conv_Ovf_I2: |
|
|
|
|
case Code.Conv_Ovf_I4: |
|
|
|
|
case Code.Conv_Ovf_I8: |
|
|
|
|
case Code.Conv_Ovf_U: |
|
|
|
|
case Code.Conv_Ovf_U1: |
|
|
|
|
case Code.Conv_Ovf_U2: |
|
|
|
|
case Code.Conv_Ovf_U4: |
|
|
|
|
case Code.Conv_Ovf_U8: |
|
|
|
|
|
|
|
|
|
case Code.Conv_Ovf_I_Un: |
|
|
|
|
case Code.Conv_Ovf_I1_Un: |
|
|
|
|
case Code.Conv_Ovf_I2_Un: |
|
|
|
|
case Code.Conv_Ovf_I4_Un: |
|
|
|
|
case Code.Conv_Ovf_I8_Un: |
|
|
|
|
case Code.Conv_Ovf_U_Un: |
|
|
|
|
case Code.Conv_Ovf_U1_Un: |
|
|
|
|
case Code.Conv_Ovf_U2_Un: |
|
|
|
|
case Code.Conv_Ovf_U4_Un: |
|
|
|
|
case Code.Conv_Ovf_U8_Un: return Constants.Int32; |
|
|
|
|
#endregion
|
|
|
|
|
#region Indirect
|
|
|
|
|
case Code.Ldind_I: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_I1: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_I2: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_I4: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_I8: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_U1: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_U2: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_U4: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_R4: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_R8: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldind_Ref: throw new NotImplementedException(); |
|
|
|
|
|
|
|
|
|
case Code.Stind_I: throw new NotImplementedException(); |
|
|
|
|
case Code.Stind_I1: throw new NotImplementedException(); |
|
|
|
|
case Code.Stind_I2: throw new NotImplementedException(); |
|
|
|
|
case Code.Stind_I4: throw new NotImplementedException(); |
|
|
|
|
case Code.Stind_I8: throw new NotImplementedException(); |
|
|
|
|
case Code.Stind_R4: throw new NotImplementedException(); |
|
|
|
|
case Code.Stind_R8: throw new NotImplementedException(); |
|
|
|
|
case Code.Stind_Ref: throw new NotImplementedException(); |
|
|
|
|
#endregion
|
|
|
|
|
case Code.Arglist: throw new NotImplementedException(); |
|
|
|
|
case Code.Box: throw new NotImplementedException(); |
|
|
|
|
case Code.Break: throw new NotImplementedException(); |
|
|
|
|
case Code.Call: return ((MethodReference)operand).ReturnType.ReturnType; |
|
|
|
|
case Code.Calli: throw new NotImplementedException(); |
|
|
|
|
case Code.Callvirt: throw new NotImplementedException(); |
|
|
|
|
case Code.Castclass: throw new NotImplementedException(); |
|
|
|
|
case Code.Ckfinite: throw new NotImplementedException(); |
|
|
|
|
case Code.Constrained: throw new NotImplementedException(); |
|
|
|
|
case Code.Cpblk: throw new NotImplementedException(); |
|
|
|
|
case Code.Cpobj: throw new NotImplementedException(); |
|
|
|
|
case Code.Dup: throw new NotImplementedException(); |
|
|
|
|
case Code.Endfilter: throw new NotImplementedException(); |
|
|
|
|
case Code.Endfinally: throw new NotImplementedException(); |
|
|
|
|
case Code.Initblk: throw new NotImplementedException(); |
|
|
|
|
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.Ldarga: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldc_I4: return Cecil.Constants.Int16; |
|
|
|
|
case Code.Ldc_I8: return Cecil.Constants.Int64; |
|
|
|
|
case Code.Ldc_R4: return Cecil.Constants.Single; |
|
|
|
|
case Code.Ldc_R8: return Cecil.Constants.Double; |
|
|
|
|
case Code.Ldfld: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldflda: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldftn: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldloc: return ((VariableDefinition)operand).VariableType; |
|
|
|
|
case Code.Ldloca: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldnull: return Cecil.Constants.Object; |
|
|
|
|
case Code.Ldobj: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldsfld: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldsflda: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldstr: return Cecil.Constants.String; |
|
|
|
|
case Code.Ldtoken: throw new NotImplementedException(); |
|
|
|
|
case Code.Ldvirtftn: throw new NotImplementedException(); |
|
|
|
|
case Code.Leave: throw new NotImplementedException(); |
|
|
|
|
case Code.Localloc: throw new NotImplementedException(); |
|
|
|
|
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.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.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.Stobj: throw new NotImplementedException(); |
|
|
|
|
case Code.Stsfld: throw new NotImplementedException(); |
|
|
|
|
case Code.Switch: throw new NotImplementedException(); |
|
|
|
|
case Code.Tail: throw new NotImplementedException(); |
|
|
|
|
case Code.Throw: throw new NotImplementedException(); |
|
|
|
|
case Code.Unaligned: throw new NotImplementedException(); |
|
|
|
|
case Code.Unbox: throw new NotImplementedException(); |
|
|
|
|
case Code.Unbox_Any: throw new NotImplementedException(); |
|
|
|
|
case Code.Volatile: throw new NotImplementedException(); |
|
|
|
|
default: throw new Exception("Unknown OpCode: " + opCode); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|