Exemplo n.º 1
0
        public IMutableBasicBlock CreateNewBlock(BasicBlockType type, int lineNumber, Guid?id = null)
        {
            var block = new BasicBlock(id ?? Guid.NewGuid(), type, lineNumber);

            _vertexLookup.Add(block.ID, block);
            return(block);
        }
Exemplo n.º 2
0
        private static void FillData(BasicBlockType export, BasicBlock bb)
        {
            export.ID.Value = bb.ID;
            List <string> predecessors = new List <string>();
            List <string> successors   = new List <string>();

            bb.getPredecessors.ForEach(x => predecessors.Add(x.ID));
            bb.getSuccessors.ForEach(x => successors.Add(x.ID));
            if (predecessors.Count > 0)
            {
                export.Predecessors.Value = string.Join(" ", predecessors.ToArray());
            }
            if (successors.Count > 0)
            {
                export.Successors.Value = string.Join(" ", successors.ToArray());
            }
            // TODO: continue
            if (bb.PolyRequired)
            {
                export.PolyRequired.Value = bb.PolyRequired;
            }
            foreach (Instruction inst_original in bb.Instructions)
            {
                InstructionType inst = export.Instruction.Append();
                FillData(inst, inst_original);
            }
        }
Exemplo n.º 3
0
 public BasicBlock(Address begin, Address end, BasicBlockType type, BinaryImage image)
 {
     if (begin.Segment != end.Segment)
     {
         throw new ArgumentException("Basic block must be on the same segment.");
     }
     this.location = begin;
     this.length   = end.Offset - begin.Offset;
     this.type     = type;
     this.features = CodeFeaturesHelper.GetFeatures(GetInstructions(image));
 }
Exemplo n.º 4
0
        private static void FillData(FunctionType export, Function function)
        {
            export.CalledFrom.EnumerationValue = (CalledFromType.EnumValues)function.calledFrom;
            export.GlobalID.Value = function.globalID;
            export.ID.Value       = function.ID;
            List <string> input_vars_id  = new List <string>();
            List <string> output_vars_id = new List <string>();

            function.LocalVariables.FindAll(x => x.kind == Variable.Kind.Input).ForEach(x => input_vars_id.Add(x.ID));
            function.LocalVariables.FindAll(x => x.kind == Variable.Kind.Output).ForEach(x => output_vars_id.Add(x.ID));
            if (input_vars_id.Count > 0)
            {
                export.RefInputVars.Value = string.Join(" ", input_vars_id.ToArray());
            }
            if (output_vars_id.Count > 0)
            {
                export.RefOutputVars.Value = string.Join(" ", output_vars_id.ToArray());
            }

            // Exporting local variables
            if (function.LocalVariables.Count > 0)
            {
                export.Local.Append();
            }
            foreach (Variable var_orig in function.LocalVariables)
            {
                VariableType var = export.Local.First.Variable.Append();
                FillData(var, var_orig);
            }

            // Exporting basic blocks
            foreach (BasicBlock bb_orig in function.BasicBlocks)
            {
                BasicBlockType bb = export.BasicBlock.Append();
                FillData(bb, bb_orig);
            }
        }
Exemplo n.º 5
0
 internal BasicBlock(int index, BasicBlockType type, Instruction instruction)
     : this(index, instruction)
 {
     Type          = type;
     OriginalIndex = ++_next_index;
 }
Exemplo n.º 6
0
        /// <summary>
        /// Gets the image associated with the segment specified by its id.
        /// </summary>
        /// <param name="segmentId">Id of the segment to resolve.</param>
        /// <returns>The image associated with the given segment, or null if
        /// the segment id is invalid.</returns>
        //protected abstract ImageChunk ResolveSegment(int segmentId);

        #region Flow Analysis Methods

        /// <summary>
        /// Analyzes a contiguous sequence of instructions that form a basic
        /// block. A basic block terminates as soon as any of the following
        /// conditions is true:
        /// - An analysis error occurs
        /// - An block terminating instructions: RET, RETF, IRET, HLT.
        /// - A b/c/j instruction: Jcc, JMP, JMPF, LOOPcc.
        /// </summary>
        /// <param name="start">Address to begin analysis.</param>
        /// <param name="xrefs">Collection to add xrefs to.</param>
        /// <returns>
        /// A new BasicBlock if one was created during the analysis.
        /// If no new BasicBlocks are created, or if an existing block was
        /// split into two, returns null.
        /// </returns>
        // TODO: should be roll-back the entire basic block if we
        // encounters an error on our way? maybe not.
        protected virtual BasicBlock AnalyzeBasicBlock(XRef start, ICollection <XRef> xrefs)
        {
            Address ip = start.Target; // instruction pointer

            if (!image.IsAddressValid(ip))
            {
                AddError(ip, ErrorCode.OutOfImage,
                         "XRef target is outside of the image (referred from {0})",
                         start.Source);
                return(null);
            }

            // Check if the entry address is already analyzed.
            ByteAttribute b = image[ip];

            if (b.Type != ByteType.Unknown)
            {
                // Fail if we ran into data or padding while expecting code.
                if (b.Type != ByteType.Code)
                {
                    AddError(ip, ErrorCode.RanIntoData,
                             "XRef target is in the middle of data (referred from {0})",
                             start.Source);
                    return(null);
                }

                // Now the byte was previously analyzed as code. We must have
                // already created a basic block that contains this byte.
                BasicBlock block = BasicBlocks.Find(ip);
                System.Diagnostics.Debug.Assert(block != null);

                // If the existing block starts at this address, we're done.
                if (block.Location == ip)
                {
                    return(null);
                }

                // TBD: recover the following in some way...
#if false
                if (image[b.BasicBlock.StartAddress].Address.Segment != pos.Segment)
                {
                    AddError(pos, ErrorCategory.Error,
                             "Ran into the middle of a block [{0},{1}) from another segment " +
                             "when processing block {2} referred from {3}",
                             b.BasicBlock.StartAddress, b.BasicBlock.EndAddress,
                             start.Target, start.Source);
                    return(null);
                }
#endif

                // Now split the existing basic block into two. This requires
                // that the cut-off point is at instruction boundary.
                if (!b.IsLeadByte)
                {
                    AddError(ip, ErrorCode.RanIntoCode,
                             "XRef target is in the middle of an instruction (referred from {0})",
                             start.Source);
                    return(null);
                }
                BasicBlock[] subBlocks = BasicBlocks.SplitBasicBlock(block, ip, image);

                // Create a xref from the previous block to this block.
                XRef xref = CreateFallThroughXRef(GetLastInstructionInBasicBlock(subBlocks[0]), ip);
                xrefs.Add(xref);

                return(null);
            }
            // TODO: Move the above into a separate procedure.

            // Analyze each instruction in sequence until we encounter
            // analyzed code, flow instruction, or an error condition.
            BasicBlockType blockType = BasicBlockType.Unknown;
            while (true)
            {
                // Decode an instruction at this location.
                Address     instructionStart = ip;
                Instruction insn             = CreateInstruction(ip, start);
                if (insn == null)
                {
                    AddError(ip, ErrorCode.BrokenBasicBlock,
                             "Basic block ended prematurally because of invalid instruction.");
                    blockType = BasicBlockType.Broken;
                    break;
                }
                Address instructionEnd = ip + insn.EncodedLength;

                // Advance the instruction pointer.
                ip = instructionEnd;

                // Determine whether this instruction affects control flow.
                XRefType flowType = GetFlowInstructionType(insn.Operation);

                if (flowType != XRefType.None)
                {
                    // Creates an active cross reference if necessary.
                    if (NeedsActiveXRef(flowType))
                    {
                        XRef xref = CreateFlowXRef(flowType, instructionStart, insn);
                        if (xref != null)
                        {
                            xrefs.Add(xref);
                        }
                    }

                    // Creates a fall-through cross reference if necessary.
                    if (CanFallThrough(flowType))
                    {
                        XRef xref = CreateFallThroughXRef(instructionStart, instructionEnd);
                        xrefs.Add(xref);
                    }

                    // Terminate the block.
                    blockType = GetBasicBlockType(flowType);
                    break;
                }

                // If the new location is already analyzed as code, create a
                // control-flow edge from the previous block to the existing
                // block, and we are done.
                if (!image.IsAddressValid(ip))
                {
                    blockType = BasicBlockType.Broken;
                    break;
                }
                if (image[ip].Type == ByteType.Code)
                {
                    System.Diagnostics.Debug.Assert(image[ip].IsLeadByte);

                    XRef xref = CreateFallThroughXRef(instructionStart, instructionEnd);
                    xrefs.Add(xref);
                    blockType = BasicBlockType.FallThrough;
                    break;
                }
            }

            // Create a basic block unless we failed on the first instruction.
            if (ip.Offset > start.Target.Offset)
            {
                BasicBlock block = new BasicBlock(start.Target, ip, blockType, image);
                BasicBlocks.Add(block);
            }
            return(null);
        }
Exemplo n.º 7
0
        //Constructors
        public BasicBlock(BasicBlockType bb, Function func)
        {
            _ID          = new IDManager(bb.ID.Value);
            parent       = func;
            PolyRequired = bb.PolyRequired.Exists() ? bb.PolyRequired.Value : false;
            if (bb.Predecessors.Exists())
            {
                foreach (string pid in bb.Predecessors.Value.Split(' '))
                {
                    RefPredecessors.Add(pid);
                }
            }
            if (bb.Successors.Exists())
            {
                foreach (string sid in bb.Successors.Value.Split(' '))
                {
                    RefSuccessors.Add(sid);
                }
            }
            // Adding instructions to basic block
            foreach (InstructionType instr in bb.Instruction)
            {
                Instructions.Add(new Instruction(instr, this));
            }

            // Trying to link real successors to this basic block
            switch (RefSuccessors.Count)
            {
            case 1:
                if (parent.BasicBlocks.ConvertAll(y => y.ID).Contains(RefSuccessors[0]))
                {
                    Successors.Add(parent.BasicBlocks.Find(y => y.ID == RefSuccessors[0]));
                    RefSuccessors.Clear();
                }
                break;

            case 2:
                if (parent.BasicBlocks.ConvertAll(y => y.ID).Contains(RefSuccessors[0]))
                {
                    Successors.Insert(0, parent.BasicBlocks.Find(y => y.ID == RefSuccessors[0]));
                }
                else if (parent.BasicBlocks.ConvertAll(y => y.ID).Contains(RefSuccessors[1]))
                {
                    Successors.Add(parent.BasicBlocks.Find(y => y.ID == RefSuccessors[1]));
                }
                if (Successors.Count == 2)
                {
                    RefSuccessors.Clear();
                }
                break;

            default:
                break;
            }

            // Trying to link real predecessors to this basic block
            if (RefPredecessors.Count() > 0)
            {
                RefPredecessors.ForEach(x => { parent.BasicBlocks.ForEach(y => { if (y.ID == x)
                                                                                 {
                                                                                     Predecessors.Add(y);
                                                                                 }
                                                                          }); });
            }
            Predecessors.ForEach(x => RefPredecessors.Remove(x.ID));

            // Trying to link this (new) basic block as predecessor/successor to other basic blocks of the function
            foreach (BasicBlock block in parent.BasicBlocks)
            {
                if (block.RefPredecessors.Contains(ID))
                {
                    block.Predecessors.Add(this);
                    block.RefPredecessors.Remove(ID);
                }

                if (block.RefSuccessors.Contains(ID))
                {
                    switch (block.RefSuccessors.Count)
                    {
                    case 1:
                        block.Successors.Add(this);
                        block.RefSuccessors.Clear();
                        break;

                    case 2:
                        if (block.RefSuccessors[0] == ID)
                        {
                            block.Successors.Insert(0, this);
                        }
                        else
                        {
                            block.Successors.Add(this);
                        }
                        if (block.Successors.Count == 2)
                        {
                            block.RefSuccessors.Clear();
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
        }
Exemplo n.º 8
0
 public BasicBlock(Guid id, BasicBlockType type, int lineNumber)
 {
     ID         = id;
     Type       = type;
     LineNumber = lineNumber;
 }