public bool IsOpCall(Mono.Cecil.MethodReference refs, out string name) { var defs = refs.Resolve(); foreach (var attr in defs.CustomAttributes) { if (attr.AttributeType.Name == "ScriptOpAttribute") { var type = attr.ConstructorArguments[0].Type; var value = (byte)attr.ConstructorArguments[0].Value; foreach (var t in type.Resolve().Fields) { if (t.Constant != null) { if ((byte)t.Constant == value) { //dosth name = t.Name; return(true); } } } } //if(attr.t) } name = ""; return(false); }
public bool IsAppCall(Mono.Cecil.MethodReference refs, out byte[] hash) { try { var defs = refs.Resolve(); foreach (var attr in defs.CustomAttributes) { if (attr.AttributeType.Name == "AppcallAttribute") { var type = attr.ConstructorArguments[0].Type; var a = attr.ConstructorArguments[0]; var list = a.Value as Mono.Cecil.CustomAttributeArgument[]; hash = new byte[20]; for (var i = 0; i < 20; i++) { hash[i] = (byte)list[i].Value; } //dosth return(true); } //if(attr.t) } hash = null; return(false); } catch { hash = null; return(false); } }
IMethod GetMethod(object token) { Mono.Cecil.ModuleDefinition module = null; string methodname = null; string typename = null; MethodParamList genlist = null; MethodParamList list = null; if (token is Mono.Cecil.MethodReference) { Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference); module = _ref.Module; methodname = _ref.Name; typename = _ref.DeclaringType.FullName; list = new MethodParamList(environment, _ref); if (_ref.IsGenericInstance) { Mono.Cecil.GenericInstanceMethod gmethod = _ref as Mono.Cecil.GenericInstanceMethod; genlist = new MethodParamList(environment, gmethod); } } else if (token is Mono.Cecil.MethodDefinition) { Mono.Cecil.MethodDefinition _def = token as Mono.Cecil.MethodDefinition; module = _def.Module; methodname = _def.Name; typename = _def.DeclaringType.FullName; list = new MethodParamList(environment, _def); if (_def.IsGenericInstance) { throw new NotImplementedException(); //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod; //genlist = new MethodParamList(environment, gmethod); } } else { throw new NotImplementedException(); } var typesys = GetType(typename, module); if (typesys == null) { throw new Exception("type can't find:" + typename); } IMethod _method = null; if (genlist != null) { _method = typesys.GetMethodT(methodname, genlist, list); } else { _method = typesys.GetMethod(methodname, list); } return(_method); }
public bool IsSysCall(Mono.Cecil.MethodReference refs, out string name) { try { var defs = refs.Resolve(); foreach (var attr in defs.CustomAttributes) { if (attr.AttributeType.Name == "SyscallAttribute") { var type = attr.ConstructorArguments[0].Type; var value = (string)attr.ConstructorArguments[0].Value; //dosth name = value; return(true); } //if(attr.t) } name = ""; return(false); } catch { name = ""; return(false); } }
private static Mono.Cecil.MethodReference CloneMethodWithDeclaringType( Mono.Cecil.MethodReference methodDef, Mono.Cecil.TypeReference declaringTypeRef) { if (!declaringTypeRef.IsGenericInstance || methodDef == null) { return(methodDef); } var methodRef = new Mono.Cecil.MethodReference(methodDef.Name, methodDef.ReturnType, declaringTypeRef) { CallingConvention = methodDef.CallingConvention, HasThis = methodDef.HasThis, ExplicitThis = methodDef.ExplicitThis }; foreach (Mono.Cecil.GenericParameter genParamDef in methodDef.GenericParameters) { methodRef.GenericParameters.Add(CloneGenericParameter(genParamDef, methodRef)); } methodRef.ReturnType = declaringTypeRef.Module.ImportReference(methodDef.ReturnType, methodRef); foreach (Mono.Cecil.ParameterDefinition paramDef in methodDef.Parameters) { methodRef.Parameters.Add( new Mono.Cecil.ParameterDefinition( paramDef.Name, paramDef.Attributes, declaringTypeRef.Module.ImportReference(paramDef.ParameterType, methodRef))); } return(methodRef); }
public static void InjectPrologue(Mono.Cecil.MethodReference methodRef) { if (null != s_CurFile) { s_CurFile.InjectPrologue(methodRef); } }
public MethodParamList(ICLRSharp_Environment env, Mono.Cecil.MethodReference method) { if (method.HasParameters) { Mono.Cecil.GenericInstanceType _typegen = null; _typegen = method.DeclaringType as Mono.Cecil.GenericInstanceType; Mono.Cecil.GenericInstanceMethod gm = method as Mono.Cecil.GenericInstanceMethod; MethodParamList _methodgen = null; if (gm != null) { _methodgen = new MethodParamList(env, gm); } foreach (var p in method.Parameters) { string paramname = p.ParameterType.FullName; if (p.ParameterType.IsGenericParameter) { if (p.ParameterType.Name.Contains("!!")) { int index = int.Parse(p.ParameterType.Name.Substring(2)); paramname = _methodgen[index].FullName; } else if (p.ParameterType.Name.Contains("!")) { int index = int.Parse(p.ParameterType.Name.Substring(1)); paramname = _typegen.GenericArguments[index].FullName; } } if (paramname.Contains("!!")) { //string typename = param.ParameterType.FullName; for (int i = 0; i < _methodgen.Count; i++) { string pp = "!!" + i.ToString(); paramname = paramname.Replace(pp, _methodgen[i].FullName); } //this.Add(GetTType(env, p, _methodgen)); } if (paramname.Contains("!"))//函数有T { var gens = (method.DeclaringType as Mono.Cecil.GenericInstanceType).GenericArguments; for (int i = 0; i < gens.Count; i++) { string pp = "!" + i.ToString(); paramname = paramname.Replace(pp, gens[i].FullName); } } //else { this.Add(env.GetType(paramname)); } } } }
public IMethod Resolve(Mono.Cecil.MethodReference methodReference) { IMethod method = context.Resolve(methodReference); if (method != null) { method = (IMethod)method.Specialize(substitution); } return(method); }
public static bool CheckMethod(Mono.Cecil.MethodDefinition methodDef, Mono.Cecil.MethodReference methodRef) { string func; if (s_CheckMethodFuncs.TryGetValue(methodRef.Name, out func)) { var ret = s_Calculator.Calc(func, methodDef, methodRef); if (null != ret) { return((bool)Convert.ChangeType(ret, typeof(bool))); } } return(true); }
private static void ConvertMethodDefinition(MethodReference method, TypeReference enumType) { if (method.ReturnType.FullName == SystemEnumName) { method.ReturnType = enumType; } foreach (var p in method.Parameters) { if (p.ParameterType.FullName == SystemEnumName) { p.ParameterType = enumType; } } }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call var c = _Convert1by1(AntShares.VM.OpCode.CALL, src, to, new byte[] { 5, 0 }); c.needfix = true; c.srcfunc = src.tokenMethod; return(0); } else if (refs.ReturnType.Name == "ScriptEngine") { //donothing 語法過渡類型 return(0); } else {//maybe a syscall // or other if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else { string name; if (IsOpCall(refs, out name)) { if (name == "CHECKSIG") { _Convert1by1(AntShares.VM.OpCode.CHECKSIG, src, to); return(0); } } if (IsSysCall(refs, out name)) { _Convert1by1(AntShares.VM.OpCode.SYSCALL, src, to, str2Pushdata1bytes(name)); return(0); } throw new Exception("unknown call:" + src.tokenMethod); } } }
public static ProductException CreateError(int code, Mono.Cecil.MemberReference member, string message, params object[] args) { Mono.Cecil.MethodReference method = member as Mono.Cecil.MethodReference; if (method == null) { var property = member as Mono.Cecil.PropertyDefinition; if (property != null) { method = property.GetMethod; if (method == null) { method = property.SetMethod; } } } return(CreateError(code, method == null ? null : method.Resolve(), message, args)); }
public static ProductException Create(Application app, int code, bool error, Exception innerException, Mono.Cecil.MemberReference member, Instruction instruction, string message, params object [] args) { Mono.Cecil.MethodReference method = member as Mono.Cecil.MethodReference; if (method == null) { var property = member as Mono.Cecil.PropertyDefinition; if (property != null) { method = property.GetMethod; if (method == null) { method = property.SetMethod; } } } return(Create(app, code, error, innerException, method == null ? null : method.Resolve(), instruction, message, args)); }
public bool IsNotifyCall(Mono.Cecil.MethodDefinition defs, Mono.Cecil.MethodReference refs, NeoMethod to, out string name) { name = to.lastsfieldname; if (to.lastsfieldname == null) { return(false); } Mono.Cecil.TypeDefinition call = null; if (defs == null) { try { call = refs.DeclaringType.Resolve(); } catch {//当不能取得这个,大半都是模板类 } } else { call = defs.DeclaringType; } if (call != null) { if (call.BaseType.Name == "MulticastDelegate" || call.BaseType.Name == "Delegate") { to.lastsfieldname = null; return(true); } } else//不能还原类型,只好用名字判断了 { if (refs.Name == "Invoke" && refs.DeclaringType.Name.Contains("Action`")) { to.lastsfieldname = null; return(true); } } name = "Notify"; return(false); }
public MethodParamList(ICLRSharp_Environment env, Mono.Cecil.MethodReference method) { if (method.HasParameters) { Mono.Cecil.GenericInstanceType _typegen = null; _typegen = method.DeclaringType as Mono.Cecil.GenericInstanceType; Mono.Cecil.GenericInstanceMethod gm = method as Mono.Cecil.GenericInstanceMethod; MethodParamList _methodgen = null; if (gm != null) { _methodgen = new MethodParamList(env, gm); } foreach (var p in method.Parameters) { string paramname = p.ParameterType.FullName; if (p.ParameterType.IsGenericParameter) { if (p.ParameterType.Name.Contains("!!")) { int index = int.Parse(p.ParameterType.Name.Substring(2)); paramname = _methodgen[index].FullName; } else if (p.ParameterType.Name.Contains("!")) { int index = int.Parse(p.ParameterType.Name.Substring(1)); paramname = _typegen.GenericArguments[index].FullName; } } if (paramname.Contains("!!")) { this.Add(GetTType(env, p, method, _methodgen)); } else { this.Add(env.GetType(paramname, method.Module)); } } } }
public void ResetVirtualRegisters() { foreach (IR.InstructionElement i in this.FlatInstructionList) { switch (i.Instruction.OpCode.StackBehaviourPush) { case Mono.Cecil.Cil.StackBehaviour.Push0: break; case Mono.Cecil.Cil.StackBehaviour.Varpush: Mono.Cecil.MethodReference f = ((Mono.Cecil.MethodReference)i.Instruction.Operand); if (f.ReturnType.ReturnType.FullName != "System.Void") { i.Register = new VirtualRegister(); } break; case Mono.Cecil.Cil.StackBehaviour.Push1_push1: i.Register = new VirtualRegister(); i.DupRegister = new VirtualRegister(); break; case Mono.Cecil.Cil.StackBehaviour.Push1: case Mono.Cecil.Cil.StackBehaviour.Pushi: case Mono.Cecil.Cil.StackBehaviour.Pushi8: case Mono.Cecil.Cil.StackBehaviour.Pushr4: case Mono.Cecil.Cil.StackBehaviour.Pushr8: case Mono.Cecil.Cil.StackBehaviour.Pushref: i.Register = new VirtualRegister(); break; default: throw new Exception("Unexpected stack push type: " + i.Instruction.OpCode.StackBehaviourPush); } } }
private int _ConvertCall(OpCode src, NeoMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; int callpcount = 0; byte[] callhash = null; VM.OpCode callcode = VM.OpCode.NOP; Mono.Cecil.MethodDefinition defs = null; try { defs = refs.Resolve(); } catch { } if (IsNonCall(defs)) { return(0); } else if (IsNotifyCall(defs, refs, to, out callname)) { calltype = 5; } else if (to.lastparam >= 0) { callpcount = to.lastparam; calltype = 6; to.lastparam = -1; } else if (IsOpCall(defs, out callname)) { if (System.Enum.TryParse <VM.OpCode>(callname, out callcode)) { calltype = 2; } else { throw new Exception("Can not find OpCall:" + callname); } } else if (IsSysCall(defs, out callname)) { calltype = 3; } else if (IsAppCall(defs, out callhash)) { calltype = 4; } else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else {//maybe a syscall // or other if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit(")) { //各类显示隐示转换都忽略 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Int64 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } return(0); } else if (src.tokenMethod == "System.Void System.Diagnostics.Debugger::Break()") { _Convert1by1(VM.OpCode.NOP, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals(")) { var _ref = src.tokenUnknown as Mono.Cecil.MethodReference; if (_ref.DeclaringType.FullName == "System.Boolean" || _ref.DeclaringType.FullName == "System.Int32" || _ref.DeclaringType.FullName == "System.Numerics.BigInteger") { _Convert1by1(VM.OpCode.NUMEQUAL, src, to); } else { _Convert1by1(VM.OpCode.EQUAL, src, to); } //各类==指令 //有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)") //{ // _Convert1by1(VM.OpCode.EQUAL, src, to); // return 0; //} //else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") //{ // _Convert1by1(VM.OpCode.EQUAL, src, to); // return 0; //} //_Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Inequality(")) { var _ref = src.tokenUnknown as Mono.Cecil.MethodReference; if (_ref.DeclaringType.FullName == "System.Boolean" || _ref.DeclaringType.FullName == "System.Int32" || _ref.DeclaringType.FullName == "System.Numerics.BigInteger") { _Convert1by1(VM.OpCode.NUMNOTEQUAL, src, to); } else { _Convert1by1(VM.OpCode.EQUAL, src, to); _Convert1by1(VM.OpCode.NOT, null, to); } ////各类!=指令 ////有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)") //{ // _Convert1by1(VM.OpCode.INVERT, src, to); // _Insert1(VM.OpCode.EQUAL, "", to); // return 0; //} //_Convert1by1(VM.OpCode.INVERT, src, to); //_Insert1(VM.OpCode.EQUAL, "", to); return(0); } else if (src.tokenMethod.Contains("::op_Addition(")) { //各类+指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.ADD, src, to); return(0); } _Convert1by1(VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Subtraction(")) { //各类-指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.SUB, src, to); return(0); } _Convert1by1(VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Multiply(")) { //各类*指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MUL, src, to); return(0); } _Convert1by1(VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Division(")) { //各类/指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Division(System.Numerics.BigInteger, System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.DIV, src, to); return(0); } _Convert1by1(VM.OpCode.DIV, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Modulus(")) { //各类%指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MOD, src, to); return(0); } _Convert1by1(VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(VM.OpCode.SUBSTR, null, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32)") { throw new Exception("neomachine cant use this call,please use .SubString(1,2) with 2 params."); } else if (src.tokenMethod == "System.String System.Char::ToString()") { return(0); } else if (src.tokenMethod == "System.Byte[] System.Numerics.BigInteger::ToByteArray()") { return(0); } else if (src.tokenMethod == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); return(0); } else if (src.tokenMethod == "System.UInt32 <PrivateImplementationDetails>::ComputeStringHash(System.String)") { throw new Exception("not supported on neovm now."); // 需要neo.vm nuget更新以后,这个才可以放开,就可以处理 string switch了。"); //_Convert1by1(VM.OpCode.CSHARPSTRHASH32, src, to); //return 0; } else { } } if (calltype == 0) { //之前的所有尝试都无效,那也不一定是个不存在的函数,有可能在别的模块里 if (TryInsertMethod(outModule, defs)) { calltype = 1; //ILModule module = new ILModule(); //module.LoadModule //ILType type =new ILType() //ILMethod method = new ILMethod(defs) } else { throw new Exception("unknown call: " + src.tokenMethod + "\r\n in: " + to.name + "\r\n"); } } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; bool havethis = md.HasThis; if (calltype == 2) { //opcode call } else {//翻转参数顺序 //如果是syscall 并且有this的,翻转范围加一 if (calltype == 3 && havethis) { pcount++; } _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } } if (calltype == 1) { if (this.outModule.option.useNep8) { byte _pcount = (byte)defs.Parameters.Count; byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1); var c = _Convert1by1(VM.OpCode.CALL_I, null, to, new byte[] { _rvcount, _pcount, 0, 0 }); c.needfixfunc = true; c.srcfunc = src.tokenMethod; } else { var c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfixfunc = true; c.srcfunc = src.tokenMethod; } return(0); } else if (calltype == 2) { _Convert1by1(callcode, src, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is to long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { if (this.outModule.option.useNep8) { byte _pcount = (byte)defs.Parameters.Count; byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1); if (callhash.All(v => v == 0))//empty nep4 { throw new Exception("nep4 calltype==6"); } else { var bytes = new byte[] { _rvcount, _pcount }.Concat(callhash).ToArray(); _Convert1by1(VM.OpCode.CALL_E, null, to, bytes); } } else { _Convert1by1(VM.OpCode.APPCALL, null, to, callhash); } } else if (calltype == 5) { //把name参数推进去 var callp = Encoding.UTF8.GetBytes(callname); _ConvertPush(callp, src, to); //参数打包成array _ConvertPush(pcount + 1, null, to); _Convert1by1(VM.OpCode.PACK, null, to); //a syscall { var bytes = Encoding.UTF8.GetBytes("Neo.Runtime.Notify"); byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); } } else if (calltype == 6) { _ConvertPush(callpcount, src, to); _Convert1by1(VM.OpCode.ROLL, null, to); //dyn appcall if (this.outModule.option.useNep8) { byte _pcount = (byte)defs.Parameters.Count; byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1); //byte signature = (byte)( // (retcount << 7) // | // defs.Parameters.Count // ); _Convert1by1(VM.OpCode.CALL_ED, null, to, new byte[] { _rvcount, _pcount }); } else { byte[] nullhash = new byte[20]; _Convert1by1(VM.OpCode.APPCALL, null, to, nullhash); } } return(0); }
public static void Inject(string input_assembly_path, string output_assembly_path, string logger_assembly_path, string logger_type_name, string before_call_log_method_name, string log_attribute_name) { System.Diagnostics.Debug.Assert(System.IO.File.Exists(input_assembly_path)); if (input_assembly_path != output_assembly_path) { if (System.IO.File.Exists(output_assembly_path)) { System.IO.File.Delete(output_assembly_path); } System.IO.File.Copy(input_assembly_path, output_assembly_path); System.Diagnostics.Debug.Assert(System.IO.File.Exists(output_assembly_path)); } var assembly_resolver = new Mono.Cecil.DefaultAssemblyResolver(); string input_assembly_directory = System.IO.Path.GetDirectoryName(input_assembly_path); assembly_resolver.AddSearchDirectory(input_assembly_directory); #if SILVERLIGHT Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath path_task = new Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath(); path_task.RegistryBase = "Software\\Microsoft\\Microsoft SDKs\\Silverlight"; path_task.Execute(); assembly_resolver.AddSearchDirectory(path_task.SilverlightPath); foreach (string path in path_task.SilverlightSDKPaths) { assembly_resolver.AddSearchDirectory(path); } #endif Mono.Cecil.AssemblyDefinition injectible_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(output_assembly_path, new Mono.Cecil.ReaderParameters { AssemblyResolver = assembly_resolver }); System.Diagnostics.Debug.Assert(System.IO.File.Exists(logger_assembly_path)); Mono.Cecil.AssemblyDefinition logger_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(logger_assembly_path); Mono.Cecil.TypeDefinition logger_type = logger_assembly.MainModule.GetType(logger_type_name); System.Diagnostics.Debug.Assert(logger_type != null); Mono.Cecil.MethodDefinition before_callback_method_info = logger_type.Methods.First(m => m.Name == before_call_log_method_name); Mono.Cecil.MethodReference before_callback_reference = injectible_assembly.MainModule.Import(before_callback_method_info); //make sure to get System.Object.ToString method from assembly compatible with the injected assembly #if SILVERLIGHT string core_assembly_path = path_task.SilverlightPath + "mscorlib.dll"; Mono.Cecil.AssemblyDefinition core_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(core_assembly_path); Mono.Cecil.TypeDefinition object_type = core_assembly.MainModule.GetType("System.Object"); Mono.Cecil.MethodDefinition to_string_method_info = object_type.Methods.First(m => m.Name == "ToString"); #else System.Reflection.MethodInfo to_string_method_info = typeof(System.Object).GetMethod("ToString"); #endif Mono.Cecil.MethodReference to_string_reference = injectible_assembly.MainModule.Import(to_string_method_info); foreach (Mono.Cecil.TypeDefinition type_definition in injectible_assembly.MainModule.Types) { bool is_type_logable = type_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name); foreach (Mono.Cecil.MethodDefinition method_definition in type_definition.Methods) { bool is_method_logable = is_type_logable || method_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name); if (is_method_logable) { Mono.Cecil.Cil.ILProcessor processor = method_definition.Body.GetILProcessor(); System.Collections.Generic.List <Mono.Cecil.Cil.Instruction> original_instructions = new System.Collections.Generic.List <Mono.Cecil.Cil.Instruction>(); original_instructions.AddRange(method_definition.Body.Instructions); method_definition.Body.Instructions.Clear(); #region parameters int method_parameters_count = method_definition.Parameters.Count; int local_variables_count = method_definition.Body.Variables.Count; int arguments_array_index = local_variables_count; // Create an array of type System.String with the same number of elements as count of method parameters // Add metadata for a new variable of type System.String[] to method body // .locals init (System.String[] V_0) Mono.Cecil.ArrayType arguments = new Mono.Cecil.ArrayType(injectible_assembly.MainModule.TypeSystem.String); method_definition.Body.Variables.Add(new Mono.Cecil.Cil.VariableDefinition((Mono.Cecil.TypeReference)arguments)); method_definition.Body.InitLocals = true; method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, method_parameters_count)); method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Newarr, injectible_assembly.MainModule.TypeSystem.String)); // This instruction will store the address of the newly created array in the newly added local variable, which is at index = local_variables_count method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stloc, arguments_array_index)); #region parameters_to_string // Instance methods have an an implicit argument called "this" // so in that case we need to refer to actual arguments with +1 position int parameter_offset = method_definition.IsStatic ? 0 : 1; for (int i = 0; i < method_parameters_count; ++i) { // load argument array and current index method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index)); method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, i)); // load argument method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldarga, i + parameter_offset)); // convert argument to string Mono.Cecil.TypeReference argument_type = method_definition.Parameters[i].ParameterType; method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Constrained, argument_type)); method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Callvirt, to_string_reference)); // store string in array method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stelem_Ref)); } #endregion parameters_to_string string method_signature = method_definition.ToString(); // load method signature method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldstr, method_signature)); // load parameters array method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index)); #endregion parameters // load before call instruction method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Call, before_callback_reference)); foreach (var IL in original_instructions) { method_definition.Body.Instructions.Add(IL); } } } } injectible_assembly.Write(output_assembly_path); }
public void RegisterCall(Mono.Cecil.MethodReference t) { m_calls.Add(new KeyValuePair <int, Mono.Cecil.MethodReference>(m_instructionList.Count, t)); }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; byte[] callhash = null; VM.OpCode callcode = VM.OpCode.NOP; Mono.Cecil.MethodDefinition defs = null; try { defs = refs.Resolve(); } catch { } if (IsNonCall(defs)) { return(0); } else if (IsOpCall(defs, out callname)) { if (System.Enum.TryParse <VM.OpCode>(callname, out callcode)) { calltype = 2; } else { throw new Exception("Can not find OpCall:" + callname); } } else if (IsSysCall(defs, out callname)) { calltype = 3; } else if (IsAppCall(defs, out callhash)) { calltype = 4; } else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else {//maybe a syscall // or other if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit(")) { //各类显示隐示转换都忽略 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Int64 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } return(0); } else if (src.tokenMethod == "System.Void System.Diagnostics.Debugger::Break()") { _Convert1by1(VM.OpCode.NOP, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals(")) { //各类==指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)") { _Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") { _Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } _Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Inequality(")) { //各类!=指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.INVERT, src, to); _Insert1(VM.OpCode.EQUAL, "", to); return(0); } _Convert1by1(VM.OpCode.INVERT, src, to); _Insert1(VM.OpCode.EQUAL, "", to); return(0); } else if (src.tokenMethod.Contains("::op_Addition(")) { //各类+指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.ADD, src, to); return(0); } _Convert1by1(VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Subtraction(")) { //各类-指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.SUB, src, to); return(0); } _Convert1by1(VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Multiply(")) { //各类*指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MUL, src, to); return(0); } _Convert1by1(VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Division(")) { //各类/指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Division(System.Numerics.BigInteger, System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.DIV, src, to); return(0); } _Convert1by1(VM.OpCode.DIV, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Modulus(")) { //各类%指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MOD, src, to); return(0); } _Convert1by1(VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(VM.OpCode.SUBSTR, null, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32)") { throw new Exception("antsmachine cant use this call,please use .SubString(1,2) with 2 params."); } else if (src.tokenMethod == "System.String System.Char::ToString()") { return(0); } else if (src.tokenMethod == "System.Byte[] System.Numerics.BigInteger::ToByteArray()") { return(0); } else if (src.tokenMethod == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); return(0); } else { } } if (calltype == 0) { throw new Exception("unknown call:" + src.tokenMethod); } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } if (calltype == 1) { var c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfix = true; c.srcfunc = src.tokenMethod; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is to long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { _Convert1by1(VM.OpCode.APPCALL, null, to, callhash); } return(0); }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; VM.OpCode callcode = VM.OpCode.NOP; if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else if (refs.ReturnType.Name == "ExecutionEngine" || refs.ReturnType.Name == "Storage") { if (src != null) { //有可能jump到此处 this.addrconv[src.addr] = this.addr;//因为没插入代码,实际是下一行 } //donothing 語法過渡類型 return(0); } else {//maybe a syscall // or other if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals(")) { _Convert1by1(AntShares.VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThanOrEqual(System.Numerics.BigInteger,System.Int64)") { _Convert1by1(AntShares.VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_GreaterThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.GT, src, to); return(0); } else { if (IsOpCall(refs, out callname)) { if (callname == "CHECKSIG") { callcode = VM.OpCode.CHECKSIG; calltype = 2; } } if (IsSysCall(refs, out callname)) { calltype = 3; } } } if (calltype == 0) { throw new Exception("unknown call:" + src.tokenMethod); } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } if (calltype == 1) { var c = _Convert1by1(AntShares.VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfix = true; c.srcfunc = src.tokenMethod; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is to long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(AntShares.VM.OpCode.SYSCALL, null, to, outbytes); return(0); } return(0); }
private static void ConvertMethodDefinition(MethodReference method, TypeReference enumType) { if (method.ReturnType.FullName == SystemEnumName) method.ReturnType = enumType; foreach (var p in method.Parameters) if (p.ParameterType.FullName == SystemEnumName) p.ParameterType = enumType; }
ICLRType GetTType(ICLRSharp_Environment env, Mono.Cecil.ParameterDefinition param, Mono.Cecil.MethodReference method, MethodParamList _methodgen) { string typename = param.ParameterType.FullName; for (int i = 0; i < _methodgen.Count; i++) { string p = "!!" + i.ToString(); typename = typename.Replace(p, _methodgen[i].FullName); } return(env.GetType(typename, method.Module)); }
public static void CallVirtual(Mono.Cecil.MethodReference method) { CurrentEmitContext.Emit(CreateInstruction.CallVirtual(method)); }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; VM.OpCode callcode = VM.OpCode.NOP; if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else if (refs.ReturnType.Name == "ExecutionEngine") { //donothing 語法過渡類型 return(0); } else {//maybe a syscall // or other if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") { _Convert1by1(AntShares.VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThanOrEqual(System.Numerics.BigInteger,System.Int64)") { _Convert1by1(AntShares.VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_GreaterThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.GT, src, to); return(0); } else { if (IsOpCall(refs, out callname)) { if (callname == "CHECKSIG") { callcode = VM.OpCode.CHECKSIG; calltype = 2; } } if (IsSysCall(refs, out callname)) { calltype = 3; } } } if (calltype == 0) { throw new Exception("unknown call:" + src.tokenMethod); } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _Insert1(VM.OpCode.PUSHDATA1, "swap 0 and 2 param", to, int2Pushdata1bytes(2)); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _Insert1(VM.OpCode.PUSHDATA1, "load" + saveto, to, int2Pushdata1bytes(saveto)); _Insert1(VM.OpCode.PICK, "", to); _Insert1(VM.OpCode.PUSHDATA1, "load" + i + 1, to, int2Pushdata1bytes(i + 1)); _Insert1(VM.OpCode.PICK, "", to); _Insert1(VM.OpCode.PUSHDATA1, "save to" + saveto + 2, to, int2Pushdata1bytes(saveto + 2)); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _Insert1(VM.OpCode.PUSHDATA1, "save to" + i + 1, to, int2Pushdata1bytes(i + 1)); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } if (calltype == 1) { var c = _Convert1by1(AntShares.VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfix = true; c.srcfunc = src.tokenMethod; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { _Convert1by1(AntShares.VM.OpCode.SYSCALL, null, to, str2Pushdata1bytes(callname)); return(0); } return(0); }
private void AssignReturnType() { IsReturnTypeRef = false; switch (Instruction.OpCode.StackBehaviourPush) { case Mono.Cecil.Cil.StackBehaviour.Push0: ReturnType = null; break; case Mono.Cecil.Cil.StackBehaviour.Push1: switch (Instruction.OpCode.Code) { //These return the argument type case Mono.Cecil.Cil.Code.Ldarg_0: ReturnType = Type.GetType(ParentMethod.Parameters[0].ParameterType.FullName); break; case Mono.Cecil.Cil.Code.Ldarg_1: ReturnType = Type.GetType(ParentMethod.Parameters[1].ParameterType.FullName); break; case Mono.Cecil.Cil.Code.Ldarg_2: ReturnType = Type.GetType(ParentMethod.Parameters[2].ParameterType.FullName); break; case Mono.Cecil.Cil.Code.Ldarg_3: ReturnType = Type.GetType(ParentMethod.Parameters[3].ParameterType.FullName); break; case Mono.Cecil.Cil.Code.Ldarg_S: case Mono.Cecil.Cil.Code.Ldarg: ReturnType = Type.GetType(ParentMethod.Parameters[((int)Instruction.Operand)].ParameterType.FullName); break; //These return the local variable type case Mono.Cecil.Cil.Code.Ldloc_0: ReturnType = Type.GetType(ParentMethod.Body.Variables[0].VariableType.FullName); break; case Mono.Cecil.Cil.Code.Ldloc_1: ReturnType = Type.GetType(ParentMethod.Body.Variables[1].VariableType.FullName); break; case Mono.Cecil.Cil.Code.Ldloc_2: ReturnType = Type.GetType(ParentMethod.Body.Variables[2].VariableType.FullName); break; case Mono.Cecil.Cil.Code.Ldloc_3: ReturnType = Type.GetType(ParentMethod.Body.Variables[3].VariableType.FullName); break; case Mono.Cecil.Cil.Code.Ldloc_S: case Mono.Cecil.Cil.Code.Ldloc: ReturnType = Type.GetType(ParentMethod.Body.Variables[((Mono.Cecil.Cil.VariableReference)(Instruction.Operand)).Index].VariableType.FullName); break; //These return the same type as their source operands case Mono.Cecil.Cil.Code.Add: case Mono.Cecil.Cil.Code.Sub: case Mono.Cecil.Cil.Code.Mul: case Mono.Cecil.Cil.Code.Div: case Mono.Cecil.Cil.Code.Rem: case Mono.Cecil.Cil.Code.And: case Mono.Cecil.Cil.Code.Or: case Mono.Cecil.Cil.Code.Xor: case Mono.Cecil.Cil.Code.Shl: case Mono.Cecil.Cil.Code.Shr: case Mono.Cecil.Cil.Code.Neg: case Mono.Cecil.Cil.Code.Not: case Mono.Cecil.Cil.Code.Div_Un: case Mono.Cecil.Cil.Code.Rem_Un: case Mono.Cecil.Cil.Code.Shr_Un: case Mono.Cecil.Cil.Code.Add_Ovf: case Mono.Cecil.Cil.Code.Add_Ovf_Un: case Mono.Cecil.Cil.Code.Mul_Ovf: case Mono.Cecil.Cil.Code.Mul_Ovf_Un: case Mono.Cecil.Cil.Code.Sub_Ovf: case Mono.Cecil.Cil.Code.Sub_Ovf_Un: if (Childnodes[0].IsReturnTypeRef) { throw new Exception("Unexpected operands"); } ReturnType = Childnodes[0].ReturnType; break; case Mono.Cecil.Cil.Code.Ldobj: if (!Childnodes[0].IsReturnTypeRef) { throw new Exception("Ldobj from something that is not an array?"); } ReturnType = Childnodes[0].ReturnType; IsReturnTypeRef = false; break; //These are not fixed yet case Mono.Cecil.Cil.Code.Mkrefany: case Mono.Cecil.Cil.Code.Ldelem_Any: case Mono.Cecil.Cil.Code.Ldsfld: case Mono.Cecil.Cil.Code.Ldfld: throw new Exception("The opcode is not supported for Push1: " + Instruction.OpCode.Code); case Mono.Cecil.Cil.Code.Unbox_Any: ReturnType = Type.GetType(((Mono.Cecil.TypeReference)Instruction.Operand).FullName); IsReturnTypeRef = false; break; default: throw new Exception("Unexpected Push1 operation: " + Instruction.OpCode.Code); } break; case Mono.Cecil.Cil.StackBehaviour.Push1_push1: //AFAIK, the only instruction that does this is the dup instruction System.Diagnostics.Trace.Assert(Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Dup); ReturnType = Childnodes[0].ReturnType; IsReturnTypeRef = Childnodes[0].IsReturnTypeRef; break; case Mono.Cecil.Cil.StackBehaviour.Pushi: //This can actually also be an adress switch (Instruction.OpCode.Code) { case Mono.Cecil.Cil.Code.Ldelema: if (!Childnodes[0].ReturnType.IsArray) { throw new Exception("Ldelem a for type which is not an array: " + Childnodes[0].ReturnType.FullName); } ReturnType = Childnodes[0].ReturnType.GetElementType(); IsReturnTypeRef = true; break; case Mono.Cecil.Cil.Code.Ldc_I4: case Mono.Cecil.Cil.Code.Ldc_I4_0: case Mono.Cecil.Cil.Code.Ldc_I4_1: case Mono.Cecil.Cil.Code.Ldc_I4_2: case Mono.Cecil.Cil.Code.Ldc_I4_3: case Mono.Cecil.Cil.Code.Ldc_I4_4: case Mono.Cecil.Cil.Code.Ldc_I4_5: case Mono.Cecil.Cil.Code.Ldc_I4_6: case Mono.Cecil.Cil.Code.Ldc_I4_7: case Mono.Cecil.Cil.Code.Ldc_I4_8: case Mono.Cecil.Cil.Code.Ldc_I4_M1: case Mono.Cecil.Cil.Code.Ldc_I4_S: case Mono.Cecil.Cil.Code.Ldlen: case Mono.Cecil.Cil.Code.Conv_I1: case Mono.Cecil.Cil.Code.Conv_I2: case Mono.Cecil.Cil.Code.Conv_I4: case Mono.Cecil.Cil.Code.Conv_U4: case Mono.Cecil.Cil.Code.Isinst: case Mono.Cecil.Cil.Code.Conv_Ovf_I1: case Mono.Cecil.Cil.Code.Conv_Ovf_I2: case Mono.Cecil.Cil.Code.Conv_Ovf_I4: case Mono.Cecil.Cil.Code.Conv_Ovf_U1: case Mono.Cecil.Cil.Code.Conv_Ovf_U2: case Mono.Cecil.Cil.Code.Conv_Ovf_U4: case Mono.Cecil.Cil.Code.Refanyval: case Mono.Cecil.Cil.Code.Ldtoken: case Mono.Cecil.Cil.Code.Conv_U1: case Mono.Cecil.Cil.Code.Conv_U2: case Mono.Cecil.Cil.Code.Conv_I: case Mono.Cecil.Cil.Code.Conv_U: case Mono.Cecil.Cil.Code.Conv_Ovf_I: case Mono.Cecil.Cil.Code.Conv_Ovf_U: case Mono.Cecil.Cil.Code.Arglist: case Mono.Cecil.Cil.Code.Ceq: case Mono.Cecil.Cil.Code.Cgt: case Mono.Cecil.Cil.Code.Cgt_Un: case Mono.Cecil.Cil.Code.Clt: case Mono.Cecil.Cil.Code.Clt_Un: case Mono.Cecil.Cil.Code.Sizeof: case Mono.Cecil.Cil.Code.Refanytype: case Mono.Cecil.Cil.Code.Ldelem_I: case Mono.Cecil.Cil.Code.Ldelem_I4: ReturnType = typeof(int); break; case Mono.Cecil.Cil.Code.Ldelem_I1: ReturnType = typeof(sbyte); break; case Mono.Cecil.Cil.Code.Ldelem_I2: ReturnType = typeof(short); break; case Mono.Cecil.Cil.Code.Ldelem_I8: ReturnType = typeof(long); break; case Mono.Cecil.Cil.Code.Ldelem_R4: ReturnType = typeof(float); break; case Mono.Cecil.Cil.Code.Ldelem_R8: ReturnType = typeof(double); break; case Mono.Cecil.Cil.Code.Ldelem_U1: ReturnType = typeof(byte); break; case Mono.Cecil.Cil.Code.Ldelem_U2: ReturnType = typeof(ushort); break; case Mono.Cecil.Cil.Code.Ldelem_U4: ReturnType = typeof(uint); break; default: throw new Exception("Unexpected Pushi instruction: " + Instruction.OpCode.Code); } break; case Mono.Cecil.Cil.StackBehaviour.Pushi8: /*switch (instruction.OpCode.Code) * { * case Mono.Cecil.Cil.Code.Ldc_I8: * case Mono.Cecil.Cil.Code.Ldind_I8: * case Mono.Cecil.Cil.Code.Conv_I8: * case Mono.Cecil.Cil.Code.Conv_Ovf_I8: * case Mono.Cecil.Cil.Code.Conv_Ovf_I8_Un: * case Mono.Cecil.Cil.Code.Ldelem_I8: * ReturnType = typeof(long); * break; * case Mono.Cecil.Cil.Code.Conv_U8: * case Mono.Cecil.Cil.Code.Conv_Ovf_U8: * case Mono.Cecil.Cil.Code.Conv_Ovf_U8_Un: * ReturnType = typeof(ulong); * break; * default: * throw new Exception("Unexpected Pushi8 operation"); * }*/ //According to ECMA spec: // Special instructions are used to interpret integers on the stack as though they were unsigned, rather than tagging the stack locations as being unsigned. ReturnType = typeof(long); break; case Mono.Cecil.Cil.StackBehaviour.Pushr4: ReturnType = typeof(float); break; case Mono.Cecil.Cil.StackBehaviour.Pushr8: ReturnType = typeof(double); break; case Mono.Cecil.Cil.StackBehaviour.Varpush: //Instruction is supposed to be a call type function System.Diagnostics.Trace.Assert(Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Call || Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Calli || Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Callvirt); Mono.Cecil.MethodReference mdef = ((Mono.Cecil.MethodReference)Instruction.Operand); switch (mdef.ReturnType.ReturnType.FullName) { case "System.Void": ReturnType = null; break; case "System.Byte": case "System.SByte": case "System.Boolean": case "System.Int16": case "System.Int32": case "System.UInt16": case "System.UInt32": ReturnType = typeof(int); break; case "System.Int64": case "System.UInt64": ReturnType = typeof(long); break; case "System.Float": ReturnType = typeof(float); break; case "System.Double": ReturnType = typeof(double); break; default: ReturnType = Type.GetType(mdef.ReturnType.ReturnType.FullName); IsReturnTypeRef = true; break; } break; case Mono.Cecil.Cil.StackBehaviour.Pushref: IsReturnTypeRef = true; switch (Instruction.OpCode.Code) { case Mono.Cecil.Cil.Code.Ldnull: System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type"); ReturnType = null; //TODO: can we infer the type somehow? break; case Mono.Cecil.Cil.Code.Ldind_Ref: System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type"); ReturnType = null; //TODO: How do we guess this? break; case Mono.Cecil.Cil.Code.Ldstr: ReturnType = typeof(string); break; case Mono.Cecil.Cil.Code.Newobj: case Mono.Cecil.Cil.Code.Castclass: System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type"); ReturnType = ExtractClassType((Mono.Cecil.MemberReference)Instruction.Operand); break; case Mono.Cecil.Cil.Code.Box: ReturnType = Childnodes[0].ReturnType; break; case Mono.Cecil.Cil.Code.Newarr: System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type"); ReturnType = ExtractClassType((Mono.Cecil.MemberReference)Instruction.Operand); break; case Mono.Cecil.Cil.Code.Ldelem_Ref: System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type"); ReturnType = (Type)Instruction.Operand; break; default: throw new Exception("Unexpected Pushref operation"); } break; } }
public IMethod GetMethod(object token) { IMethod __method = null; if (methodCache.TryGetValue(token.GetHashCode(), out __method)) { return(__method); } Mono.Cecil.ModuleDefinition module = null; string methodname = null; string typename = null; MethodParamList genlist = null; MethodParamList list = null; if (token is Mono.Cecil.MethodReference) { Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference); module = _ref.Module; methodname = _ref.Name; typename = _ref.DeclaringType.FullName; list = new MethodParamList(environment, _ref); if (_ref.IsGenericInstance) { Mono.Cecil.GenericInstanceMethod gmethod = _ref as Mono.Cecil.GenericInstanceMethod; genlist = new MethodParamList(environment, gmethod); } } else if (token is Mono.Cecil.MethodDefinition) { Mono.Cecil.MethodDefinition _def = token as Mono.Cecil.MethodDefinition; module = _def.Module; methodname = _def.Name; typename = _def.DeclaringType.FullName; list = new MethodParamList(environment, _def); if (_def.IsGenericInstance) { throw new NotImplementedException(); //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod; //genlist = new MethodParamList(environment, gmethod); } } else { throw new NotImplementedException(); } var typesys = GetType(typename); if (typesys == null) { typename = typename.Replace("0...", ""); typesys = GetType(typename); } if (typesys == null) { throw new Exception("type can't find:" + typename); } IMethod _method = null; if (genlist != null) { _method = typesys.GetMethodT(methodname, genlist, list); } else { _method = typesys.GetMethod(methodname, list); } methodCache[token.GetHashCode()] = _method; return(_method); }
public static long GetToken(Mono.Cecil.MethodReference method) => (long)((ulong)method.MetadataToken.ToInt32()) << 32 | ( (uint)((method.Module.Name.GetHashCode() << 5) + method.Module.Name.GetHashCode()) ^ (uint)method.Module.Assembly.FullName.GetHashCode() );
public static Instruction CallVirtual(Mono.Cecil.MethodReference method) { return(Instruction.Create(OpCodes.Callvirt, method)); }