Exemplo n.º 1
0
        public unsafe static uint Size(AnyInstruction *pInstr, uint bcv)
        {
            switch (pInstr->Kind(bcv))
            {
            case InstructionKind.SingleType:
            case InstructionKind.DoubleType:
            case InstructionKind.Goto:
            case InstructionKind.Break:
            case InstructionKind.Environment:
                return(1);

            case InstructionKind.Call:
            case InstructionKind.Set:
                return(2);

            case InstructionKind.Push:     // 0xF?
                var pui = (PushInstruction *)pInstr;

                switch (pui->Type)
                {
                case DataType.Int16:
                    return(1);

                case DataType.Variable:
                    return(2);

                default:
                    return(pui->Type.Size() / sizeof(uint) + 1);
                }

            default:
                return(0);
            }
        }
Exemplo n.º 2
0
        static CodeBlock[] SplitBlocks(CodeInfo code, uint bcv)
        {
            var blocks = new List <CodeBlock>();
            var instr  = code.Instructions;

            var jumpTo = FindJumpOffsets(code, bcv);

            for (int i = 0; i < jumpTo.Length; i++)
            {
                var             instrs   = new List <IntPtr>();
                var             br       = jumpTo[i];
                var             ind      = Utils.IndexOfPtr(instr, br);
                AnyInstruction *nextAddr = null;

                for (var j = ind; j != -1 && j < instr.Length; j++)
                {
                    var ins = instr[j];

                    if (i != jumpTo.Length - 1 && ins == jumpTo[i + 1]) // sorted
                    {
                        nextAddr = ins;
                        break;
                    }

                    instrs.Add((IntPtr)ins);
                }

                if (instrs.Count == 0)
                {
                    continue;
                }

                if (i == jumpTo.Length - 1 && br > instr[instr.Length - 1]) // implicit 'ret' after last instruction
                {
                    blocks.Add(new CodeBlock
                    {
                        Instructions = Utils.MPtrListToPtrArr(instrs),
                        BranchTo     = null,
                        Type         = BranchType.Unconditional
                    });
                }
                else
                {
                    var lastI = (AnyInstruction *)(instrs[instrs.Count - 1]);

                    blocks.Add(new CodeBlock
                    {
                        Instructions = Utils.MPtrListToPtrArr(instrs),
                        BranchTo     = lastI->Kind(bcv) == InstructionKind.Goto ? (AnyInstruction *)((long)lastI + lastI->Goto.Offset * 4L) : nextAddr /* can be null */,
                        Type         = lastI->Kind(bcv) == InstructionKind.Goto ? lastI->Goto.Type(bcv) : BranchType.Unconditional
                    });
                }
            }

            return(blocks.ToArray());
        }
Exemplo n.º 3
0

        
Exemplo n.º 4
0
        public static AnyInstruction *[] MPtrListToPtrArr(IList <IntPtr> l)
        {
            var r = new AnyInstruction *[l.Count];

            for (int i = 0; i < r.Length; i++)
            {
                r[i] = (AnyInstruction *)l[i];
            }

            return(r);
        }
Exemplo n.º 5
0
        public static int IndexOfPtr(AnyInstruction *[] arr, AnyInstruction *elem)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                if (elem == arr[i])
                {
                    return(i);
                }
            }

            return(-1);
        }
Exemplo n.º 6
0
        public unsafe static uint Size(AnyInstruction *pInstr, uint bcv)
        {
            switch (pInstr->Kind(bcv))
            {
            case InstructionKind.SingleType:
            case InstructionKind.DoubleType:
            case InstructionKind.Goto:
            case InstructionKind.Break:
            case InstructionKind.Environment:
                return(1);

            case InstructionKind.Call:
                return(2);

            case InstructionKind.Set:
                if (*(uint *)pInstr == SetArrayMagic)    // some magic number that has something to do with arrays
                {
                    return(1);
                }

                return(2);

            case InstructionKind.Push:     // 0xF?
                var pui = (PushInstruction *)pInstr;

                switch (pui->Type)
                {
                case DataType.Int16:
                    return(1);

                case DataType.Variable:
                    return(2);

                default:
                    return(pui->Type.Size() / sizeof(uint) + 1);
                }

            default:
                return(0);
            }
        }
Exemplo n.º 7
0
        static AnyInstruction*[] FindJumpOffsets(CodeInfo code)
        {
            var blocks = new List<CodeBlock>();
            var instr  = code.Instructions;

            var ret = new List<IntPtr>();

            ret.Add((IntPtr)instr[0]);

            for (int i = 0; i < instr.Length; i++)
            {
                var ins = instr[i];
                if (ins->Kind() == InstructionKind.Goto)
                {
                    IntPtr p;
                    // instructions after a 'goto'
                    if (i < instr.Length - 1)
                    {
                        p = (IntPtr)instr[i + 1];

                        if (!ret.Contains(p))
                            ret.Add(p);
                    }

                    // goto targets
                    p = (IntPtr)((long)ins + ins->Goto.Offset * 4L);

                    if (!ret.Contains(p))
                        ret.Add(p);
                }
            }

            ret.Sort(Utils.ComparePtrs);

            var ret_ = new AnyInstruction*[ret.Count];

            for (int i = 0; i < ret_.Length; i++)
                ret_[i] = (AnyInstruction*)ret[i];

            return ret_;
        }