예제 #1
0
파일: Scanner.cs 프로젝트: ghmole/reko
        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);
        }
예제 #2
0
        public void Usb_NameWithoutSignature()
        {
            Given_Procedure(0x1000);
            Given_UserName(0x1000, "usrName");
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);
            Assert.AreEqual("usrName", proc.Name);
        }
예제 #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);
        }
예제 #4
0
        public void Usb_Word32()
        {
            Given_Procedure(0x1000);
            Given_UserSignature(0x1000, "void test(word32 foo)");
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);
            Assert.AreEqual("(fn void (word32))", proc.Signature.ToString());
            Assert.AreSame(PrimitiveType.Word32, proc.Signature.Parameters[0].DataType);
        }
예제 #5
0
        public void Usb_NoDecompileProcedure()
        {
            Given_UnscannedProcedure(0x1000);
            Given_UserSignature(0x01000, "void test([[reko::arg(register,\"ecx\")]] float f)");
            Given_UserProcDecompileFlag(0x1000, false);

            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);
        }
예제 #6
0
        public void Usb_BuildSignature_Stdcall()
        {
            Given_Procedure(0x1000);
            Given_UserSignature(0x01000, "char * __stdcall test(int i, float f, double d)");

            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);

            Assert.AreEqual(20, proc.Signature.StackDelta);
        }
예제 #7
0
        public void Usb_BuildSignature()
        {
            Given_Procedure(0x1000);
            var ser = mr.Stub <ProcedureSerializer>(arch, null, "cdecl");

            platform.Expect(s => s.CreateProcedureSerializer(null, null)).IgnoreArguments().Return(ser);
            ser.Expect(s => s.Deserialize(
                           Arg <SerializedSignature> .Is.NotNull,
                           Arg <Frame> .Is.NotNull)).Return(new ProcedureSignature());
            mr.ReplayAll();

            var usb = new UserSignatureBuilder(program);
            var sig = usb.BuildSignature("int foo(char *)", proc.Frame);

            mr.ReplayAll();
        }
예제 #8
0
        public void Usb_BuildSignature_KeepRegisterType()
        {
            Given_Procedure(0x1000);
            Given_UserSignature(0x01000, "void test([[reko::arg(register,\"ecx\")]] float f)");

            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);

            var ass = proc.Statements
                      .Select(stm => stm.Instruction as Assignment)
                      .Where(instr => instr != null)
                      .Single();

            Assert.AreEqual("ecx = f", ass.ToString());
            // verify that data type of register was not overwritten
            Assert.AreEqual("word32", ass.Dst.DataType.ToString());
            Assert.AreEqual("real32", ass.Src.DataType.ToString());
        }