Esempio n. 1
0
        int AnalyzeCodeBlock(CodeBlock block, List<Instruction> insns, Dictionary<Instruction, CodeBlock> blockMapping, int index, int endAddress)
        {
            int i = index;
            int continueAddr = int.MaxValue;
            while (i < insns.Count)
            {
                if (i == endAddress)
                    return i;
                Instruction insn = insns[i];
                if (i == index)
                {
                    if (blockMapping.ContainsKey(insn))
                    {
                        Instruction lastInsn = blockMapping[insn].Instructions[blockMapping[insn].Instructions.Count - 1];
                        CodeBlock cur = blockMapping[insn];
                        while (lastInsn.Inst == Instructions.DummyCodeBlock)
                        {
                            cur = cur.CodeBlocks[lastInsn.Operand1];
                            lastInsn = cur.Instructions[cur.Instructions.Count - 1];
                        }
                        foreach (Instruction j in blockMapping[insn].Instructions)
                            block.Instructions.Add(j);
                        foreach (CodeBlock j in blockMapping[insn].CodeBlocks)
                            block.CodeBlocks.Add(j);
                        return insns.IndexOf(lastInsn) + 1;
                    }
                    blockMapping.Add(insn, block);
                }
                if (insn.IsBranchTarget && i != index)
                {
                    CodeBlock newBlock = new CodeBlock();
                    block.CodeBlocks.Add(newBlock);
                    Instruction dummy = new Instruction();
                    dummy.Inst = Instructions.DummyCodeBlock;
                    dummy.Operand1 = block.CodeBlocks.Count - 1;
                    block.Instructions.Add(dummy);
                    i = AnalyzeCodeBlock(newBlock, insns, blockMapping, i, -1);
                    if (newBlock.Instructions.Count == 1)
                    {
                        if (newBlock.Instructions[0].BranchTarget.Count > 0)
                        {
                        }
                    }
                    continue;
                }
                int elseTarget = insn.BranchTarget.Count > 0 ? insn.BranchTarget[0] : int.MaxValue;
                block.Instructions.Add(insn);
                i++;
                if (insn.StartNewBlock)
                {
                    if (insn.BranchTarget[0] > i)
                    {
                        if (insns[i].EndBlock)
                        {
                        }
                        int tmpI = i;
                        int tmpI2 = i;
                        CodeBlock newBlock = new CodeBlock();
                        CodeBlock newBlock2 = null;
                        Instruction dummy2 = null;
                        block.CodeBlocks.Add(newBlock);
                        Instruction dummy = new Instruction();
                        dummy.Inst = Instructions.DummyCodeBlock;
                        dummy.Operand1 = block.CodeBlocks.Count - 1;
                        block.Instructions.Add(dummy);
                        i = AnalyzeCodeBlock(newBlock, insns, blockMapping, i, elseTarget);
                        /*Instruction lastInsn = newBlock.Instructions[newBlock.Instructions.Count - 1];
                        if (lastInsn.Inst == Instructions.DummyCodeBlock)
                        {
                            lastInsn = newBlock.CodeBlocks[lastInsn.Operand1].Instructions.Last();
                        }
                        if (lastInsn.BranchTarget.Count > 0)
                        {
                            continueAddr = lastInsn.BranchTarget[0];
                        }*/
                        continueAddr = FindContinueAddress(elseTarget, newBlock);
                        if ((continueAddr != -1) && !insns[continueAddr - 1].EndBlock)
                        {
                            Instruction continueInsn = insns[continueAddr - 1];
                            continueInsn.EndBlock = true;
                            continueInsn.BranchTarget.Add(continueAddr);
                        }
                        if (continueAddr == elseTarget)
                        {
                            dummy.Operand2 = 1;
                        }

                        bool shouldReturn = false;
                        if (elseTarget < continueAddr)
                        {
                            i = elseTarget;
                            if (i != elseTarget)
                            {
                            }
                            newBlock2 = new CodeBlock();
                            block.CodeBlocks.Add(newBlock2);
                            dummy2 = new Instruction();
                            dummy2.Inst = Instructions.DummyCodeBlock;
                            dummy2.Operand1 = block.CodeBlocks.Count - 1;
                            block.Instructions.Add(dummy2);
                            i = AnalyzeCodeBlock(newBlock2, insns, blockMapping, i, continueAddr);
                            //tmpI2 = i;
                            if (i == continueAddr)
                                shouldReturn = true;
                        }
                        else
                        {
                            shouldReturn = true;
                        }
                        /*i = tmpI;
                        newBlock = new CodeBlock();
                        block.CodeBlocks.Add(newBlock);
                        dummy = new Instruction();
                        dummy.Inst = Instructions.DummyCodeBlock;
                        dummy.Operand1 = block.CodeBlocks.Count - 1;
                        block.Instructions.Add(dummy);
                        i = AnalyzeCodeBlock(newBlock, insns, blockMapping, i);

                        if (newBlock2 != null)
                        {
                            block.CodeBlocks.Add(newBlock2);
                            dummy2.Operand1 = block.CodeBlocks.Count - 1;
                            block.Instructions.Add(dummy2);
                            i = tmpI2;
                        }*/
                        if ((shouldReturn && endAddress == -1) || i >= endAddress)
                            return i;
                        else
                            continue;
                    }
                }

                if ((insn.EndBlock && (((insn.BranchTarget.Count == 0) || insn.BranchTarget[0] > endAddress) || endAddress == -1) && (insn.Inst != Instructions.Ret || (i < insns.Count && insns[i].IsBranchTarget))) || (i >= endAddress && endAddress >= 0))
                {
                    if (i > 1 && (insns[i - 2].Inst == Instructions.Switch || insns[i - 2].Inst == Instructions.SwitchS))
                        endAddress = insns[i - 1].BranchTarget[0];
                    else
                        return i;
                }
            }
            return i;
        }
Esempio n. 2
0
 public static Instruction ParseInstruction(System.IO.BinaryReader br,Assembly asm,Function func)
 {
     Instructions op = (Instructions)br.ReadInt16();
     Instruction insn = new Instruction();
     insn.Assembly = asm;
     insn.Function = func;
     insn.Inst = op;
     switch (op)
     {
         case Instructions.BneLocal:
         case Instructions.BgeLocal:
         case Instructions.BltLocal:
         case Instructions.BgtLocal:
         case Instructions.BneField:
         case Instructions.BeqField:
         case Instructions.BneFieldLocal:
         case Instructions.BgtField:
             insn.Operand1 = br.ReadInt32();
             insn.Operand2 = br.ReadInt32();
             insn.Operand3 = br.ReadInt32();
             insn.BranchTarget.Add(insn.Operand3);
             insn.StartNewBlock = true;
             break;
         case Instructions.Jmp:
             insn.Operand1 = br.ReadInt32();
             insn.BranchTarget.Add(insn.Operand1);
             insn.EndBlock = true;
             break;
         case Instructions.BrFalse:
         case Instructions.BrTrue:                    
             insn.Operand1 = br.ReadInt32();
             insn.BranchTarget.Add(insn.Operand1);
             insn.StartNewBlock = true;
             break;
         case Instructions.Switch:
         case Instructions.SwitchS:
             insn.Operand1 = br.ReadInt32();
             Switch swi = asm.SwitchTables[insn.Operand1];
             foreach (int i in swi.SwitchTable.Values)
                 insn.BranchTarget.Add(i);
             if (swi.DefaultCase != -1)
                 insn.BranchTarget.Add(swi.DefaultCase);
             break;
         case Instructions.Push:
         case Instructions.CallMethod:
         case Instructions.Call:
         case Instructions.RefGlobal:
         case Instructions.RefLocal:
         case Instructions.PushS:
         case Instructions.AssertFunc:
         case Instructions.AssertFile:
         case Instructions.CallSys:
         case Instructions.EndOfFunc:
         case Instructions.StructDelLocal:
         case Instructions.PushField:
         case Instructions.IncLocal:
         case Instructions.DecLocal:
         case Instructions.ArraySizeField:
         case Instructions.ArraySizeGlobal:
         case Instructions.PushLocal2:
         case Instructions.PushSLocal:
         case Instructions.AssignSConst:
         case Instructions.PushSField:
         case Instructions.ArrayStructRef:
         case Instructions.PushSGlobal:
         case Instructions.AssignSLocal:
         case Instructions.StringEmptyLocal:
         case Instructions.StringEmptyField:
         case Instructions.StructRef:
         case Instructions.AssignSField:
         case Instructions.Msg:
             insn.Operand1 = br.ReadInt32();
             break;
         case Instructions.PushF:
             insn.Operand1F = br.ReadSingle();
             break;
         case Instructions.BrFalseField:
         case Instructions.BNotEmptyField:
         case Instructions.BneS:
             insn.Operand1 = br.ReadInt32();
             insn.Operand2 = br.ReadInt32();
             insn.BranchTarget.Add(insn.Operand2);
             insn.StartNewBlock = true;
             break;
         case Instructions.StructCreateLocal:
         case Instructions.AssignLocal:
         case Instructions.AssignField:
         case Instructions.CallHLL:
         case Instructions.AssignFieldLocal:
         case Instructions.AssignGlobalLocal:
         case Instructions.AssignLocalField:
         case Instructions.ArrayPushBackLocal:
         case Instructions.AssignGlobal:
         case Instructions.GeField:
         case Instructions.EqlSLocal:
         case Instructions.NeqSLocal:
         case Instructions.EqlSFieldLocal:
         case Instructions.AssignSFieldLocal:
         case Instructions.PushStructRefField:
         case Instructions.ArrayPushBackFieldLocal:
         case Instructions.AssignArrayLocalField:
         case Instructions.ArrayPushBackLocalString:
         case Instructions.ArrayPushBackGlobalLocalRef:
         case Instructions.ArrayPushBackFieldLocalRef:
         case Instructions.AssignFieldLocalITOB:
         case Instructions.ArrayPushBackGlobalLocal:
         case Instructions.MinLocal:
         case Instructions.NeqFieldS:
         case Instructions.NeqSFieldLocal:
         case Instructions.AssignSLocalLocal:
             insn.Operand1 = br.ReadInt32();
             insn.Operand2 = br.ReadInt32();
             break;
         case Instructions.LtOrGeLocal:
             insn.Operand1 = br.ReadInt32();
             insn.Operand2 = br.ReadInt32();
             insn.Operand3 = br.ReadInt32();
             break;
         case Instructions.Ret:
             insn.EndBlock = true;
             break;
         case Instructions.PushSP:
         case Instructions.Le:
         default:
             break;
     }
     return insn;
 }