private void _insertBeginCode(ILMethod from, AntsMethod to) { ////压入深度临时栈 //_Insert1(VM.OpCode.DEPTH, "record depth.", to); //_Insert1(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(VM.OpCode.NEWARRAY, "", to); _Insert1(VM.OpCode.TOALTSTACK, "", to); //移动参数槽位 for (var i = 0; i < from.paramtypes.Count; i++) { //getarray _Insert1(VM.OpCode.FROMALTSTACK, "set param:" + i, to); _Insert1(VM.OpCode.DUP, null, to); _Insert1(VM.OpCode.TOALTSTACK, null, to); _InsertPush(i, "", to); //Array pos _InsertPush(2, "", to); //Array item _Insert1(VM.OpCode.ROLL, null, to); _Insert1(VM.OpCode.SETITEM, null, to); } }
private AntsCode _Convert1by1(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 _ConvertLdLocA(OpCode src, AntsMethod to, int pos) //{ // _ConvertPush(pos, src, to); //} private void _ConvertLdArg(OpCode src, AntsMethod to, int pos) { //push d var c = _Convert1by1(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(VM.OpCode.PUSHDATA1, null, to, int2Pushdata1bytes(to.paramtypes.Count - 1 - pos)); //d+n _Convert1by1(VM.OpCode.ADD, null, to); //push olddepth _Convert1by1(VM.OpCode.FROMALTSTACK, null, to); _Convert1by1(VM.OpCode.DUP, null, to); _Convert1by1(VM.OpCode.TOALTSTACK, null, to); //(d+n)-olddepth _Convert1by1(VM.OpCode.SUB, null, to); //pick _Convert1by1(VM.OpCode.PICK, null, to); }
private void _insertBeginCode(JavaMethod from, AntsMethod to) { //压入槽位栈 _InsertPush(from.MaxVariableIndex + 1, "begincode", to); _Insert1(VM.OpCode.NEWARRAY, "", to); _Insert1(VM.OpCode.TOALTSTACK, "", to); for (var i = 0; i < from.paramTypes.Count; i++) { int pos = 0; if (from.method.IsStatic) { pos = from.argTable[i]; } else {//非静态0号是this pos = from.argTable[i + 1]; } _Insert1(VM.OpCode.DUPFROMALTSTACK, "init param:" + i, to); _InsertPush(pos, "", to); _InsertPush(2, "", to); _Insert1(VM.OpCode.ROLL, "", to); _Insert1(VM.OpCode.SETITEM, "", to); } ////初始化临时槽位位置 //to.addVariablesCount = from.addLocal_VariablesCount; //for (var i = 0; i < from.addLocal_VariablesCount; i++) //{ // //to.body_Variables.Add(new JavaParam(src.name, src.type)); // _InsertPush(0, "body_Variables init", to); //} }
private int _ConvertNew(JavaMethod method, OpCode src, AntsMethod to) { var c = method.DeclaringType.classfile.constantpool[src.arg1] as javaloader.ClassFile.ConstantPoolItemClass; if (c.Name == "java.lang.StringBuilder") { _ConvertPush(1, src, to); _Insert1(VM.OpCode.NEWARRAY, "", to); } else if (c.Name == "java.math.BigInteger") { var next = method.GetNextCodeAddr(src.addr); if (method.body_Codes[next].code == javaloader.NormalizedByteCode.__dup) { return(1); } else { return(0); } } else { throw new Exception("new not supported type." + c.Name); } return(0); }
private void ConvertAddrInMethod(AntsMethod to) { foreach (var c in to.body_Codes.Values) { if (c.needfix && c.code != VM.OpCode.CALL //call 要做函数间的转换 ) { if (c.code == VM.OpCode.SWITCH) { for (var i = 0; i < c.srcaddrswitch.Length; i++) { var addr = addrconv[c.srcaddrswitch[i]]; Int16 addroff = (Int16)(addr - c.addr); var bs = BitConverter.GetBytes(addroff); c.bytes[i * 2 + 2] = bs[0]; c.bytes[i * 2 + 2 + 1] = bs[1]; c.needfix = false; } } else { var addr = addrconv[c.srcaddr]; Int16 addroff = (Int16)(addr - c.addr); c.bytes = BitConverter.GetBytes(addroff); c.needfix = false; } } } }
private int _ConvertNewObj(OpCode src, AntsMethod to) { var _type = (src.tokenUnknown as Mono.Cecil.MethodReference); if (_type.FullName == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { return(0);//donothing; } else if (_type.DeclaringType.FullName.Contains("Exception")) { _Convert1by1(VM.OpCode.NOP, src, to);//空白 var pcount = _type.Parameters.Count; for (var i = 0; i < pcount; i++) { _Insert1(VM.OpCode.DROP, "", to); } return(0); } var type = _type.Resolve(); _Convert1by1(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 ConvertMethod(ILMethod from, AntsMethod to) { 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 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 string CreateJmpMain(Dictionary <byte, string> entries) { AntsMethod main = new AntsMethod(); main.name = "System.Void @JmpMain()"; main.displayName = "Main"; main.isPublic = true; main.returntype = "System.Void"; var bytes = Encoding.UTF8.GetBytes("Neo.Runtime.GetTrigger"); byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); this.addr = 0; this.addrconv.Clear(); _Convert1by1(VM.OpCode.SYSCALL, null, main, outbytes); //_Convert1by1(VM.OpCode.TOALTSTACK, null, main); //for //ifjmp //ifjmp //throw //for //jmp //jmp //jmp foreach (var key in entries.Keys) { _Convert1by1(VM.OpCode.DUP, null, main); _ConvertPush(key, null, main); _Convert1by1(VM.OpCode.NUMEQUAL, null, main); var jmp = _Convert1by1(VM.OpCode.JMPIF, null, main, new byte[2]); jmp.needfix = true; jmp.srcaddr = key; } _Convert1by1(VM.OpCode.THROW, null, main); foreach (var key in entries.Keys) { var callbegin = _Convert1by1(VM.OpCode.DROP, null, main); this.addrconv[key] = callbegin.addr; var name = entries[key]; var jmp = _Convert1by1(VM.OpCode.JMP, null, main, new byte[2]); jmp.needfixfunc = true; jmp.srcfunc = name; } this.ConvertAddrInMethod(main); outModule.mapMethods[main.name] = main; return(main.name); }
private int _ConvertInitObj(OpCode src, AntsMethod to) { var type = (src.tokenUnknown as Mono.Cecil.TypeReference).Resolve(); _Convert1by1(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(VM.OpCode.SWAP, null, to);//replace n to top ////push d //_Convert1by1(VM.OpCode.DEPTH, null, to); //_Convert1by1(VM.OpCode.DEC, null, to);//d 多了一位,剪掉 //_Convert1by1(VM.OpCode.SWAP, null, to);//把n拿上來 ////push n ////_ConvertPush(pos, null, to);有n了 ////d-n-1 //_Convert1by1(VM.OpCode.SUB, null, to); //_Convert1by1(VM.OpCode.DEC, null, to); ////push olddepth //_Convert1by1(VM.OpCode.FROMALTSTACK, null, to); //_Convert1by1(VM.OpCode.DUP, null, to); //_Convert1by1(VM.OpCode.TOALTSTACK, null, to); ////(d-n-1)-olddepth //_Convert1by1(VM.OpCode.SUB, null, to); ////swap d-n-1 and top //_Convert1by1(VM.OpCode.XSWAP, null, to); ////drop top //_Convert1by1(VM.OpCode.DROP, null, to); return(0); }
private void _ConvertLdLoc(ILMethod method, OpCode src, AntsMethod to, int pos) { //get array _Convert1by1(VM.OpCode.FROMALTSTACK, src, to); _Convert1by1(VM.OpCode.DUP, null, to); _Convert1by1(VM.OpCode.TOALTSTACK, null, to); //get i _ConvertPush(pos + method.paramtypes.Count, null, to);//翻转取参数顺序 _Convert1by1(VM.OpCode.PICKITEM, null, to); }
private void _ConvertStArg(OpCode src, AntsMethod to, int pos) { //get array _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to); //set i _ConvertPush(pos, null, to);//翻转取参数顺序 //got v to top _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); }
private void ConvertAddrInMethod(AntsMethod to) { foreach (var c in to.body_Codes.Values) { if (c.needfix) { var addr = addrconv[c.srcaddr]; Int16 addroff = (Int16)(addr - c.addr); c.bytes = BitConverter.GetBytes(addroff); c.needfix = false; } } }
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)); _Insert1(AntShares.VM.OpCode.PUSHDATA1, "body_Variables init", to, int2Pushdata1bytes(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(VM.OpCode.PICKITEM, null, to);//修改值 return(0); }
private int _ConvertNew(JavaMethod method, OpCode src, AntsMethod to) { var c = method.DeclaringType.classfile.constantpool[src.arg1] as javaloader.ClassFile.ConstantPoolItemClass; if (c.Name == "java.lang.StringBuilder") { _ConvertPush(1, src, to); _Insert1(VM.OpCode.NEWARRAY, "", to); } else { throw new Exception("new not supported type." + c.Name); } return(0); }
private void _ConvertLdLoc(OpCode src, AntsMethod to, int pos) { //push d var c = _Convert1by1(AntShares.VM.OpCode.DUPFROMALTSTACK, src, to); if (c.debugcode == null) { c.debugcode = "from LdLoc -> 5 code"; c.debugline = 0; } _InsertPush(pos, "", to);//add index //pick _Convert1by1(AntShares.VM.OpCode.PICKITEM, null, to); }
private int _ConvertNewObj(OpCode src, AntsMethod to) { var type = (src.tokenUnknown as Mono.Cecil.MethodReference).Resolve(); _Convert1by1(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 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 void _ConvertStLoc(JavaMethod method, OpCode src, AntsMethod to, int pos) { //push d var c = _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to); if (c.debugcode == null) { c.debugcode = "from StLoc -> 6 code"; c.debugline = 0; } _InsertPush(pos, "", to);//add index _InsertPush(2, "", to); _Insert1(VM.OpCode.ROLL, "", to); _Insert1(VM.OpCode.SETITEM, "", 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 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(VM.OpCode.FROMALTSTACK, src, to); _Convert1by1(VM.OpCode.DUP, null, to); _Convert1by1(VM.OpCode.TOALTSTACK, null, to); //get i _ConvertPush(pos + method.paramtypes.Count, null, to);//翻转取参数顺序 //getitem _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); //_Convert1by1(VM.OpCode.CLONESTRUCTONLY, src, to); ////push d //var c = _Convert1by1(VM.OpCode.DEPTH, null, to); //if (c.debugcode == null) //{ // c.debugcode = "from StLoc -> 6 code"; // c.debugline = 0; //} ////_Convert1by1(VM.ScriptOp.OP_DUP, src, to); ////push n //_ConvertPush(pos, null, to); ////d-n-1 //_Convert1by1(VM.OpCode.SUB, null, to); //_Convert1by1(VM.OpCode.DEC, null, to); ////push olddepth //_Convert1by1(VM.OpCode.FROMALTSTACK, null, to); //_Convert1by1(VM.OpCode.DUP, null, to); //_Convert1by1(VM.OpCode.TOALTSTACK, null, to); ////(d-n-1)-olddepth //_Convert1by1(VM.OpCode.SUB, null, to); ////swap d-n-1 and top //_Convert1by1(VM.OpCode.XSWAP, null, to); ////drop top //_Convert1by1(VM.OpCode.DROP, null, to); }
private void _ConvertLdLocA(ILMethod method, OpCode src, AntsMethod to, int pos) {//这有两种情况,我们需要先判断这个引用地址是拿出来干嘛的 var n1 = method.body_Codes[method.GetNextCodeAddr(src.addr)]; var n2 = method.body_Codes[method.GetNextCodeAddr(n1.addr)]; if (n1.code == CodeEx.Initobj)//初始化结构体,必须给引用地址 { _ConvertPush(pos + method.paramtypes.Count, src, to); } else if (n2.code == CodeEx.Call && n2.tokenMethod.Contains(".ctor")) { _ConvertPush(pos + method.paramtypes.Count, src, to); } else { _ConvertLdLoc(method, src, to, pos); } }
private void _insertEndCode(JavaMethod from, AntsMethod to, OpCode src) { //占位不谢 //_Convert1by1(VM.OpCode.NOP, src, to); ////移除临时槽位 ////drop body_Variables //for (var i = 0; i < from.addLocal_VariablesCount; i++) //{ // _Insert1(VM.OpCode.DEPTH, "body_Variables drop", to, null); // _Insert1(VM.OpCode.DEC, null, to, null); // //push olddepth // _Insert1(VM.OpCode.FROMALTSTACK, null, to); // _Insert1(VM.OpCode.DUP, null, to); // _Insert1(VM.OpCode.TOALTSTACK, null, to); // //(d-1)-olddepth // _Insert1(VM.OpCode.SUB, null, to); // _Insert1(VM.OpCode.XDROP, null, to, null); //} ////移除参数槽位 //for (var i = 0; i < from.paramTypes.Count; i++) //{ // //d // _Insert1(VM.OpCode.DEPTH, "param drop", to, null); // //push olddepth // _Insert1(VM.OpCode.FROMALTSTACK, null, to); // _Insert1(VM.OpCode.DUP, null, to); // _Insert1(VM.OpCode.DEC, null, to);//深度-1 // _Insert1(VM.OpCode.TOALTSTACK, null, to); // //(d)-olddepth // _Insert1(VM.OpCode.SUB, null, to); // _Insert1(VM.OpCode.XDROP, null, to, null); //} //移除深度临时栈 _Insert1(VM.OpCode.FROMALTSTACK, "", to); _Insert1(VM.OpCode.DROP, "", 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, "", 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(VM.OpCode.CLONESTRUCTONLY, src, to); _ConvertPush(id, null, to); //index _Convert1by1(VM.OpCode.SWAP, null, to); //把item 拿上來 _Convert1by1(VM.OpCode.SETITEM, null, to); //修改值 //item //index //array return(0); }
private void ConvertAddrInMethod(AntsMethod to) { foreach (var c in to.body_Codes.Values) { if (c.needfix && c.code != VM.OpCode.CALL //call 要做函数间的转换 ) { //need neo.vm update. //if (c.code == VM.OpCode.SWITCH) //{ // for (var i = 0; i < c.srcaddrswitch.Length; i++) // { // var addr = addrconv[c.srcaddrswitch[i]]; // Int16 addroff = (Int16)(addr - c.addr); // var bs = BitConverter.GetBytes(addroff); // c.bytes[i * 2 + 2] = bs[0]; // c.bytes[i * 2 + 2 + 1] = bs[1]; // c.needfix = false; // } //} //else { var addr = 0; try { addr = addrconv[c.srcaddr]; } catch { throw new Exception("cannot convert addr in: " + to.name + "\r\n"); } Int16 addroff = (Int16)(addr - c.addr); c.bytes = BitConverter.GetBytes(addroff); c.needfix = false; } } } }
private void ConvertMethod(JavaMethod from, AntsMethod to) { convertType.Clear(); to.returntype = from.returnType; for (var i = 0; i < from.paramTypes.Count; i++) { to.paramtypes.Add(new AntsParam("_" + i, from.paramTypes[i])); } 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 == javaloader.NormalizedByteCode.__return || src.code == javaloader.NormalizedByteCode.__ireturn || src.code == javaloader.NormalizedByteCode.__lreturn || src.code == javaloader.NormalizedByteCode.__areturn) //before return { _insertEndCode(from, to, src); } skipcount = ConvertCode(from, src, to); } } ConvertAddrInMethod(to); }