private int _ConvertNew(JavaMethod method, OpCode src, BhpMethod 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 BhpCode _InsertPush(byte[] data, string comment, BhpMethod 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 _ConvertLdLocA(OpCode src, AntsMethod to, int pos) //{ // _ConvertPush(pos, src, to); //} private void _ConvertLdArg(OpCode src, BhpMethod 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(ILMethod from, BhpMethod 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 void _insertBeginCode(JavaMethod from, BhpMethod 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 BhpCode _Convert1by1(VM.OpCode code, OpCode src, BhpMethod to, byte[] data = null) { BhpCode _code = new BhpCode(); 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 int _ConvertInitObj(OpCode src, BhpMethod 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, BhpMethod 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 _ConvertLdArg(ILMethod method, OpCode src, BhpMethod to, int pos) { try { var ptype = method.method.Parameters[pos].ParameterType.Resolve(); //var ptype = method.method.Parameters[pos].ParameterType; //if (ptype.BaseType.IsFunctionPointer) //{ if (ptype.BaseType.FullName == "System.MulticastDelegate" || ptype.BaseType.FullName == "System.Delegate") { foreach (var m in ptype.Methods) { if (m.Name == "Invoke") { to.lastparam = m.Parameters.Count; break; } } } } catch { } //} //get array _Convert1by1(VM.OpCode.FROMALTSTACK, src, to); _Convert1by1(VM.OpCode.DUP, null, to); _Convert1by1(VM.OpCode.TOALTSTACK, null, to); //get i _ConvertPush(pos, null, to);//翻转取参数顺序 _Convert1by1(VM.OpCode.PICKITEM, null, to); ////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 int _ConvertPushI8WithConv(ILMethod from, long i, OpCode src, BhpMethod to) { var next = from.GetNextCodeAddr(src.addr); var code = from.body_Codes[next].code; BigInteger outv; if (code == CodeEx.Conv_U || code == CodeEx.Conv_U8) //code == CodeEx.Conv_U1 || code ==CodeEx.Conv_U2 || code==CodeEx.Conv_U4|| code== CodeEx.Conv_U8) { ulong v = (ulong)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else if (code == CodeEx.Conv_U1) { byte v = (byte)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else if (code == CodeEx.Conv_U2) { ushort v = (ushort)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else if (code == CodeEx.Conv_U4) { uint v = (uint)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else if (code == CodeEx.Call) { var call = from.body_Codes[next]; if (call.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.UInt64)") {//如果是ulong转型到biginteger,需要注意 ulong v = (ulong)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } } { _ConvertPush(i, src, to); return(0); } }
private void _ConvertStArg(OpCode src, BhpMethod 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(BhpMethod 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 int _ConvertNewObj(OpCode src, BhpMethod 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(); //如果构造函数上有一个[OpCode],替换New Array操作 foreach (var m in type.DeclaringType.Methods) { if (m.IsConstructor && m.HasCustomAttributes) { foreach (var attr in m.CustomAttributes) { if (attr.AttributeType.Name == "OpCodeAttribute") { //var _type = attr.ConstructorArguments[0].Type; var value = (byte)attr.ConstructorArguments[0].Value; VM.OpCode v = (VM.OpCode)value; _Insert1(v, null, to); return(0); } } } } _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 int _ConvertLdfld(OpCode src, BhpMethod 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 BhpCode _InsertPush(int i, string comment, BhpMethod 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, BhpMethod 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 BhpCode _ConvertPush(long i, OpCode src, BhpMethod 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 _ConvertStLoc(ILMethod method, OpCode src, BhpMethod 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, BhpMethod 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, BhpMethod 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 int _ConvertStfld(ILMethod method, OpCode src, BhpMethod 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 ConvertMethod(JavaMethod from, BhpMethod to) { convertType.Clear(); to.returntype = from.returnType; for (var i = 0; i < from.paramTypes.Count; i++) { to.paramtypes.Add(new BhpParam("_" + 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); }
private void ConvertAddrInMethod(BhpMethod to) { foreach (var c in to.body_Codes.Values) { if (c.needfix) { try { var _addr = addrconv[c.srcaddr]; Int16 addroff = (Int16)(_addr - c.addr); c.bytes = BitConverter.GetBytes(addroff); c.needfix = false; } catch { throw new Exception("cannot convert addr in: " + to.name + "\r\n"); } } } }
private void _ConvertLdLoc(JavaMethod method, OpCode src, BhpMethod to, int pos) { if (method.method.IsStatic == false && pos == 0) {//忽略非静态函数取this的操作 return; } //push d var c = _Convert1by1(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(VM.OpCode.PICKITEM, null, to); }
private int _ConvertPushI4WithConv(ILMethod from, int i, OpCode src, BhpMethod to) { var next = from.GetNextCodeAddr(src.addr); var code = from.body_Codes[next].code; BigInteger outv; if (code == CodeEx.Conv_U || code == CodeEx.Conv_U8) //code == CodeEx.Conv_U1 || code ==CodeEx.Conv_U2 || code==CodeEx.Conv_U4|| code== CodeEx.Conv_U8) { ulong v = (uint)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else if (code == CodeEx.Conv_U1) { byte v = (byte)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else if (code == CodeEx.Conv_U2) { ushort v = (ushort)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else if (code == CodeEx.Conv_U4) { uint v = (uint)i; outv = v; _ConvertPush(outv.ToByteArray(), src, to); return(1); } else { _ConvertPush(i, src, to); return(0); } }
private int _ConvertStringBuilder(string callname, OpCode src, BhpMethod to) { if (callname == "<init>") { _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.DUP, null, to); _ConvertPush(0, null, to); _ConvertPush(3, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); return(0); } if (callname == "append") { _Convert1by1(VM.OpCode.SWAP, null, to);//把对象数组换上来 _Convert1by1(VM.OpCode.DUP, null, to); _ConvertPush(0, null, to); _Convert1by1(VM.OpCode.PICKITEM, null, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SWAP, null, to);//把对象数组换上来 _Convert1by1(VM.OpCode.CAT, null, to); _ConvertPush(0, null, to); _Convert1by1(VM.OpCode.SWAP, null, to);//把对象数组换上来 _Convert1by1(VM.OpCode.SETITEM, null, to); return(0); } if (callname == "toString") { _ConvertPush(0, null, to); _Convert1by1(VM.OpCode.PICKITEM, null, to); return(0); } return(0); }
private void _ConvertCastclass(ILMethod method, OpCode src, BhpMethod to) { var type = src.tokenUnknown as Mono.Cecil.TypeReference; try { var dtype = type.Resolve(); if (dtype.BaseType.FullName == "System.MulticastDelegate" || dtype.BaseType.FullName == "System.Delegate") { foreach (var m in dtype.Methods) { if (m.Name == "Invoke") { to.lastparam = m.Parameters.Count; break; } } } } catch { } }
private BhpCode _Insert1(VM.OpCode code, string comment, BhpMethod to, byte[] data = null) { BhpCode _code = new BhpCode(); 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, BhpMethod 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); } try { skipcount = ConvertCode(from, src, to); } catch (Exception err) { throw new Exception("error:" + from.method.FullName + "::" + src, err); } } } ConvertAddrInMethod(to); }
private int _ConvertIfNonNull(JavaMethod method, OpCode src, BhpMethod to) { int nm = method.GetLastCodeAddr(src.addr);//上一指令 int n = method.GetNextCodeAddr(src.addr); int n2 = method.GetNextCodeAddr(n); var codenext = method.body_Codes[n]; if (nm >= 0 && n >= 0 && n2 >= 0 && method.body_Codes[nm].code == javaloader.NormalizedByteCode.__dup && //上一条是dup指令 src.arg1 == n2 - src.addr && //刚好跳过throw 指令 codenext.code == javaloader.NormalizedByteCode.__invokestatic ) { var cc = method.DeclaringType.classfile.constantpool; var c = cc[codenext.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref; var name = c.Class + "::" + c.Name; if (name == "kotlin.jvm.internal.Intrinsics::throwNpe") {//识别到套路 var _code = to.body_Codes.Last().Value; //移除上一条指令 to.body_Codes.Remove(_code.addr); this.addr = _code.addr; return(1); } } var codenextnext = method.body_Codes[n2]; _ConvertPush(0, src, to);//和0比较 _Convert1by1(VM.OpCode.NUMNOTEQUAL, null, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.addr + src.arg1; return(0); }