private AntsCode _Convert1by1(AntShares.VM.OpCode code, OpCode src, AntsMethod to, byte[] data = null) { AntsCode _code = new AntsCode(); int startaddr = addr; _code.addr = addr; if (src != null) { addrconv[src.addr] = addr; _code.debugcode = src.debugcode; _code.debugline = src.debugline; _code.debugILAddr = src.addr; _code.debugILCode = src.code.ToString(); } addr++; _code.code = code; if (data != null) { _code.bytes = data; addr += _code.bytes.Length; } to.body_Codes[startaddr] = _code; return(_code); }
private void _insertBeginCode(ILMethod from, AntsMethod to) { ////压入深度临时栈 //_Insert1(AntShares.VM.OpCode.DEPTH, "record depth.", to); //_Insert1(AntShares.VM.OpCode.TOALTSTACK, "", to); ////初始化临时槽位位置 //foreach (var src in from.body_Variables) //{ // to.body_Variables.Add(new ILParam(src.name, src.type)); // _InsertPush(0, "body_Variables init", to); //} //新玩法,用一个数组,应该能减少指令数量 _InsertPush(from.paramtypes.Count + from.body_Variables.Count, "begincode", to); _Insert1(AntShares.VM.OpCode.NEWARRAY, "", to); _Insert1(AntShares.VM.OpCode.TOALTSTACK, "", to); //移动参数槽位 for (var i = 0; i < from.paramtypes.Count; i++) { //getarray _Insert1(AntShares.VM.OpCode.FROMALTSTACK, "set param:" + i, to); _Insert1(AntShares.VM.OpCode.DUP, null, to); _Insert1(AntShares.VM.OpCode.TOALTSTACK, null, to); _InsertPush(i, "", to); //Array pos _InsertPush(2, "", to); //Array item _Insert1(AntShares.VM.OpCode.ROLL, null, to); _Insert1(AntShares.VM.OpCode.SETITEM, null, to); } }
private void _ConvertLdArg(OpCode src, AntsMethod to, int pos) { //push d var c = _Convert1by1(AntShares.VM.OpCode.DEPTH, src, to); if (c.debugcode == null) { c.debugcode = "from LdArg -> 5 code"; c.debugline = 0; } //push n _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(to.paramtypes.Count - 1 - pos)); //d+n _Convert1by1(AntShares.VM.OpCode.ADD, null, to); //push olddepth _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //(d+n)-olddepth _Convert1by1(AntShares.VM.OpCode.SUB, null, to); //pick _Convert1by1(AntShares.VM.OpCode.PICK, null, to); }
private void _ConvertLdLoc(OpCode src, AntsMethod to, int pos) { //push d var c = _Convert1by1(AntShares.VM.OpCode.DEPTH, src, to); if (c.debugcode == null) { c.debugcode = "from LdLoc -> 5 code"; c.debugline = 0; } //push n _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(pos)); //d-n-1 _Convert1by1(AntShares.VM.OpCode.SUB, null, to); _Convert1by1(AntShares.VM.OpCode.DEC, null, to); //push olddepth _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //(d-n-1)-olddepth _Convert1by1(AntShares.VM.OpCode.SUB, null, to); //pick _Convert1by1(AntShares.VM.OpCode.PICK, null, to); }
private int _ConvertInitObj(OpCode src, AntsMethod to) { var type = (src.tokenUnknown as Mono.Cecil.TypeReference).Resolve(); _Convert1by1(AntShares.VM.OpCode.NOP, src, to); //空白 _ConvertPush(type.Fields.Count, null, to); //插入个数量 _Insert1(VM.OpCode.NEWARRAY, null, to); //然後要將計算棧上的第一個值,寫入第二個值對應的pos _Convert1by1(AntShares.VM.OpCode.SWAP, null, to);//replace n to top //push d _Convert1by1(AntShares.VM.OpCode.DEPTH, null, to); _Convert1by1(AntShares.VM.OpCode.DEC, null, to); //d 多了一位,剪掉 _Convert1by1(AntShares.VM.OpCode.SWAP, null, to); //把n拿上來 //push n //_ConvertPush(pos, null, to);有n了 //d-n-1 _Convert1by1(AntShares.VM.OpCode.SUB, null, to); _Convert1by1(AntShares.VM.OpCode.DEC, null, to); //push olddepth _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //(d-n-1)-olddepth _Convert1by1(AntShares.VM.OpCode.SUB, null, to); //swap d-n-1 and top _Convert1by1(AntShares.VM.OpCode.XSWAP, null, to); //drop top _Convert1by1(AntShares.VM.OpCode.DROP, null, to); return(0); }
private AntsCode _InsertPush(byte[] data, string comment, AntsMethod to) { if (data.Length == 0) { return(_Insert1(VM.OpCode.PUSH0, comment, to)); } if (data.Length <= 75) { return(_Insert1((VM.OpCode)data.Length, comment, to, data)); } byte prefixLen; VM.OpCode code; if (data.Length <= byte.MaxValue) { prefixLen = sizeof(byte); code = VM.OpCode.PUSHDATA1; } else if (data.Length <= ushort.MaxValue) { prefixLen = sizeof(ushort); code = VM.OpCode.PUSHDATA2; } else { prefixLen = sizeof(uint); code = VM.OpCode.PUSHDATA4; } byte[] bytes = new byte[data.Length + prefixLen]; Buffer.BlockCopy(BitConverter.GetBytes(data.Length), 0, bytes, 0, prefixLen); Buffer.BlockCopy(data, 0, bytes, prefixLen, data.Length); return(_Insert1(code, comment, to, bytes)); }
private void _ConvertLdArg(OpCode src, AntsMethod to, int pos) { //get array _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, src, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //get i _ConvertPush(pos, null, to);//翻转取参数顺序 _Convert1by1(AntShares.VM.OpCode.PICKITEM, null, to); ////push d //var c = _Convert1by1(AntShares.VM.OpCode.DEPTH, src, to); //if (c.debugcode == null) //{ // c.debugcode = "from LdArg -> 5 code"; // c.debugline = 0; //} ////push n //_ConvertPush(pos, null, to);//翻转取参数顺序 ////_Convert1by1(AntShares.VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(to.paramtypes.Count - 1 - pos)); ////d+n //_Convert1by1(AntShares.VM.OpCode.ADD, null, to); ////push olddepth //_Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); //_Convert1by1(AntShares.VM.OpCode.DUP, null, to); //_Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); ////(d+n)-olddepth //_Convert1by1(AntShares.VM.OpCode.SUB, null, to); ////pick //_Convert1by1(AntShares.VM.OpCode.PICK, null, to); }
private void _ConvertStLoc(OpCode src, AntsMethod to, int pos) { //push d var c = _Convert1by1(AntShares.VM.OpCode.DEPTH, src, to); if (c.debugcode == null) { c.debugcode = "from StLoc -> 6 code"; c.debugline = 0; } //_Convert1by1(AntShares.VM.ScriptOp.OP_DUP, src, to); //push n _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(pos)); //d-n-1 _Convert1by1(AntShares.VM.OpCode.SUB, null, to); _Convert1by1(AntShares.VM.OpCode.DEC, null, to); //push olddepth _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //(d-n-1)-olddepth _Convert1by1(AntShares.VM.OpCode.SUB, null, to); //swap d-n-1 and top _Convert1by1(AntShares.VM.OpCode.XSWAP, null, to); //drop top _Convert1by1(AntShares.VM.OpCode.DROP, null, to); }
private int _ConvertInitObj(OpCode src, AntsMethod to) { var type = (src.tokenUnknown as Mono.Cecil.TypeReference).Resolve(); _Convert1by1(AntShares.VM.OpCode.NOP, src, to); //空白 _ConvertPush(type.Fields.Count, null, to); //插入个数量 if (type.IsValueType) { _Insert1(VM.OpCode.NEWSTRUCT, null, to); } else { _Insert1(VM.OpCode.NEWARRAY, null, to); } //now stack a index, a value //getarray _Insert1(VM.OpCode.FROMALTSTACK, null, to); _Insert1(VM.OpCode.DUP, null, to); _Insert1(VM.OpCode.TOALTSTACK, null, to); _InsertPush(2, "", to);//move item _Insert1(VM.OpCode.ROLL, null, to); _InsertPush(2, "", to);//move value _Insert1(VM.OpCode.ROLL, null, to); _Insert1(VM.OpCode.SETITEM, null, to); ////然後要將計算棧上的第一個值,寫入第二個值對應的pos //_Convert1by1(AntShares.VM.OpCode.SWAP, null, to);//replace n to top ////push d //_Convert1by1(AntShares.VM.OpCode.DEPTH, null, to); //_Convert1by1(AntShares.VM.OpCode.DEC, null, to);//d 多了一位,剪掉 //_Convert1by1(AntShares.VM.OpCode.SWAP, null, to);//把n拿上來 ////push n ////_ConvertPush(pos, null, to);有n了 ////d-n-1 //_Convert1by1(AntShares.VM.OpCode.SUB, null, to); //_Convert1by1(AntShares.VM.OpCode.DEC, null, to); ////push olddepth //_Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); //_Convert1by1(AntShares.VM.OpCode.DUP, null, to); //_Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); ////(d-n-1)-olddepth //_Convert1by1(AntShares.VM.OpCode.SUB, null, to); ////swap d-n-1 and top //_Convert1by1(AntShares.VM.OpCode.XSWAP, null, to); ////drop top //_Convert1by1(AntShares.VM.OpCode.DROP, null, to); return(0); }
private void _ConvertLdLoc(ILMethod method, OpCode src, AntsMethod to, int pos) { //get array _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, src, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //get i _ConvertPush(pos + method.paramtypes.Count, null, to);//翻转取参数顺序 _Convert1by1(AntShares.VM.OpCode.PICKITEM, null, to); }
private void _ConvertLdLocA(ILMethod method, OpCode src, AntsMethod to, int pos) {//这有两种情况,我们需要先判断这个引用地址是拿出来干嘛的 var n1 = method.body_Codes[method.GetNextCodeAddr(src.addr)]; if (n1.code == CodeEx.Initobj)//初始化结构体,必须给引用地址 { _ConvertPush(pos + method.paramtypes.Count, src, to); } else { _ConvertLdLoc(method, src, to, pos); } }
private void _insertBeginCode(ILMethod from, AntsMethod to) { //压入深度临时栈 _Insert1(AntShares.VM.OpCode.DEPTH, "record depth.", to); _Insert1(AntShares.VM.OpCode.TOALTSTACK, "", to); //初始化临时槽位位置 foreach (var src in from.body_Variables) { to.body_Variables.Add(new ILParam(src.name, src.type)); _InsertPush(0, "body_Variables init", to); } }
private int _ConvertNewArr(ILMethod method, OpCode src, AntsMethod to) { var type = src.tokenType; if (type != "System.Byte") { _Convert1by1(VM.OpCode.NEWARRAY, src, to); return(0); //this.logger.Log("_ConvertNewArr::not support type " + type + " for array."); } else { var code = to.body_Codes.Last().Value; //we need a number if (code.code > AntShares.VM.OpCode.PUSH16) { this.logger.Log("_ConvertNewArr::not support var lens for array."); return(0); } var number = getNumber(code); //移除上一条指令 to.body_Codes.Remove(code.addr); this.addr--; if (code.bytes != null) { this.addr -= code.bytes.Length; } int n = method.GetNextCodeAddr(src.addr); int n2 = method.GetNextCodeAddr(n); int n3 = method.GetNextCodeAddr(n2); if (method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call) {//這是在初始化數組 var data = method.body_Codes[n2].tokenUnknown as byte[]; this._ConvertPush(data, src, to); return(3); } else { this._ConvertPush(new byte[number], src, to); } } return(0); }
private int _ConvertLdfld(OpCode src, AntsMethod to) { var field = (src.tokenUnknown as Mono.Cecil.FieldReference).Resolve(); var type = field.DeclaringType; var id = type.Fields.IndexOf(field); if (id < 0) { throw new Exception("impossible."); } _ConvertPush(id, src, to); _Convert1by1(AntShares.VM.OpCode.PICKITEM, null, to);//修改值 return(0); }
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); } } }
private AntsCode _InsertPush(int i, string comment, AntsMethod to) { if (i == 0) { return(_Insert1(VM.OpCode.PUSH0, comment, to)); } if (i == -1) { return(_Insert1(VM.OpCode.PUSHM1, comment, to)); } if (i > 0 && i <= 16) { return(_Insert1((VM.OpCode)(byte) i + 0x50, comment, to)); } return(_InsertPush(((BigInteger)i).ToByteArray(), comment, to)); }
private AntsCode _ConvertPush(long i, OpCode src, AntsMethod to) { if (i == 0) { return(_Convert1by1(VM.OpCode.PUSH0, src, to)); } if (i == -1) { return(_Convert1by1(VM.OpCode.PUSHM1, src, to)); } if (i > 0 && i <= 16) { return(_Convert1by1((VM.OpCode)(byte) i + 0x50, src, to)); } return(_ConvertPush(((BigInteger)i).ToByteArray(), src, to)); }
private int _ConvertNewObj(OpCode src, AntsMethod to) { var type = (src.tokenUnknown as Mono.Cecil.MethodReference).Resolve(); _Convert1by1(AntShares.VM.OpCode.NOP, src, to); //空白 _ConvertPush(type.DeclaringType.Fields.Count, null, to); //插入个数量 if (type.DeclaringType.IsValueType) { _Insert1(VM.OpCode.NEWSTRUCT, null, to); } else { _Insert1(VM.OpCode.NEWARRAY, null, to); } return(0); }
private void ConvertAddrInMethod(AntsMethod to) { foreach (var c in to.body_Codes.Values) { if (c.needfix && c.code != AntShares.VM.OpCode.CALL //call 要做函数间的转换 ) { var addr = addrconv[c.srcaddr]; Int16 addroff = (Int16)(addr - c.addr); c.bytes = BitConverter.GetBytes(addroff); c.needfix = false; } } }
private void _ConvertStLoc(ILMethod method, OpCode src, AntsMethod to, int pos) { //get array _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, src, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //get i _ConvertPush(pos + method.paramtypes.Count, null, to);//翻转取参数顺序 //getitem _ConvertPush(2, null, to); _Convert1by1(AntShares.VM.OpCode.ROLL, null, to); _Convert1by1(AntShares.VM.OpCode.SETITEM, null, to); //_Convert1by1(AntShares.VM.OpCode.CLONESTRUCTONLY, src, to); ////push d //var c = _Convert1by1(AntShares.VM.OpCode.DEPTH, null, to); //if (c.debugcode == null) //{ // c.debugcode = "from StLoc -> 6 code"; // c.debugline = 0; //} ////_Convert1by1(AntShares.VM.ScriptOp.OP_DUP, src, to); ////push n //_ConvertPush(pos, null, to); ////d-n-1 //_Convert1by1(AntShares.VM.OpCode.SUB, null, to); //_Convert1by1(AntShares.VM.OpCode.DEC, null, to); ////push olddepth //_Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); //_Convert1by1(AntShares.VM.OpCode.DUP, null, to); //_Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); ////(d-n-1)-olddepth //_Convert1by1(AntShares.VM.OpCode.SUB, null, to); ////swap d-n-1 and top //_Convert1by1(AntShares.VM.OpCode.XSWAP, null, to); ////drop top //_Convert1by1(AntShares.VM.OpCode.DROP, null, to); }
private void _insertEndCode(ILMethod from, AntsMethod to, OpCode src) { ////占位不谢 _Convert1by1(AntShares.VM.OpCode.NOP, src, to); ////移除临时槽位 ////drop body_Variables //for (var i = 0; i < from.body_Variables.Count; i++) //{ // _Insert1(AntShares.VM.OpCode.DEPTH, "body_Variables drop", to, null); // _Insert1(AntShares.VM.OpCode.DEC, null, to, null); // //push olddepth // _Insert1(AntShares.VM.OpCode.FROMALTSTACK, null, to); // _Insert1(AntShares.VM.OpCode.DUP, null, to); // _Insert1(AntShares.VM.OpCode.TOALTSTACK, null, to); // //(d-1)-olddepth // _Insert1(AntShares.VM.OpCode.SUB, null, to); // _Insert1(AntShares.VM.OpCode.XDROP, null, to, null); //} ////移除参数槽位 //for (var i = 0; i < from.paramtypes.Count; i++) //{ // //d // _Insert1(AntShares.VM.OpCode.DEPTH, "param drop", to, null); // //push olddepth // _Insert1(AntShares.VM.OpCode.FROMALTSTACK, null, to); // _Insert1(AntShares.VM.OpCode.DUP, null, to); // _Insert1(AntShares.VM.OpCode.DEC, null, to);//深度-1 // _Insert1(AntShares.VM.OpCode.TOALTSTACK, null, to); // //(d)-olddepth // _Insert1(AntShares.VM.OpCode.SUB, null, to); // _Insert1(AntShares.VM.OpCode.XDROP, null, to, null); //} //移除深度临时栈 _Insert1(AntShares.VM.OpCode.FROMALTSTACK, "endcode", to); _Insert1(AntShares.VM.OpCode.DROP, "", to); }
private int _ConvertStfld(ILMethod method, OpCode src, AntsMethod to) { var field = (src.tokenUnknown as Mono.Cecil.FieldReference).Resolve(); var type = field.DeclaringType; var id = type.Fields.IndexOf(field); if (id < 0) { throw new Exception("impossible."); } //_Convert1by1(AntShares.VM.OpCode.CLONESTRUCTONLY, src, to); _ConvertPush(id, null, to); //index _Convert1by1(AntShares.VM.OpCode.SWAP, null, to); //把item 拿上來 _Convert1by1(AntShares.VM.OpCode.SETITEM, null, to); //修改值 //item //index //array return(0); }
private int _ConvertStfld(OpCode src, AntsMethod to) { var field = (src.tokenUnknown as Mono.Cecil.FieldReference).Resolve(); var type = field.DeclaringType; var id = type.Fields.IndexOf(field); if (id < 0) { throw new Exception("impossible."); } _Convert1by1(AntShares.VM.OpCode.NOP, src, to); //空白 _Convert1by1(AntShares.VM.OpCode.SWAP, null, to); //把n拿上來 n 和 item //push d _Convert1by1(AntShares.VM.OpCode.DEPTH, src, to); _Convert1by1(AntShares.VM.OpCode.DEC, null, to); //d 多了一位,剪掉 _Convert1by1(AntShares.VM.OpCode.SWAP, null, to); //把n拿上來 //push n //_ConvertPush(pos, null, to);有n了 //d-n-1 _Convert1by1(AntShares.VM.OpCode.SUB, null, to); _Convert1by1(AntShares.VM.OpCode.DEC, null, to); //push olddepth _Convert1by1(AntShares.VM.OpCode.FROMALTSTACK, null, to); _Convert1by1(AntShares.VM.OpCode.DUP, null, to); _Convert1by1(AntShares.VM.OpCode.TOALTSTACK, null, to); //(d-n-1)-olddepth _Convert1by1(AntShares.VM.OpCode.SUB, null, to); //pick _Convert1by1(AntShares.VM.OpCode.PICK, null, to); _Convert1by1(AntShares.VM.OpCode.SWAP, null, to); //把item 拿上來 _ConvertPush(id, null, to); //index _Convert1by1(AntShares.VM.OpCode.SWAP, null, to); //把item 拿上來 _Convert1by1(AntShares.VM.OpCode.SETITEM, null, to); //修改值 //item //index //array return(0); }
private AntsCode _Insert1(AntShares.VM.OpCode code, string comment, AntsMethod to, byte[] data = null) { AntsCode _code = new AntsCode(); int startaddr = addr; _code.addr = addr; { _code.debugcode = comment; _code.debugline = 0; } addr++; _code.code = code; if (data != null) { _code.bytes = data; addr += _code.bytes.Length; } to.body_Codes[startaddr] = _code; return(_code); }
private void ConvertMethod(ILMethod from, AntsMethod to) { to.returntype = from.returntype; foreach (var src in from.paramtypes) { to.paramtypes.Add(new ILParam(src.name, src.type)); } this.addr = 0; this.addrconv.Clear(); //插入一个记录深度的代码,再往前的是参数 _insertBeginCode(from, to); int skipcount = 0; foreach (var src in from.body_Codes.Values) { if (skipcount > 0) { skipcount--; } else { //在return之前加入清理参数代码 if (src.code == CodeEx.Ret)//before return { _insertEndCode(from, to, src); } skipcount = ConvertCode(from, src, to); } } ConvertAddrInMethod(to); }
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; if (IsOpCall(refs, 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(refs, out callname)) { calltype = 3; } else if (IsAppCall(refs, 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(AntShares.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(AntShares.VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") { _Convert1by1(AntShares.VM.OpCode.EQUAL, src, to); return(0); } _Convert1by1(AntShares.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(AntShares.VM.OpCode.EQUAL, "", to); return(0); } _Convert1by1(VM.OpCode.INVERT, src, to); _Insert1(AntShares.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(AntShares.VM.OpCode.ADD, src, to); return(0); } _Convert1by1(AntShares.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(AntShares.VM.OpCode.SUB, src, to); return(0); } _Convert1by1(AntShares.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(AntShares.VM.OpCode.MUL, src, to); return(0); } _Convert1by1(AntShares.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(AntShares.VM.OpCode.DIV, src, to); return(0); } _Convert1by1(AntShares.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(AntShares.VM.OpCode.MOD, src, to); return(0); } _Convert1by1(AntShares.VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(AntShares.VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(AntShares.VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(AntShares.VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(AntShares.VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(AntShares.VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(AntShares.VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(AntShares.VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(AntShares.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 (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); } else if (calltype == 4) { _Convert1by1(AntShares.VM.OpCode.APPCALL, null, to, callhash); } return(0); }
private void _ConvertLdLocA(OpCode src, AntsMethod to, int pos) { _ConvertPush(pos, src, to); }
private int ConvertCode(ILMethod method, OpCode src, AntsMethod to) { int skipcount = 0; switch (src.code) { case CodeEx.Nop: _Convert1by1(AntShares.VM.OpCode.NOP, src, to); break; case CodeEx.Ret: //return 在外面特殊处理了 _Insert1(AntShares.VM.OpCode.RET, null, to); break; case CodeEx.Pop: _Convert1by1(AntShares.VM.OpCode.DROP, src, to); break; case CodeEx.Ldc_I4: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(src.tokenI32)); break; case CodeEx.Ldc_I4_0: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(0)); break; case CodeEx.Ldc_I4_1: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(1)); break; case CodeEx.Ldc_I4_2: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(2)); break; case CodeEx.Ldc_I4_3: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(3)); break; case CodeEx.Ldc_I4_4: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(4)); break; case CodeEx.Ldc_I4_5: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(5)); break; case CodeEx.Ldc_I4_6: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(6)); break; case CodeEx.Ldc_I4_7: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(7)); break; case CodeEx.Ldc_I4_8: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(1)); break; case CodeEx.Ldc_I4_S: _Convert1by1(AntShares.VM.OpCode.PUSHDATA1, src, to, int2Pushdata1bytes(src.tokenI32)); break; case CodeEx.Stloc_0: _ConvertStLoc(src, to, 0); break; case CodeEx.Stloc_1: _ConvertStLoc(src, to, 1); break; case CodeEx.Stloc_2: _ConvertStLoc(src, to, 2); break; case CodeEx.Stloc_3: _ConvertStLoc(src, to, 3); break; case CodeEx.Stloc_S: _ConvertStLoc(src, to, src.tokenI32); break; case CodeEx.Ldloc_0: _ConvertLdLoc(src, to, 0); break; case CodeEx.Ldloc_1: _ConvertLdLoc(src, to, 1); break; case CodeEx.Ldloc_2: _ConvertLdLoc(src, to, 2); break; case CodeEx.Ldloc_3: _ConvertLdLoc(src, to, 3); break; case CodeEx.Ldloc_S: _ConvertLdLoc(src, to, src.tokenI32); break; case CodeEx.Ldarg_0: _ConvertLdArg(src, to, 0); break; case CodeEx.Ldarg_1: _ConvertLdArg(src, to, 1); break; case CodeEx.Ldarg_2: _ConvertLdArg(src, to, 2); break; case CodeEx.Ldarg_3: _ConvertLdArg(src, to, 3); break; case CodeEx.Ldarg_S: case CodeEx.Ldarg: _ConvertLdArg(src, to, src.tokenI32); break; //需要地址轉換的情況 case CodeEx.Br_S: case CodeEx.Br: { var code = _Convert1by1(AntShares.VM.OpCode.JMP, src, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Brtrue: case CodeEx.Brtrue_S: { var code = _Convert1by1(AntShares.VM.OpCode.JMPIF, src, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Brfalse: case CodeEx.Brfalse_S: { var code = _Convert1by1(AntShares.VM.OpCode.JMPIFNOT, src, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Blt: case CodeEx.Blt_S: { _Convert1by1(AntShares.VM.OpCode.LT, src, to); var code = _Convert1by1(AntShares.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Ble: case CodeEx.Ble_S: { _Convert1by1(AntShares.VM.OpCode.LTE, src, to); var code = _Convert1by1(AntShares.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Bgt: case CodeEx.Bgt_S: { _Convert1by1(AntShares.VM.OpCode.GT, src, to); var code = _Convert1by1(AntShares.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Bge: case CodeEx.Bge_S: { _Convert1by1(AntShares.VM.OpCode.GTE, src, to); var code = _Convert1by1(AntShares.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; //math case CodeEx.Add: case CodeEx.Add_Ovf: case CodeEx.Add_Ovf_Un: _Convert1by1(AntShares.VM.OpCode.ADD, src, to); break; case CodeEx.Sub: case CodeEx.Sub_Ovf: case CodeEx.Sub_Ovf_Un: _Convert1by1(AntShares.VM.OpCode.SUB, src, to); break; case CodeEx.Mul: case CodeEx.Mul_Ovf: case CodeEx.Mul_Ovf_Un: _Convert1by1(AntShares.VM.OpCode.MUL, src, to); break; case CodeEx.Div: case CodeEx.Div_Un: _Convert1by1(AntShares.VM.OpCode.DIV, src, to); break; case CodeEx.Rem: case CodeEx.Rem_Un: _Convert1by1(AntShares.VM.OpCode.MOD, src, to); break; //logic case CodeEx.Clt: case CodeEx.Clt_Un: _Convert1by1(AntShares.VM.OpCode.LT, src, to); break; case CodeEx.Cgt: case CodeEx.Cgt_Un: _Convert1by1(AntShares.VM.OpCode.GT, src, to); break; case CodeEx.Ceq: _Convert1by1(AntShares.VM.OpCode.NUMEQUAL, src, to); break; //call case CodeEx.Call: case CodeEx.Callvirt: _ConvertCall(src, to); break; //用上一个参数作为数量,new 一个数组 case CodeEx.Newarr: skipcount = _ConvertNewArr(method, src, to); break; //array case CodeEx.Ldelem_Ref: _Convert1by1(AntShares.VM.OpCode.PICKITEM, src, to); break; case CodeEx.Ldlen: _Convert1by1(AntShares.VM.OpCode.ARRAYSIZE, src, to); break; case CodeEx.Castclass: break; case CodeEx.Box: case CodeEx.Unbox: case CodeEx.Conv_I: case CodeEx.Conv_I1: case CodeEx.Conv_I2: case CodeEx.Conv_I4: case CodeEx.Conv_I8: case CodeEx.Conv_U: case CodeEx.Conv_U1: case CodeEx.Conv_U2: case CodeEx.Conv_U4: case CodeEx.Conv_U8: break; default: throw new Exception("not support code" + src.code); //logger.Log("not support code" + src.code); break; } return(skipcount); }
public AntsModule Convert(ILModule _in) { //logger.Log("beginConvert."); this.outModule = new AntsModule(this.logger); foreach (var t in _in.mapType) { if (t.Key[0] == '<') { continue; //系统的,不要 } if (t.Key.Contains("_API_")) { continue; //api的,不要 } foreach (var m in t.Value.methods) { if (m.Value.method == null) { continue; } AntsMethod nm = new AntsMethod(); nm.name = m.Value.method.FullName; this.methodLink[m.Value] = nm; outModule.mapMethods[nm.name] = nm; } } foreach (var t in _in.mapType) { if (t.Key[0] == '<') { continue; //系统的,不要 } if (t.Key.Contains("_API_")) { continue; //api的,不要 } foreach (var m in t.Value.methods) { if (m.Value.method == null) { continue; } var nm = this.methodLink[m.Value]; //try { this.ConvertMethod(m.Value, nm); } //catch (Exception err) //{ // logger.Log("error:" + err.Message); //} } } //转换完了,做个link,全部拼到一起 string mainmethod = ""; foreach (var key in outModule.mapMethods.Keys) { if (key.Contains("::Verify(")) { var m = outModule.mapMethods[key]; foreach (var l in this.methodLink) { if (l.Value == m) { var srcm = l.Key.method; if (srcm.DeclaringType.BaseType.Name == "VerificationCode" && srcm.ReturnType.FullName == "System.Boolean") { logger.Log("找到函数入口点:" + key); if (mainmethod != "") { throw new Exception("拥有多个函数入口点,请检查"); } mainmethod = key; } } } } if (key.Contains("::Main(")) { var m = outModule.mapMethods[key]; foreach (var l in this.methodLink) { if (l.Value == m) { var srcm = l.Key.method; if (srcm.DeclaringType.BaseType.Name == "FunctionCode") { logger.Log("找到函数入口点:" + key); if (mainmethod != "") { throw new Exception("拥有多个函数入口点,请检查"); } mainmethod = key; } } } } } if (mainmethod == "") { throw new Exception("找不到入口函数,请检查"); } //得找到第一个函数 this.LinkCode(mainmethod); //this.findFirstFunc();//得找到第一个函数 //然后给每个method 分配一个func addr //还需要对所有的call 做一次地址转换 //this.outModule.Build(); return(outModule); }
private int _ConvertNewArr(ILMethod method, OpCode src, AntsMethod to) { var type = src.tokenType; if (type != "System.Byte") { _Convert1by1(VM.OpCode.NEWARRAY, src, to); int n = method.GetNextCodeAddr(src.addr); int n2 = method.GetNextCodeAddr(n); int n3 = method.GetNextCodeAddr(n2); if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call) {//這是在初始化數組 var data = method.body_Codes[n2].tokenUnknown as byte[]; if (type == "System.Char") { for (var i = 0; i < data.Length; i += 2) { char info = BitConverter.ToChar(data, i); _Convert1by1(VM.OpCode.DUP, null, to); _ConvertPush(i / 2, null, to); _ConvertPush(info, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); } return(3); } throw new Exception("not support this type's init array."); } return(0); //this.logger.Log("_ConvertNewArr::not support type " + type + " for array."); } else { var code = to.body_Codes.Last().Value; //we need a number if (code.code > AntShares.VM.OpCode.PUSH16) { throw new Exception("_ConvertNewArr::not support var lens for new byte[?]."); } var number = getNumber(code); //移除上一条指令 to.body_Codes.Remove(code.addr); this.addr--; if (code.bytes != null) { this.addr -= code.bytes.Length; } int n = method.GetNextCodeAddr(src.addr); int n2 = method.GetNextCodeAddr(n); int n3 = method.GetNextCodeAddr(n2); if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call) {//這是在初始化數組 var data = method.body_Codes[n2].tokenUnknown as byte[]; this._ConvertPush(data, src, to); return(3); } else { this._ConvertPush(new byte[number], src, to); } } return(0); }