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 int _ConvertIfNonNull(JavaMethod method, OpCode src, AntsMethod 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); }
private int _ConvertNewArray(JavaMethod method, OpCode src, AntsMethod to) { int skipcount = 0; if (src.arg1 != 8) { //this.logger.Log("_ConvertNewArray::not support type " + src.arg1 + " for array."); _Convert1by1(VM.OpCode.NEWARRAY, src, to); return(0); } //bytearray var code = to.body_Codes.Last().Value; //we need a number if (code.code > 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 = code.addr; OpCode next = src; int dupcount = 0; int pcount = 0; int[] buf = new int[] { 0, 0, 0 }; byte[] outbuf = new byte[number]; do { int n = method.GetNextCodeAddr(next.addr); next = method.body_Codes[n]; if (next.code == javaloader.NormalizedByteCode.__dup) { dupcount++; skipcount++; } else if (next.code == javaloader.NormalizedByteCode.__iconst) { buf[pcount] = next.arg1; pcount++; skipcount++; } else if (next.code == javaloader.NormalizedByteCode.__bastore) { dupcount--; var v = (byte)buf[pcount - 1]; var i = buf[pcount - 2]; //while (outbuf.Count <= i) // outbuf.Add(0); outbuf[i] = v; pcount -= 2; skipcount++; } else if (next.code == javaloader.NormalizedByteCode.__astore) { _ConvertPush(outbuf.ToArray(), src, to); return(skipcount); } else { throw new Exception("can not parse this new array code chain."); } }while (next != null); return(0); }
private int _ConvertNewArray(JavaMethod method, OpCode src, AntsMethod to) { int skipcount = 0; if (src.arg1 != 8) { //this.logger.Log("_ConvertNewArray::not support type " + src.arg1 + " for array."); _Convert1by1(VM.OpCode.NEWARRAY, src, to); return(0); } //bytearray var code = to.body_Codes.Last().Value; //we need a number if (code.code > 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 = code.addr; OpCode next = src; int dupcount = 0; int pcount = 0; int[] buf = new int[] { 0, 0, 0 }; byte[] outbuf = new byte[number]; do { int n = method.GetNextCodeAddr(next.addr); next = method.body_Codes[n]; if (next.code == javaloader.NormalizedByteCode.__invokestatic) { var i = method.DeclaringType.classfile.constantpool[next.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref; var callname = i.Class + "::" + i.Name; if (callname == "java.lang.Integer::valueOf") { //nothing skipcount++; } else { throw new Exception("can not parse this new array code chain." + next.code); } } else if (next.code == javaloader.NormalizedByteCode.__invokevirtual) { var i = method.DeclaringType.classfile.constantpool[next.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref; var callname = i.Class + "::" + i.Name; if (callname == "java.lang.Byte::byteValue") { skipcount++; } else { throw new Exception("can not parse this new array code chain." + next.code); } } else if (next.code == javaloader.NormalizedByteCode.__checkcast) { //nothing skipcount++; } else if (next.code == javaloader.NormalizedByteCode.__dup) { dupcount++; skipcount++; } else if (next.code == javaloader.NormalizedByteCode.__iconst) { buf[pcount] = next.arg1; pcount++; skipcount++; } else if (next.code == javaloader.NormalizedByteCode.__bastore) { dupcount--; var v = (byte)buf[pcount - 1]; var i = buf[pcount - 2]; //while (outbuf.Count <= i) // outbuf.Add(0); outbuf[i] = v; pcount -= 2; skipcount++; } else if (next.code == javaloader.NormalizedByteCode.__astore) { _ConvertPush(outbuf.ToArray(), src, to); return(skipcount); } else { throw new Exception("can not parse this new array code chain."); } }while (next != null); return(0); }