Exemple #1
0
        public override void Process()
        {
            var builder = new VectorBuilder(scanner, program, new DirectedGraphImpl <object>());
            var vector  = builder.Build(Table.TableAddress, AddrFrom, State);

            if (vector.Count == 0)
            {
                Address addrNext = Table.TableAddress + Stride.Size;
                if (program.Image.IsValidAddress(addrNext))
                {
                    // Can't determine the size of the table, but surely it has one entry?
                    program.ImageMap.AddItem(addrNext, new ImageMapItem());
                }
                return;
            }

            Table.Addresses.AddRange(vector);
            for (int i = 0; i < vector.Count; ++i)
            {
                var st = State.Clone();
                if (Table.IsCallTable)
                {
                    scanner.ScanProcedure(vector[i], null, st);
                }
                else
                {
                    //$TODO: BlockFromAddress.
                    scanner.EnqueueJumpTarget(AddrFrom, vector[i], proc, st);
                }
            }
            vectorUses[AddrFrom] = new VectorUse(Table.TableAddress, builder.IndexRegister);
            program.ImageMap.AddItem(Table.TableAddress + builder.TableByteSize, new ImageMapItem());
        }
Exemple #2
0
        public ProcedureBase ScanProcedure(IProcessorArchitecture arch, Address addr, string?procedureName, ProcessorState state)
        {
            TerminateAnyBlockAt(addr);
            if (TryGetNoDecompiledProcedure(addr, out var ep))
            {
                return(ep);
            }
            if (Program.InterceptedCalls.TryGetValue(addr, out ep))
            {
                return(ep);
            }
            var trampoline = GetTrampoline(arch, addr);

            if (trampoline != null)
            {
                return(trampoline);
            }

            var imp = GetImportedProcedure(arch, addr, addr);

            if (imp != null)
            {
                return(imp);
            }
            Procedure proc = Program.EnsureProcedure(arch, addr, procedureName);

            if (visitedProcs.Contains(proc))
            {
                return(proc);
            }

            visitedProcs.Add(proc);
            trace.Inform("Scanning procedure at {0}", addr);

            var st = state.Clone();

            EstablishInitialState(addr, st, proc);

            //$REFACTOR: make the stack explicit?
            var oldQueue = procQueue;

            procQueue = new PriorityQueue <WorkItem>();
            var block = EnqueueJumpTarget(addr, addr, proc, st);

            if (proc.EntryBlock.Succ.Count == 0)
            {
                proc.ControlGraph.AddEdge(proc.EntryBlock, block !);
            }
            ProcessQueue();

            procQueue = oldQueue;

            InjectProcedureEntryInstructions(addr, proc);
            var usb = new UserSignatureBuilder(Program);

            usb.BuildSignature(addr, proc);
            cinj.InjectComments(proc);
            return(proc);
        }
Exemple #3
0
        /// <summary>
        /// Performs a scan of the blocks that constitute a procedure named <paramref name="procedureName"/>
        /// </summary>
        /// <param name="addr">Address of the code from which we will start scanning.</param>
        /// <param name="procedureName"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public ProcedureBase ScanProcedure(Address addr, string procedureName, ProcessorState state)
        {
            TerminateAnyBlockAt(addr);
            ExternalProcedure ep;

            if (TryGetNoDecompiledProcedure(addr, out ep))
            {
                return(ep);
            }
            if (program.InterceptedCalls.TryGetValue(addr, out ep))
            {
                return(ep);
            }
            var trampoline = GetTrampoline(addr);

            if (trampoline != null)
            {
                return(trampoline);
            }

            var imp = GetImportedProcedure(addr, addr);

            if (imp != null)
            {
                return(imp);
            }
            Procedure proc = EnsureProcedure(addr, procedureName);

            if (visitedProcs.Contains(proc))
            {
                return(proc);
            }

            visitedProcs.Add(proc);
            Debug.WriteLineIf(trace.TraceInfo, string.Format("Scanning procedure at {0}", addr));

            var st = state.Clone();

            EstablishInitialState(addr, st, proc);

            //$REFACTOR: make the stack explicit?
            var oldQueue = queue;

            queue = new PriorityQueue <WorkItem>();
            var block = EnqueueJumpTarget(addr, addr, proc, st);

            proc.ControlGraph.AddEdge(proc.EntryBlock, block);
            ProcessQueue();

            queue = oldQueue;

            InjectProcedureEntryInstructions(addr, proc);
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(addr, proc);
            return(proc);
        }
Exemple #4
0
        /// <summary>
        /// Performs a scan of the blocks that constitute a procedure named <paramref name="procedureName"/>
        /// </summary>
        /// <param name="addr">Address of the code from which we will start scanning.</param>
        /// <param name="procedureName"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public ProcedureBase ScanProcedure(Address addr, string procedureName, ProcessorState state)
        {
            TerminateAnyBlockAt(addr);
            ExternalProcedure ep;

            if (program.InterceptedCalls.TryGetValue(addr, out ep))
            {
                return(ep);
            }
            var trampoline = GetTrampoline(addr);

            if (trampoline != null)
            {
                return(trampoline);
            }

            var imp = GetImportedProcedure(addr, addr);

            if (imp != null)
            {
                return(imp);
            }
            Procedure proc = EnsureProcedure(addr, procedureName);

            if (visitedProcs.Contains(proc))
            {
                return(proc);
            }

            visitedProcs.Add(proc);
            Debug.WriteLineIf(trace.TraceInfo, string.Format("Scanning procedure at {0}", addr));

            //$REFACTOR: make the stack explicit?
            var oldQueue = queue;

            queue = new PriorityQueue <WorkItem>();
            var st = state.Clone();

            st.SetInstructionPointer(addr);
            st.OnProcedureEntered();
            var sp = proc.Frame.EnsureRegister(program.Architecture.StackRegister);

            st.SetValue(sp, proc.Frame.FramePointer);
            SetAssumedRegisterValues(addr, st);
            var block = EnqueueJumpTarget(addr, addr, proc, st);

            proc.ControlGraph.AddEdge(proc.EntryBlock, block);
            ProcessQueue();
            queue = oldQueue;

            // Add <stackpointer> := fp explicitly to the starting block.
            EstablishFrame(addr, proc, sp);
            return(proc);
        }
Exemple #5
0
        public void EnqueueVectorTable(Address addrFrom, Address addrTable, PrimitiveType elemSize, ushort segBase, bool calltable, Procedure proc, ProcessorState state)
        {
            ImageMapVectorTable table;

            if (vectors.TryGetValue(addrTable, out table))
            {
                return;
            }

            table = new ImageMapVectorTable(addrTable, calltable);
            var wi = new VectorWorkItem(this, program, table, proc);

            wi.State    = state.Clone();
            wi.Stride   = elemSize;
            wi.SegBase  = segBase;
            wi.Table    = table;
            wi.AddrFrom = addrFrom;

            imageMap.AddItem(addrTable, table);
            vectors[addrTable] = table;
            queue.Enqueue(PriorityVector, wi);
        }
        Instruction ConditionalBranch(ProcessorState state, Func<Expression, BinaryExpression> condition)
        {
            var val1 = state.Stack.Pop();
            var test = condition(val1);

            var left = (Instruction) state.Instruction.Operand;
            var right = state.Instruction.Next;

            Instruction common = GetJoinPoint(left, right);

            var rightState = state.Clone(right, common);
            var leftState = state.Clone(left, common);
            states.Push(rightState);
            states.Push(leftState);

            // Run this once the conditional branches have been processed
            state.RunNext = () => state.Merge(test, leftState, rightState);

            return common;
        }
Exemple #7
0
        /// <summary>
        /// Branches need to terminate the current basic block and make links
        /// to the 'true' and 'false' destinations.
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool VisitBranch(RtlBranch b)
        {
            // We don't know the 'then' block yet, as the following statements may chop up the block
            // we're presently in. Back-patch in when the block target is obtained.
            var branch = new Branch(b.Condition, new Block(blockCur.Procedure, "TMP!"));

            Emit(branch, blockCur);

            // The following statements may chop up the blockCur, so hang on to the essentials.
            var proc = blockCur.Procedure;
            RtlInstructionCluster ricDelayed = null;

            if ((b.Class & RtlClass.Delay) != 0)
            {
                rtlStream.MoveNext();
                ricDelayed = rtlStream.Current;
                ric        = ricDelayed;
            }
            var fallthruAddress = ric.Address + ric.Length;

            Block blockThen;

            if (!program.SegmentMap.IsValidAddress((Address)b.Target))
            {
                blockThen = proc.AddBlock(this.ric.Address.GenerateName("l", "_then"));
                var jmpSite = state.OnBeforeCall(stackReg, arch.PointerType.Size);
                GenerateCallToOutsideProcedure(jmpSite, (Address)b.Target);
                Emit(new ReturnInstruction());
                blockCur.Procedure.ControlGraph.AddEdge(blockCur, blockCur.Procedure.ExitBlock);
            }
            else
            {
                blockThen = BlockFromAddress(ric.Address, (Address)b.Target, proc, state.Clone());
            }

            var blockElse      = FallthroughBlock(ric.Address, proc, fallthruAddress);
            var branchingBlock = blockCur.IsSynthesized
                ? blockCur
                : scanner.FindContainingBlock(ric.Address);

            if ((b.Class & RtlClass.Delay) != 0 &&
                ricDelayed.Instructions.Length > 0)
            {
                // Introduce stubs for the delay slot, but only
                // if the delay slot isn't empty.

                if ((b.Class & RtlClass.Annul) != 0)
                {
                    EnsureEdge(proc, branchingBlock, blockElse);
                }
                else
                {
                    Block blockDsF = null;
                    blockDsF = proc.AddBlock(branchingBlock.Name + "_ds_f");
                    blockDsF.IsSynthesized = true;
                    blockCur = blockDsF;
                    ProcessRtlCluster(ricDelayed);
                    EnsureEdge(proc, blockDsF, blockElse);
                    EnsureEdge(proc, branchingBlock, blockDsF);
                }

                Block blockDsT = proc.AddBlock(branchingBlock.Name + "_ds_t");
                blockDsT.IsSynthesized = true;
                blockCur = blockDsT;
                ProcessRtlCluster(ricDelayed);
                EnsureEdge(proc, blockDsT, blockThen);
                branch.Target = blockDsT;
                EnsureEdge(proc, branchingBlock, blockDsT);
            }
            else
            {
                branch.Target = blockThen;      // The back-patch referred to above.
                EnsureEdge(proc, branchingBlock, blockElse);
                if (blockElse != blockThen)
                {
                    EnsureEdge(proc, branchingBlock, blockThen);
                }
                else
                {
                    proc.ControlGraph.AddEdge(branchingBlock, blockThen);
                }
            }
            if (BlockHasBeenScanned(blockElse))
            {
                return(false);
            }
            else
            {
                blockCur = blockElse;
                return(true);
            }
        }