Пример #1
0
        public bool IsAppCall(JavaMethod method, OpCode src, out byte[] callhash)
        {
            if (method != null)
            {
                if (method.method.Annotations != null)
                {
                    object[] op = method.method.Annotations[0] as object[];
                    if (op[1] as string == "LAntShares/SmartContract/Framework/Appcall;")
                    {
                        if (op[2] as string == "HexStr")
                        {
                            var    info  = op[3] as string;
                            byte[] bytes = new byte[info.Length / 2];

                            for (var i = 0; i < info.Length / 2; i++)
                            {
                                bytes[i] = byte.Parse(info.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
                            }
                            callhash = bytes;
                            return(true);
                        }
                    }
                }
            }


            //m.Annotations

            callhash = null;
            return(false);
        }
Пример #2
0
        public bool IsSysCall(JavaMethod method, OpCode src, out string callname)
        {
            if (method != null)
            {
                if (method.method.Annotations != null)
                {
                    object[] op = method.method.Annotations[0] as object[];
                    if (op[1] as string == "LAntShares/SmartContract/Framework/Syscall;")
                    {
                        if (op[2] as string == "value")
                        {
                            var info = op[3] as string;
                            callname = info;
                            return(true);
                        }
                    }
                }
            }


            //m.Annotations

            callname = "";
            return(false);
        }
Пример #3
0
        public bool IsAppCall(JavaMethod method, OpCode src, out byte[] callhash)
        {
            if (method != null)
            {
                if (method.method.Annotations != null)
                {
                    object[] op = method.method.Annotations[0] as object[];
                    if (op[1] as string == "Lorg/neo/smartcontract/framework/Appcall;")
                    {
                        if (op[2] as string == "value")
                        {
                            var info = op[3] as string;
                            if (info.Length < 40)
                            {
                                throw new Exception("appcall hash is too short.");
                            }
                            byte[] bytes = new byte[20];

                            for (var i = 0; i < 20; i++)
                            {
                                bytes[i] = byte.Parse(info.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
                            }
                            callhash = bytes;
                            return(true);
                        }
                    }
                }
            }


            //m.Annotations

            callhash = null;
            return(false);
        }
Пример #4
0
        public void InitToken(JavaMethod method, Instruction ins)
        {
            this.code = ins.NormalizedOpCode;
            this.arg1 = ins.Arg1;
            this.arg2 = ins.Arg2;
            this.addr = ins.PC;
            if (method.method.LineNumberTableAttribute == null || method.method.LineNumberTableAttribute.TryGetValue(this.addr, out this.debugline) == false)
            {
                this.debugline = -1;
            }
            if (this.debugline >= 0)
            {
                if (this.debugline - 1 < method.DeclaringType.srcfile.Length)
                {
                    this.debugcode = method.DeclaringType.srcfile[this.debugline - 1];
                }
            }
            switch (code)
            {
            case javaloader.NormalizedByteCode.__iconst:
                this.tokenI32 = this.arg1;
                break;

            //case javaloader.NormalizedByteCode.__newarray:
            //    var c = method.DeclaringType.classfile.constantpool[this.arg1];
            //    break;
            case javaloader.NormalizedByteCode.__astore:
                break;

            default:
                this.tokenUnknown   = ins;
                this.tokenValueType = TokenValueType.Nothing;
                break;
            }
        }
Пример #5
0
        public bool IsOpCall(JavaMethod method, OpCode src, out string callname)
        {
            if (method != null)
            {
                if (method.method.Annotations != null)
                {
                    object[] op = method.method.Annotations[0] as object[];
                    if (op[1] as string == "Lorg/neo/smartcontract/framework/OpCode;")
                    {
                        if (op[2] as string == "value")
                        {
                            var info = op[3] as object[];
                            callname = info[2] as string;
                            return(true);
                        }
                    }
                }
            }


            //m.Annotations

            callname = "";
            return(false);
        }
Пример #6
0
 public JavaClass(javaloader.ClassFile classfile, string[] srcfile = null)
 {
     this.classfile = classfile;
     this.srcfile   = srcfile;
     if (this.srcfile == null)
     {
         this.srcfile = new string[0];
     }
     foreach (var f in this.classfile.Fields)
     {
         this.fields.Add(f.Name, f.Signature);
     }
     foreach (var m in this.classfile.Methods)
     {
         bool bskip = false;
         if (m.Annotations != null)
         {
             object[] info = m.Annotations[0] as object[];
             if (info[1] as string == "LAntShares/SmartContract/Framework/Appcall;" ||
                 info[1] as string == "LAntShares/SmartContract/Framework/Syscall;" |
                 info[1] as string == "LAntShares/SmartContract/Framework/Opcall;")
             {
                 //continue;
                 bskip = true;
             }
             //if(m.Annotations[0])
         }
         var nm = new JavaMethod(this, m);
         nm.skip = bskip;
         this.methods[m.Name] = nm;
     }
     this.superClass = this.classfile.SuperClass;
 }
Пример #7
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 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);
        }
Пример #8
0
        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);
            //}
        }
Пример #9
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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        public bool IsNonCall(JavaMethod method)
        {
            if (method != null)
            {
                if (method.method.Annotations != null)
                {
                    object[] op = method.method.Annotations[0] as object[];
                    if (op[1] as string == "Lorg/neo/smartcontract/framework/Nonemit;")
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #12
0
        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);
        }
Пример #13
0
        private void ConvertMethod(JavaMethod from, NeoMethod to)
        {
            convertType.Clear();
            to.returntype = from.returnType;
            for (var i = 0; i < from.paramTypes.Count; i++)
            {
                to.paramtypes.Add(new NeoParam("_" + 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);
        }
Пример #14
0
        private void _ConvertLdLoc(JavaMethod method, OpCode src, AntsMethod 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);
        }
Пример #15
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);
        }
Пример #16
0
        public JavaClass(JavaModule module, javaloader.ClassFile classfile, string[] srcfile = null)
        {
            this.module    = module;
            this.classfile = classfile;
            if (this.classfile.IsEnum)
            {
                this.IsEnum = true;
                foreach (var m in this.classfile.Methods)
                {
                    if (m.Name == javaloader.StringConstants.CLINIT)
                    {
                        _InitConsts(m.Instructions);
                    }
                }
            }
            this.srcfile = srcfile;
            if (this.srcfile == null)
            {
                this.srcfile = new string[0];
            }
            foreach (var f in this.classfile.Fields)
            {
                this.fields.Add(f.Name, f.Signature);
            }
            bool isKtObj = false;

            if (this.classfile.SourceFileAttribute.Contains(".kt"))
            {
                var sign = "L" + this.classfile.Name + ";";
                foreach (var f in this.classfile.Fields)
                {
                    if (f.Name == "INSTANCE" && f.IsStatic && f.Signature == sign)
                    {
                        isKtObj = true;
                        break;
                    }
                }
            }
            foreach (var m in this.classfile.Methods)
            {
                bool bskip = false;
                if (m.IsStatic == false && isKtObj == false)
                {
                    bskip = true;
                    //静态成员不要,除非是kotlin 的 object 对象,相当于静态
                }

                if (m.Annotations != null)
                {
                    object[] info = m.Annotations[0] as object[];
                    if (info[1] as string == "Lorg/neo/smartcontract/framework/Appcall;" ||
                        info[1] as string == "Lorg/neo/smartcontract/framework/Syscall;" ||
                        info[1] as string == "Lorg/neo/smartcontract/framework/OpCode;" ||
                        info[1] as string == "Lorg/neo/smartcontract/framework/Nonemit;")
                    {
                        //continue;
                        bskip = true;
                    }
                    //if(m.Annotations[0])
                }
                if (m.Name == "<init>")
                {
                    bskip = true;
                }
                var nm = new JavaMethod(this, m);
                nm.skip = bskip;
                //if (bskip == false && methods.ContainsKey(m.Name))
                //{
                //    throw new Exception("already have a func named:" + classfile.Name + "." + m.Name);
                //}
                this.methods[m.Name + m.Signature] = nm;
            }
            this.superClass = this.classfile.SuperClass;
        }
Пример #17
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);
        }
Пример #18
0
        private int _ConvertCall(JavaMethod method, OpCode src, AntsMethod to)
        {
            _Convert1by1(VM.OpCode.NOP, src, to);
            var cc   = method.DeclaringType.classfile.constantpool;
            var c    = cc[src.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref;
            var name = c.Class + "::" + c.Name;

            List <string> paramTypes = new List <string>();
            string        returntype;

            JavaMethod.scanTypes(c.Signature, out returntype, paramTypes);


            JavaClass  javaclass   = null;
            JavaMethod _javamethod = null;

            if (this.srcModule.classes.ContainsKey(c.Class))
            {
                javaclass = this.srcModule.classes[c.Class];
                if (javaclass.methods.ContainsKey(c.Name))
                {
                    _javamethod = javaclass.methods[c.Name];
                }
                else
                {
                    while (javaclass != null)
                    {
                        if (this.srcModule.classes.ContainsKey(javaclass.superClass))
                        {
                            javaclass = this.srcModule.classes[javaclass.superClass];
                            if (javaclass.methods.ContainsKey(c.Name))
                            {
                                _javamethod = javaclass.methods[c.Name];
                                break;
                            }
                        }
                        else
                        {
                            javaclass = null;
                        }
                    }
                }
            }
            int    calltype = 0;
            string callname = "";

            byte[]    callhash = null;
            VM.OpCode callcode = VM.OpCode.NOP;

            if (IsOpCall(_javamethod, src, 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(_javamethod, src, out callname))
            {
                calltype = 3;
            }
            else if (IsAppCall(_javamethod, src, out callhash))
            {
                calltype = 4;
            }
            else if (this.outModule.mapMethods.ContainsKey(name))
            {//this is a call
                calltype = 1;
            }
            else
            {
                if (name == "java.io.PrintStream::println")
                {//drop 1;
                    Console.WriteLine("logstr.");
                    _Convert1by1(VM.OpCode.DROP, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::<init>")
                {//do nothing
                    if (c.Signature == "([B)V")
                    {
                        return(0);
                    }
                    else if (c.Signature == "(Ljava/lang/String;)V")
                    {
                        throw new Exception("not support new BigInteger(string)");
                    }
                }
                else if (name == "java.math.BigInteger::add")
                {
                    _Convert1by1(VM.OpCode.ADD, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::subtract")
                {
                    _Convert1by1(VM.OpCode.SUB, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::multiply")
                {
                    _Convert1by1(VM.OpCode.MUL, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::divide")
                {
                    _Convert1by1(VM.OpCode.DIV, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::mod")
                {
                    _Convert1by1(VM.OpCode.MOD, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::compareTo")
                {
                    //need parse
                    _Convert1by1(VM.OpCode.SUB, src, to);
                    _Convert1by1(VM.OpCode.SIGN, null, to);
                    //_Convert1by1(VM.OpCode.DEC, src, to);
                    return(0);
                }
                // todo: what about java.lang.String::contentEquals?
                else if (name == "java.math.BigInteger::equals" ||
                         name == "java.lang.String::equals" ||
                         name == "kotlin.jvm.internal.Intrinsics::areEqual")
                {
                    _Convert1by1(VM.OpCode.NUMEQUAL, src, to);
                    //_Convert1by1(VM.OpCode.DEC, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::valueOf" ||
                         name == "java.math.BigInteger::intValue" ||
                         name == "java.lang.Boolean::valueOf" ||
                         name == "java.lang.Character::valueOf" ||
                         name == "java.lang.String::valueOf" ||
                         name == "java.lang.Long::valueOf" ||
                         name == "java.math.BigInteger::toByteArray")
                {
                    //donothing
                    return(0);
                }
                else if (name == "java.lang.Boolean::booleanValue")
                {
                    _Convert1by1(VM.OpCode.NOP, src, to);
                    return(0);
                }
                else if (name == "java.lang.String::hashCode")
                {
                    //java switch 的编译方式很奇怪
                    return(0);
                }
                else if (name == "java.lang.String::charAt")
                {
                    _ConvertPush(1, src, to);
                    _Convert1by1(VM.OpCode.SUBSTR, null, to);
                    return(0);
                }
                else if (name == "java.lang.String::length")
                {
                    _Convert1by1(VM.OpCode.SIZE, null, to);
                    return(0);
                }
                else if (c.Class == "java.lang.StringBuilder")
                {
                    return(_ConvertStringBuilder(c.Name, null, to));
                }
                else if (name == "java.util.Arrays::equals")
                {
                    _Convert1by1(VM.OpCode.EQUAL, null, to);
                    return(0);
                }
                else if (name == "kotlin.jvm.internal.Intrinsics::checkParameterIsNotNull")
                {
                    _Convert1by1(VM.OpCode.DROP, null, to);
                    _Convert1by1(VM.OpCode.DROP, null, to);
                    return(0);
                }
            }

            if (calltype == 0)
            {
                throw new Exception("unknown call:" + name);
            }
            var pcount = paramTypes.Count;

            if (calltype == 2)
            {
                //opcode call
            }
            else
            {//翻转参数入栈顺序
                _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 = name;
                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 too 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);
        }
Пример #19
0
        private int ConvertCode(JavaMethod method, OpCode src, AntsMethod to)
        {
            int skipcount = 0;

            switch (src.code)
            {
            case javaloader.NormalizedByteCode.__nop:
                _Convert1by1(VM.OpCode.NOP, src, to);
                break;

            case javaloader.NormalizedByteCode.__return:
            case javaloader.NormalizedByteCode.__ireturn:
            case javaloader.NormalizedByteCode.__lreturn:
            case javaloader.NormalizedByteCode.__freturn:
            case javaloader.NormalizedByteCode.__dreturn:
            case javaloader.NormalizedByteCode.__areturn:
                //        //return 在外面特殊处理了
                _Insert1(VM.OpCode.RET, null, to);
                break;

            case javaloader.NormalizedByteCode.__pop:
                _Convert1by1(VM.OpCode.DROP, src, to);
                break;

            case javaloader.NormalizedByteCode.__getstatic:
            {
                _Convert1by1(VM.OpCode.NOP, src, to);

                var cc = method.DeclaringType.classfile.constantpool;
                var c  = cc[src.arg1] as javaloader.ClassFile.ConstantPoolItemFieldref;
                if (c.Class == "java.math.BigInteger")
                {
                    if (c.Name == "ONE")
                    {
                        _ConvertPush(1, src, to);
                    }
                    if (c.Name == "ZERO")
                    {
                        _ConvertPush(0, src, to);
                    }
                }
                if (c.Class == "java.lang.System")
                {
                    if (c.Name == "out")
                    {
                        //donothing
                    }
                }
                //this.convertType.Push(c.Signature);
            }
            break;

            case javaloader.NormalizedByteCode.__ldc:
            {
                var cc   = method.DeclaringType.classfile.constantpool;
                var item = cc[src.arg1];
                if (item is javaloader.ClassFile.ConstantPoolItemString)
                {
                    var str = (item as javaloader.ClassFile.ConstantPoolItemString).Value;
                    _ConvertPush(Encoding.UTF8.GetBytes(str), src, to);
                }
                else if (item is javaloader.ClassFile.ConstantPoolItemLong)
                {
                    var v = (item as javaloader.ClassFile.ConstantPoolItemLong).Value;
                    _ConvertPush(v, src, to);
                }
                else if (item is javaloader.ClassFile.ConstantPoolItemInteger)
                {
                    var v = (item as javaloader.ClassFile.ConstantPoolItemInteger).Value;
                    _ConvertPush(v, src, to);
                }
                else
                {
                    throw new Exception("not parse.");
                }
            }
            break;

            case javaloader.NormalizedByteCode.__iconst:

                _ConvertPush(src.arg1, src, to);
                break;

            case javaloader.NormalizedByteCode.__lconst_1:
                _ConvertPush(1, src, to);
                break;

            case javaloader.NormalizedByteCode.__lconst_0:
                _ConvertPush(0, src, to);
                break;

            case javaloader.NormalizedByteCode.__newarray:
            case javaloader.NormalizedByteCode.__anewarray:
                skipcount = _ConvertNewArray(method, src, to);
                break;

            case javaloader.NormalizedByteCode.__astore:
            case javaloader.NormalizedByteCode.__istore:
                _ConvertStLoc(src, to, src.arg1);
                break;

            case javaloader.NormalizedByteCode.__aload:
            case javaloader.NormalizedByteCode.__iload:
                _ConvertLdLoc(src, to, src.arg1);
                break;

            case javaloader.NormalizedByteCode.__aaload:
            case javaloader.NormalizedByteCode.__iaload:
                _Convert1by1(VM.OpCode.PICKITEM, src, to);
                break;

            case javaloader.NormalizedByteCode.__iastore:
            case javaloader.NormalizedByteCode.__aastore:
                _Convert1by1(VM.OpCode.SETITEM, src, to);
                break;

            case javaloader.NormalizedByteCode.__arraylength:
                _Convert1by1(VM.OpCode.ARRAYSIZE, src, to);
                break;

            case javaloader.NormalizedByteCode.__invokevirtual:
            case javaloader.NormalizedByteCode.__invokestatic:
            case javaloader.NormalizedByteCode.__invokespecial:
            {
                _ConvertCall(method, src, to);
            }
            break;

            case javaloader.NormalizedByteCode.__iinc:
                _Convert1by1(VM.OpCode.NOP, src, to);
                {
                    _Insert1(VM.OpCode.DUPFROMALTSTACK, "", to);
                    _InsertPush(src.arg1, "", to);
                    _Insert1(VM.OpCode.PICKITEM, "", to);
                    _InsertPush(src.arg2, "", to);
                    _Insert1(VM.OpCode.ADD, "", to);

                    _Insert1(VM.OpCode.DUPFROMALTSTACK, "", to); //array
                    _InsertPush(src.arg1, "", to);               //index
                    _InsertPush(2, "", to);
                    _Insert1(VM.OpCode.ROLL, "", to);
                    _Insert1(VM.OpCode.SETITEM, "", to);
                }
                //_Convert1by1(VM.OpCode.INC, src, to);

                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 javaloader.NormalizedByteCode.__goto:
            {
                var code = _Convert1by1(VM.OpCode.JMP, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.arg1 + src.addr;
            }
            break;

            //    case CodeEx.Br_S:
            //        {
            //            var code = _Convert1by1(VM.OpCode.JMP, src, to, new byte[] { 0, 0 });
            //            code.needfix = true;
            //            code.srcaddr = src.tokenAddr_Index;
            //        }

            //        break;
            case javaloader.NormalizedByteCode.__if_acmpeq:
            {
                _Convert1by1(VM.OpCode.EQUAL, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_acmpne:
            {
                _Convert1by1(VM.OpCode.EQUAL, null, to);
                _Convert1by1(VM.OpCode.NOT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpeq:
            {
                _Convert1by1(VM.OpCode.NUMEQUAL, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpne:
            {
                _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;
            }
            break;

            case javaloader.NormalizedByteCode.__ifne:
            {
                _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.arg1 + src.addr;
            }
            break;

            case javaloader.NormalizedByteCode.__ifeq:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(VM.OpCode.NUMEQUAL, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.arg1 + src.addr;
            }
            break;

            case javaloader.NormalizedByteCode.__iflt:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(VM.OpCode.GT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.arg1 + src.addr;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmplt:
            {
                _Convert1by1(VM.OpCode.LT, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifle:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(VM.OpCode.GT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmple:
            {
                _Convert1by1(VM.OpCode.LTE, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifgt:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(VM.OpCode.LT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpgt:
            {
                _Convert1by1(VM.OpCode.GT, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifge:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(VM.OpCode.LTE, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpge:
            {
                _Convert1by1(VM.OpCode.GTE, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifnull:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(VM.OpCode.NUMEQUAL, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifnonnull:
            {
                _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;
            }
            break;

            //    //Stack
            case javaloader.NormalizedByteCode.__dup:
                _Convert1by1(VM.OpCode.DUP, src, to);
                break;

            //    //Bitwise logic
            case javaloader.NormalizedByteCode.__iand:
            case javaloader.NormalizedByteCode.__land:
                _Convert1by1(VM.OpCode.AND, src, to);
                break;

            case javaloader.NormalizedByteCode.__ior:
            case javaloader.NormalizedByteCode.__lor:
                _Convert1by1(VM.OpCode.OR, src, to);
                break;

            case javaloader.NormalizedByteCode.__ixor:
            case javaloader.NormalizedByteCode.__lxor:
                _Convert1by1(VM.OpCode.XOR, src, to);
                break;


            case javaloader.NormalizedByteCode.__iadd:
            case javaloader.NormalizedByteCode.__ladd:
                _Convert1by1(VM.OpCode.ADD, src, to);
                break;

            case javaloader.NormalizedByteCode.__isub:
            case javaloader.NormalizedByteCode.__lsub:
                _Convert1by1(VM.OpCode.SUB, src, to);
                break;

            case javaloader.NormalizedByteCode.__imul:
            case javaloader.NormalizedByteCode.__lmul:
                _Convert1by1(VM.OpCode.MUL, src, to);
                break;

            case javaloader.NormalizedByteCode.__idiv:
            case javaloader.NormalizedByteCode.__ldiv:
                _Convert1by1(VM.OpCode.DIV, src, to);
                break;

            case javaloader.NormalizedByteCode.__irem:
            case javaloader.NormalizedByteCode.__lrem:
                _Convert1by1(VM.OpCode.MOD, src, to);
                break;

            case javaloader.NormalizedByteCode.__new:
                _ConvertNew(method, src, to);

                break;
            //    case CodeEx.Neg:
            //        _Convert1by1(VM.OpCode.NEGATE, src, to);
            //        break;
            //    case CodeEx.Shl:
            //        _Convert1by1(VM.OpCode.SHL, src, to);
            //        break;
            //    case CodeEx.Shr:
            //    case CodeEx.Shr_Un:
            //        _Convert1by1(VM.OpCode.SHR, src, to);
            //        break;

            //    //logic
            //    case CodeEx.Clt:
            //    case CodeEx.Clt_Un:
            //        _Convert1by1(VM.OpCode.LT, src, to);
            //        break;
            //    case CodeEx.Cgt:
            //    case CodeEx.Cgt_Un:
            //        _Convert1by1(VM.OpCode.GT, src, to);
            //        break;
            //    case CodeEx.Ceq:
            //        _Convert1by1(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_U1://用意为byte[] 取一部分.....
            //        _ConvertPush(1, src, to);
            //        _Convert1by1(VM.OpCode.SUBSTR, null, to);
            //        break;
            //    case CodeEx.Ldelem_Any:
            //    case CodeEx.Ldelem_I:
            //    case CodeEx.Ldelem_I1:
            //    case CodeEx.Ldelem_I2:
            //    case CodeEx.Ldelem_I4:
            //    case CodeEx.Ldelem_I8:
            //    case CodeEx.Ldelem_R4:
            //    case CodeEx.Ldelem_R8:
            //    case CodeEx.Ldelem_Ref:
            //    case CodeEx.Ldelem_U2:
            //    case CodeEx.Ldelem_U4:
            //        _Convert1by1(VM.OpCode.PICKITEM, src, to);
            //        break;
            //    case CodeEx.Ldlen:
            //        _Convert1by1(VM.OpCode.ARRAYSIZE, src, to);
            //        break;

            //    case CodeEx.Castclass:
            //        break;
            case javaloader.NormalizedByteCode.__i2c:
            case javaloader.NormalizedByteCode.__checkcast:
                break;
            //    case CodeEx.Box:
            //    case CodeEx.Unbox:
            //    case CodeEx.Unbox_Any:
            //    case CodeEx.Break:
            //    //也有可能以后利用这个断点调试
            //    case CodeEx.Conv_I:
            //    case CodeEx.Conv_I1:
            //    case CodeEx.Conv_I2:
            //    case CodeEx.Conv_I4:
            //    case CodeEx.Conv_I8:
            //    case CodeEx.Conv_Ovf_I:
            //    case CodeEx.Conv_Ovf_I_Un:
            //    case CodeEx.Conv_Ovf_I1:
            //    case CodeEx.Conv_Ovf_I1_Un:
            //    case CodeEx.Conv_Ovf_I2:
            //    case CodeEx.Conv_Ovf_I2_Un:
            //    case CodeEx.Conv_Ovf_I4:
            //    case CodeEx.Conv_Ovf_I4_Un:
            //    case CodeEx.Conv_Ovf_I8:
            //    case CodeEx.Conv_Ovf_I8_Un:
            //    case CodeEx.Conv_Ovf_U:
            //    case CodeEx.Conv_Ovf_U_Un:
            //    case CodeEx.Conv_Ovf_U1:
            //    case CodeEx.Conv_Ovf_U1_Un:
            //    case CodeEx.Conv_Ovf_U2:
            //    case CodeEx.Conv_Ovf_U2_Un:
            //    case CodeEx.Conv_Ovf_U4:
            //    case CodeEx.Conv_Ovf_U4_Un:
            //    case CodeEx.Conv_Ovf_U8:
            //    case CodeEx.Conv_Ovf_U8_Un:
            //    case CodeEx.Conv_U:
            //    case CodeEx.Conv_U1:
            //    case CodeEx.Conv_U2:
            //    case CodeEx.Conv_U4:
            //    case CodeEx.Conv_U8:
            //        break;

            //    ///////////////////////////////////////////////
            //    //以下因为支持结构体而出现
            //    //加载一个引用,这里改为加载一个pos值
            //    case CodeEx.Ldloca:
            //    case CodeEx.Ldloca_S:
            //        _ConvertLdLocA(src, to, src.tokenI32);
            //        break;
            //    case CodeEx.Initobj:
            //        _ConvertInitObj(src, to);
            //        break;
            //    case CodeEx.Stfld:
            //        _ConvertStfld(src, to);
            //        break;
            //    case CodeEx.Ldfld:
            //        _ConvertLdfld(src, to);
            //        break;
            default:
#if WITHPDB
                //throw new Exception("unsupported instruction " + src.code);
                logger.Log("not support code" + src.code);
                break;
#else
                throw new Exception("unsupported instruction " + src.code);
#endif
            }

            return(skipcount);
        }
Пример #20
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);
        }