Reko.Scanning.Scanner.ScanProcedure C# (CSharp) Method

ScanProcedure() public method

Performs a scan of the blocks that constitute a procedure named procedureName
public ScanProcedure ( Address addr, string procedureName, ProcessorState state ) : ProcedureBase
addr Address Address of the code from which we will start scanning.
procedureName string
state ProcessorState
return ProcedureBase
        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;
        }

Usage Example

示例#1
0
        public void Scanner_UserProcedure_GenerateSignature()
        {
            Given_Program(Address.Ptr32(0x00100000), new byte[100]);
            Given_Project();
            program.User.Procedures.Add(
                Address.Ptr32(0x00100010),
                new Procedure_v1
                {
                    CSignature = "int foo(char * a, float b)"
                });
            mr.ReplayAll();

            var scanner = new Scanner(
                this.program,
                new ImportResolver(project, program, eventListener),
                this.sc);
            var proc = scanner.ScanProcedure(
                Address.Ptr32(0x00100010),
                null,
                fakeArch.CreateProcessorState());

            Assert.AreEqual("foo", proc.Name);
            Assert.AreEqual("Register int32 foo(Stack (ptr char) a, Stack real32 b)", proc.Signature.ToString(proc.Name));
        }