Esempio n. 1
0
        public void TrfPropagateStackValuesToSuccessor()
        {
            m.Label("Start");
            Identifier ecx = m.Register(1);

            trf = CreateTrashedRegisterFinder(prog);
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            trf.StackSymbolicValues[-4]  = ecx;
            trf.StackSymbolicValues[-8]  = ecx;
            trf.StackSymbolicValues[-12] = ecx;
            trf.StackSymbolicValues[-16] = m.Word32(0x1234);
            trf.StackSymbolicValues[-20] = m.Word32(0x5678);
            trf.StackSymbolicValues[-24] = m.Word32(0x9ABC);

            var succ = new Block(m.Procedure, "succ");
            var sf   = CreateBlockFlow(succ, m.Frame);

            flow[succ] = sf;
            sf.SymbolicIn.StackState[-8]  = ecx;
            sf.SymbolicIn.StackState[-12] = Constant.Word32(1231);
            sf.SymbolicIn.StackState[-20] = Constant.Word32(0x5678);
            sf.SymbolicIn.StackState[-24] = Constant.Word32(0xCCCC);

            trf.PropagateToSuccessorBlock(succ);

            Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-4].ToString(), "Didn't have a value before");
            Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-8].ToString(), "Same value as before");
            Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-12].ToString());
            Assert.AreEqual("0x00001234", sf.SymbolicIn.StackState[-16].ToString());
            Assert.AreEqual("0x00005678", sf.SymbolicIn.StackState[-20].ToString());
            Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-24].ToString());
        }
Esempio n. 2
0
        protected override void RunTest(Program prog, TextWriter writer)
        {
            var flow          = new ProgramDataFlow(prog);
            var eventListener = new FakeDecompilerEventListener();
            var trf           = new TrashedRegisterFinder(prog, prog.Procedures.Values, flow, eventListener);

            trf.Compute();
            trf.RewriteBasicBlocks();
            Dump(prog.CallGraph);
            var rl = RegisterLiveness.Compute(prog, flow, eventListener);

            GlobalCallRewriter.Rewrite(prog, flow);

            foreach (Procedure proc in prog.Procedures.Values)
            {
                Aliases alias = new Aliases(proc, prog.Architecture);
                alias.Transform();
                var          gr  = proc.CreateBlockDominatorGraph();
                SsaTransform sst = new SsaTransform(flow, proc, gr);
                ssa = sst.SsaState;
                ssa.Write(writer);
                proc.Write(false, true, writer);
                writer.WriteLine();
            }
        }
        private void ProcessScc(IList <Procedure> scc)
        {
            var procSet = scc.ToHashSet();
            var sstSet  = new HashSet <SsaTransform>();

            foreach (var proc in scc)
            {
                var sst = new SsaTransform(
                    program,
                    proc,
                    procSet,
                    dynamicLinker.Object,
                    dataFlow);
                sst.Transform();
                sst.AddUsesToExitBlock();
                var vp = new ValuePropagator(
                    program.SegmentMap,
                    sst.SsaState,
                    program.CallGraph,
                    dynamicLinker.Object,
                    NullDecompilerEventListener.Instance);
                vp.Transform();
                sstSet.Add(sst);
            }

            var trf = new TrashedRegisterFinder(
                program,
                dataFlow,
                sstSet,
                NullDecompilerEventListener.Instance);

            trf.Compute();
        }
Esempio n. 4
0
        public void TrfPropagateToProcedureSummary()
        {
            Procedure proc = new Procedure("proc", prog.Architecture.CreateFrame());

            prog.CallGraph.AddProcedure(proc);
            Identifier eax = proc.Frame.EnsureRegister(Registers.eax);
            Identifier ebx = proc.Frame.EnsureRegister(Registers.ebx);
            Identifier ecx = proc.Frame.EnsureRegister(Registers.ecx);
            Identifier esi = proc.Frame.EnsureRegister(Registers.esi);

            flow[proc] = new ProcedureFlow(proc, prog.Architecture);

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(proc.ExitBlock, proc.Frame);
            trf.StartProcessingBlock(proc.ExitBlock);

            trf.RegisterSymbolicValues[(RegisterStorage)eax.Storage] = eax;                     // preserved
            trf.RegisterSymbolicValues[(RegisterStorage)ebx.Storage] = ecx;                     // trashed
            trf.RegisterSymbolicValues[(RegisterStorage)esi.Storage] = Constant.Invalid;        // trashed
            trf.PropagateToProcedureSummary(proc);
            ProcedureFlow pf = flow[proc];

            Assert.AreEqual(" ebx esi", pf.EmitRegisters(prog.Architecture, "", pf.TrashedRegisters));
            Assert.AreEqual(" eax", pf.EmitRegisters(prog.Architecture, "", pf.PreservedRegisters));
        }
        public void TrfBackpropagateStackPointer()
        {
            var esp = m.Frame.EnsureRegister(Registers.esp);
            var ebp = m.Frame.EnsureRegister(Registers.ebp);
            var esi = m.Frame.EnsureRegister(Registers.esi);

            Given_TrashedRegisters(esp, esi, ebp);
            Given_Procedure(m =>
            {
                m.Assign(esp, m.ISub(esp, 4));
                m.MStore(esp, ebp);
                m.Assign(esp, m.ISub(esp, 4));
                m.MStore(esp, esi);
                m.Call(esi, 4);
                m.Assign(esi, m.Mem32(esp));
                m.Assign(esp, m.IAdd(esp, 4));
                m.Assign(ebp, m.Mem32(esp));
                m.Assign(esp, m.IAdd(esp, 4));
                m.Return();
            });

            trf = CreateTrashedRegisterFinder(true);
            trf.Compute();

            AssertPreservedRegisters("ebp esi esp");
        }
Esempio n. 6
0
        protected override void RunTest(Program prog, TextWriter writer)
        {
            var flow           = new ProgramDataFlow(prog);
            var eventListener  = new FakeDecompilerEventListener();
            var importResolver = MockRepository.GenerateStub <IImportResolver>();

            importResolver.Replay();
            var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, flow, eventListener);

            trf.Compute();
            trf.RewriteBasicBlocks();
            Dump(prog.CallGraph);
            RegisterLiveness.Compute(prog, flow, eventListener);
            GlobalCallRewriter.Rewrite(prog, flow, eventListener);

            foreach (Procedure proc in prog.Procedures.Values)
            {
                Aliases alias = new Aliases(proc, prog.Architecture);
                alias.Transform();
                var          gr  = proc.CreateBlockDominatorGraph();
                SsaTransform sst = new SsaTransform(
                    flow,
                    proc,
                    importResolver,
                    gr,
                    new HashSet <RegisterStorage>());
                ssa = sst.SsaState;
                ssa.Write(writer);
                proc.Write(false, true, writer);
                writer.WriteLine();
                ssa.CheckUses(s => Assert.Fail(s));
            }
        }
Esempio n. 7
0
 protected override void RunTest(Program prog, TextWriter writer)
 {
     this.prog = prog;
     flow      = new ProgramDataFlow(prog);
     trf       = CreateTrashedRegisterFinder();
     trf.Compute();
     DumpProcedureSummaries(writer);
 }
		protected override void RunTest(Program prog, TextWriter writer)
		{
			var eventListener = new FakeDecompilerEventListener();
			var dfa = new DataFlowAnalysis(prog, eventListener);
			var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener);
			trf.Compute();
			trf.RewriteBasicBlocks();
			var rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener);
			DumpProcedureFlows(prog, dfa, rl, writer);
		}
Esempio n. 9
0
        public void TrashFlag()
        {
            var scz = m.Frame.EnsureFlagGroup(0x7, arch.GrfToString(0x7), PrimitiveType.Byte);
            var stm = m.Assign(scz, m.Int32(3));

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);
            stm.Accept(trf);
            Assert.AreEqual(0x7, trf.TrashedFlags);
        }
Esempio n. 10
0
        public void TrfOutParameters()
        {
            var r2  = m.Register(2);
            var stm = m.SideEffect(m.Fn("Hello", m.AddrOf(r2)));

            trf = CreateTrashedRegisterFinder();
            trf.EnsureEvaluationContext(CreateBlockFlow(m.Block, m.Frame));

            stm.Instruction.Accept(trf);
            Assert.AreEqual("<invalid>", trf.RegisterSymbolicValues[(RegisterStorage)r2.Storage].ToString());
        }
Esempio n. 11
0
        public void TrashCompoundRegister()
        {
            Identifier ax  = m.Frame.EnsureRegister(Registers.ax);
            var        stm = m.Assign(ax, 1);

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            stm.Accept(trf);
            Assert.AreEqual("(ax:0x0001)", DumpValues());
        }
Esempio n. 12
0
        protected override void RunTest(Program prog, TextWriter writer)
        {
            var eventListener = new FakeDecompilerEventListener();
            var dfa           = new DataFlowAnalysis(prog, null, eventListener);
            var trf           = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener);

            trf.Compute();
            trf.RewriteBasicBlocks();
            var rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener);

            DumpProcedureFlows(prog, dfa, rl, writer);
        }
Esempio n. 13
0
        public void TrashRegister()
        {
            var r1  = m.Register(1);
            var stm = m.Assign(r1, m.Int32(0));

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            stm.Accept(trf);
            Debug.WriteLine(trf.RegisterSymbolicValues[(RegisterStorage)r1.Storage].ToString());
            Assert.IsTrue(trf.IsTrashed(r1.Storage), "r1 should have been marked as trashed.");
        }
Esempio n. 14
0
        public void TrfCopy()
        {
            Identifier r1  = m.Register(1);
            Identifier r2  = m.Register(2);
            var        ass = m.Assign(r2, r1);

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            ass.Accept(trf);
            Assert.AreEqual(r1, trf.RegisterSymbolicValues[(RegisterStorage)r2.Storage], "r2 should now be equal to r1");
        }
Esempio n. 15
0
        public void TrfTerminatingProcedure()
        {
            var eax = m.Procedure.Frame.EnsureRegister(Registers.eax);

            m.Assign(eax, m.Word32(0x40));
            m.Call(exit, 4);

            flow[m.Block] = CreateBlockFlow(m.Block, m.Frame);
            flow[exit]    = new ProcedureFlow(exit, prog.Architecture);
            flow[exit].TerminatesProcess = true;
            trf = CreateTrashedRegisterFinder(prog);
            trf.ProcessBlock(m.Block);
            Assert.AreEqual("", DumpValues());
        }
        private void RunTest(Program prog, TextWriter writer)
        {
            flow = new ProgramDataFlow(prog);
            trf  = new TrashedRegisterFinder(prog, prog.Procedures.Values, this.flow, new FakeDecompilerEventListener());
            trf.Compute();
            trf.RewriteBasicBlocks();

            foreach (var proc in prog.Procedures.Values)
            {
                flow[proc].EmitRegisters(arch, "// Trashed", flow[proc].TrashedRegisters);
                proc.Write(false, writer);
                writer.WriteLine();
            }
        }
        private void RunTest(Program prog, TextWriter writer)
        {
            flow = new ProgramDataFlow(prog);
            trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, this.flow, new FakeDecompilerEventListener());
            trf.Compute();
            trf.RewriteBasicBlocks();

            foreach (var proc in prog.Procedures.Values)
            {
                flow[proc].EmitRegisters(arch, "// Trashed", flow[proc].TrashedRegisters);
                proc.Write(false, writer);
                writer.WriteLine();
            }
        }
Esempio n. 18
0
        public void TrfProcessBlock()
        {
            Identifier eax = m.Procedure.Frame.EnsureRegister(Registers.eax);
            Identifier esp = m.Procedure.Frame.EnsureRegister(Registers.esp);

            m.Store(m.ISub(esp, 4), eax);
            m.Assign(eax, m.Int32(3));
            m.Assign(eax, m.LoadDw(m.ISub(esp, 4)));

            flow[m.Block] = CreateBlockFlow(m.Block, m.Frame);
            flow[m.Block].SymbolicIn.SetValue(esp, m.Frame.FramePointer);
            trf = CreateTrashedRegisterFinder(prog);
            trf.ProcessBlock(m.Block);
            Assert.AreEqual("(eax:eax), (esp:fp), (Stack -4:eax)", DumpValues());
        }
Esempio n. 19
0
 protected override void RunTest(Program prog, TextWriter writer)
 {
     var dfa = new DataFlowAnalysis(prog, new FakeDecompilerEventListener());
     var eventListener = new FakeDecompilerEventListener();
     var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener);
     trf.Compute();
     trf.RewriteBasicBlocks();
     RegisterLiveness rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener);
     foreach (Procedure proc in prog.Procedures.Values)
     {
         LongAddRewriter larw = new LongAddRewriter(proc, prog.Architecture);
         larw.Transform();
         proc.Write(false, writer);
         writer.WriteLine();
     }
 }
Esempio n. 20
0
        public void TrfCallInstruction()
        {
            var callee = new Procedure("Callee", prog.Architecture.CreateFrame());
            var stm    = m.Call(callee, 4);
            var pf     = new ProcedureFlow(callee, prog.Architecture);

            pf.TrashedRegisters[Registers.ebx.Number] = true;
            flow[callee] = pf;

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            stm.Instruction.Accept(trf);
            Assert.AreEqual("(ebx:<invalid>)", DumpValues());
        }
Esempio n. 21
0
        public void TrfPropagateFlagsToProcedureSummary()
        {
            var proc = new Procedure("proc", prog.Architecture.CreateFrame());

            prog.CallGraph.AddProcedure(proc);
            var flags = prog.Architecture.GetFlagGroup("SZ");
            var sz    = m.Frame.EnsureFlagGroup(flags.FlagGroupBits, flags.Name, flags.DataType);
            var stm   = m.Assign(sz, m.Int32(3));

            flow[proc] = new ProcedureFlow(proc, prog.Architecture);
            trf        = CreateTrashedRegisterFinder(prog);
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);
            stm.Accept(trf);
            trf.PropagateToProcedureSummary(proc);
            Assert.AreEqual(" SZ", flow[proc].EmitFlagGroup(prog.Architecture, "", flow[proc].grfTrashed));
        }
Esempio n. 22
0
        private void RunTest(ProgramBuilder p, string sExp)
        {
            prog = p.BuildProgram(arch);

            flow = new ProgramDataFlow(prog);
            trf  = CreateTrashedRegisterFinder();
            trf.Compute();

            var summary = DumpProcedureSummaries().Trim();

            if (sExp == summary)
            {
                return;
            }
            Console.WriteLine(summary);
            Assert.AreEqual(sExp, summary);
        }
Esempio n. 23
0
        protected override void RunTest(Program prog, TextWriter writer)
        {
            var eventListener = new FakeDecompilerEventListener();
            var dfa           = new DataFlowAnalysis(prog, null, eventListener);
            var trf           = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener);

            trf.Compute();
            trf.RewriteBasicBlocks();
            RegisterLiveness rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener);

            foreach (Procedure proc in prog.Procedures.Values)
            {
                LongAddRewriter larw = new LongAddRewriter(proc, prog.Architecture);
                larw.Transform();
                proc.Write(false, writer);
                writer.WriteLine();
            }
        }
        public void TrfCopyBack()
        {
            var esp  = m.Frame.EnsureRegister(Registers.esp);
            var r2   = m.Register(2);
            var stm1 = m.Store(m.ISub(esp, 0x10), r2);
            var stm2 = m.Assign(r2, m.Int32(0));
            var stm3 = m.Assign(r2, m.Mem32(m.ISub(esp, 0x10)));

            trf = CreateTrashedRegisterFinder();
            var flow = CreateBlockFlow(m.Block, m.Frame);

            flow.SymbolicIn.SetValue((Identifier)esp, (Expression)this.m.Frame.FramePointer);
            trf.StartProcessingBlock(m.Block);

            stm1.Instruction.Accept(trf);
            stm2.Accept(trf);
            stm3.Accept(trf);

            Assert.AreEqual(r2, trf.RegisterSymbolicValues[(RegisterStorage)r2.Storage]);
        }
Esempio n. 25
0
        public void TrfPropagateToSuccessorBlocks()
        {
            Procedure  proc  = new Procedure("test", prog.Architecture.CreateFrame());
            var        frame = proc.Frame;
            Identifier ecx   = m.Register(1);
            Identifier edx   = m.Register(2);
            Identifier ebx   = m.Register(3);
            Block      b     = proc.AddBlock("b");
            Block      t     = proc.AddBlock("t");
            Block      e     = proc.AddBlock("e");

            proc.ControlGraph.AddEdge(b, e);
            proc.ControlGraph.AddEdge(b, t);
            flow[t] = new BlockFlow(t, null, new SymbolicEvaluationContext(prog.Architecture, frame));
            flow[e] = new BlockFlow(e, null, new SymbolicEvaluationContext(prog.Architecture, frame));

            trf = CreateTrashedRegisterFinder(prog);
            CreateBlockFlow(b, frame);
            trf.StartProcessingBlock(b);
            trf.RegisterSymbolicValues[(RegisterStorage)ecx.Storage] = Constant.Invalid;
            trf.RegisterSymbolicValues[(RegisterStorage)edx.Storage] = ebx;

            flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage] = edx;
            flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage] = ebx;

            flow[t].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage] = Constant.Invalid;
            flow[t].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage] = edx;

            trf.PropagateToSuccessorBlock(e);
            trf.PropagateToSuccessorBlock(t);
            Assert.AreEqual(2, proc.ControlGraph.Successors(b).Count);
            Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & r2 => trash");
            Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "ebx & ebx => ebx");
            Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & r2 => trash");
            Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "ebx & ebx => ebx");

            Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & trash => trash");
            Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "r3 & r2 => trash");
        }
Esempio n. 26
0
        public void TrfPreserveEbp()
        {
            Identifier esp = m.Frame.EnsureRegister(Registers.esp);
            Identifier ebp = m.Frame.EnsureRegister(Registers.ebp);

            m.Store(esp, ebp);
            m.Assign(ebp, m.LoadDw(m.Int32(0x12345678)));
            m.Assign(ebp, m.LoadDw(esp));
            m.Return();

            Procedure proc = m.Procedure;

            prog.Procedures.Add(Address.Ptr32(0x10000), proc);
            prog.CallGraph.AddProcedure(proc);
            flow = new ProgramDataFlow(prog);

            trf = CreateTrashedRegisterFinder(prog);
            trf.Compute();
            ProcedureFlow pf = flow[proc];

            Assert.AreEqual(" esp ebp", pf.EmitRegisters(prog.Architecture, "", pf.PreservedRegisters), "ebp should have been preserved");
        }
        private void RunTest(ProgramBuilder p, string sExp)
        {
            program = p.BuildProgram(arch);

            flow = new ProgramDataFlow(program);
            trf  = CreateTrashedRegisterFinder();
            trf.Compute();

            var summary = DumpProcedureSummaries().Trim();

            if (sExp == summary)
            {
                return;
            }
            try
            {
                Assert.AreEqual(sExp, summary);
            }
            catch
            {
                Debug.Print("{0}", summary);
                throw;
            }
        }
Esempio n. 28
0
        public void TrfPropagateToProcedureSummary()
        {
            Procedure proc = new Procedure("proc", program.Architecture.CreateFrame());
            program.CallGraph.AddProcedure(proc);
            Identifier eax = proc.Frame.EnsureRegister(Registers.eax);
            Identifier ebx = proc.Frame.EnsureRegister(Registers.ebx);
            Identifier ecx = proc.Frame.EnsureRegister(Registers.ecx);
            Identifier esi = proc.Frame.EnsureRegister(Registers.esi);
            flow[proc] = new ProcedureFlow(proc, program.Architecture);

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(proc.ExitBlock, proc.Frame);
            trf.StartProcessingBlock(proc.ExitBlock);

            trf.RegisterSymbolicValues[(RegisterStorage) eax.Storage] = eax;			// preserved
            trf.RegisterSymbolicValues[(RegisterStorage) ebx.Storage] = ecx;			// trashed
            trf.RegisterSymbolicValues[(RegisterStorage) esi.Storage] = Constant.Invalid;				// trashed
            trf.PropagateToProcedureSummary(proc);
            ProcedureFlow pf = flow[proc];
            Assert.AreEqual(" ebx esi", pf.EmitRegisters(program.Architecture, "", pf.TrashedRegisters));
            Assert.AreEqual(" eax", pf.EmitRegisters(program.Architecture, "", pf.PreservedRegisters));
        }
Esempio n. 29
0
        public void TrfPropagateStackValuesToSuccessor()
        {
            m.Label("Start");
            Identifier ecx = m.Register(1);
            trf = CreateTrashedRegisterFinder(program);
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            trf.StackSymbolicValues[-4] = ecx;
            trf.StackSymbolicValues[-8] = ecx;
            trf.StackSymbolicValues[-12] = ecx;
            trf.StackSymbolicValues[-16] = m.Word32(0x1234);
            trf.StackSymbolicValues[-20] = m.Word32(0x5678);
            trf.StackSymbolicValues[-24] = m.Word32(0x9ABC);

            var succ = new Block(m.Procedure, "succ");
            var sf = CreateBlockFlow(succ, m.Frame);
            flow[succ] = sf;
            sf.SymbolicIn.StackState[-8] = ecx;
            sf.SymbolicIn.StackState[-12] = Constant.Word32(1231);
            sf.SymbolicIn.StackState[-20] = Constant.Word32(0x5678);
            sf.SymbolicIn.StackState[-24] = Constant.Word32(0xCCCC);

            trf.PropagateToSuccessorBlock(succ);

            Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-4].ToString(), "Didn't have a value before");
            Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-8].ToString(), "Same value as before");
            Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-12].ToString());
            Assert.AreEqual("0x00001234", sf.SymbolicIn.StackState[-16].ToString());
            Assert.AreEqual("0x00005678", sf.SymbolicIn.StackState[-20].ToString());
            Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-24].ToString());
        }
Esempio n. 30
0
        public void TrfPropagateToSuccessorBlocks()
        {
            Procedure proc = new Procedure("test", program.Architecture.CreateFrame());
            var frame = proc.Frame;
            Identifier ecx = m.Register(1);
            Identifier edx = m.Register(2);
            Identifier ebx = m.Register(3);
            Block b = proc.AddBlock("b");
            Block t = proc.AddBlock("t");
            Block e = proc.AddBlock("e");
            proc.ControlGraph.AddEdge(b, e);
            proc.ControlGraph.AddEdge(b, t);
            flow[t] = new BlockFlow(t, null, new SymbolicEvaluationContext(program.Architecture, frame));
            flow[e] = new BlockFlow(e, null, new SymbolicEvaluationContext(program.Architecture, frame));

            trf = CreateTrashedRegisterFinder(program);
            CreateBlockFlow(b, frame);
            trf.StartProcessingBlock(b);
            trf.RegisterSymbolicValues[(RegisterStorage) ecx.Storage] = Constant.Invalid;
            trf.RegisterSymbolicValues[(RegisterStorage) edx.Storage] = ebx;

            flow[e].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage] = edx;
            flow[e].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage] = ebx;

            flow[t].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage] = Constant.Invalid;
            flow[t].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage] = edx;

            trf.PropagateToSuccessorBlock(e);
            trf.PropagateToSuccessorBlock(t);
            Assert.AreEqual(2, proc.ControlGraph.Successors(b).Count);
            Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage].ToString(), "trash & r2 => trash");
            Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage].ToString(), "ebx & ebx => ebx");
            Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage].ToString(), "trash & r2 => trash");
            Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage].ToString(), "ebx & ebx => ebx");

            Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage].ToString(), "trash & trash => trash");
            Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage].ToString(), "r3 & r2 => trash");
        }
Esempio n. 31
0
        public void TrfCallInstruction()
        {
            var callee = new Procedure("Callee", program.Architecture.CreateFrame());
            var stm = m.Call(callee, 4);
            var pf = new ProcedureFlow(callee, program.Architecture);
            pf.TrashedRegisters.Add(Registers.ebx);
            flow[callee] = pf;

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            stm.Instruction.Accept(trf);
            Assert.AreEqual("(ebx:<invalid>)", DumpValues());
        }
Esempio n. 32
0
        public void TrfOutParameters()
        {
            var r2 = m.Register(2);
            var stm = m.SideEffect(m.Fn("Hello", m.AddrOf(r2)));

            trf = CreateTrashedRegisterFinder();
            trf.EnsureEvaluationContext(CreateBlockFlow(m.Block, m.Frame));

            stm.Instruction.Accept(trf);
            Assert.AreEqual("<invalid>", trf.RegisterSymbolicValues[(RegisterStorage) r2.Storage].ToString());
        }
Esempio n. 33
0
        public void TrfProcessBlock()
        {
            Identifier eax = m.Procedure.Frame.EnsureRegister(Registers.eax);
            Identifier esp = m.Procedure.Frame.EnsureRegister(Registers.esp);
            m.Store(m.ISub(esp, 4), eax);
            m.Assign(eax, m.Int32(3));
            m.Assign(eax, m.LoadDw(m.ISub(esp, 4)));

            flow[m.Block] = CreateBlockFlow(m.Block, m.Frame);
            flow[m.Block].SymbolicIn.SetValue(esp, m.Frame.FramePointer);
            trf = CreateTrashedRegisterFinder(program);
            trf.ProcessBlock(m.Block);
            Assert.AreEqual("(eax:eax), (esp:fp), (Stack -4:eax)", DumpValues());
        }
Esempio n. 34
0
        public void TrashCompoundRegister()
        {
            Identifier ax = m.Frame.EnsureRegister(Registers.ax);
            var stm = m.Assign(ax, 1);

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            stm.Accept(trf);
            Assert.AreEqual("(ax:0x0001)", DumpValues());
        }
Esempio n. 35
0
        public void TrashFlag()
        {
            var flags = arch.GetFlagGroup(0x7).FlagRegister;
            var scz = m.Frame.EnsureFlagGroup(flags, 0x7, arch.GrfToString(0x7), PrimitiveType.Byte);
            var stm = m.Assign(scz, m.Int32(3));

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);
            stm.Accept(trf);
            Assert.AreEqual(0x7, trf.TrashedFlags);
        }
Esempio n. 36
0
        public void TrashRegister()
        {
            var r1 = m.Register(1);
            var stm = m.Assign(r1, m.Int32(0));

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            stm.Accept(trf);
            Debug.WriteLine(trf.RegisterSymbolicValues[(RegisterStorage) r1.Storage].ToString());
            Assert.IsTrue(trf.IsTrashed(r1.Storage), "r1 should have been marked as trashed.");
        }
Esempio n. 37
0
 protected override void RunTest(Program prog, TextWriter writer)
 {
     this.program = prog;
     flow = new ProgramDataFlow(prog);
     trf = CreateTrashedRegisterFinder();
     trf.Compute();
     DumpProcedureSummaries(writer);
 }
Esempio n. 38
0
        private void RunTest(ProgramBuilder p, string sExp)
        {
            program = p.BuildProgram(arch);

            flow = new ProgramDataFlow(program);
            trf = CreateTrashedRegisterFinder();
            trf.Compute();

            var summary = DumpProcedureSummaries().Trim();
            if (sExp == summary)
                return;
            try
            {
                Assert.AreEqual(sExp, summary);
            }
            catch
            {
                Console.WriteLine(summary);
                throw;
            }
        }
Esempio n. 39
0
		protected override void RunTest(Program prog, TextWriter writer)
		{
            var flow = new ProgramDataFlow(prog);
            var eventListener = new FakeDecompilerEventListener();
            var importResolver = MockRepository.GenerateStub<IImportResolver>();
            importResolver.Replay();
            var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, flow, eventListener);
            trf.Compute();
            trf.RewriteBasicBlocks();
            Dump(prog.CallGraph);
            RegisterLiveness.Compute(prog, flow, eventListener);
            GlobalCallRewriter.Rewrite(prog, flow, eventListener);

			foreach (Procedure proc in prog.Procedures.Values)
			{
				Aliases alias = new Aliases(proc, prog.Architecture);
				alias.Transform();
				var gr = proc.CreateBlockDominatorGraph();
				SsaTransform sst = new SsaTransform(
                    flow,
                    proc,
                    importResolver,
                    gr,
                    new HashSet<RegisterStorage>());
				ssa = sst.SsaState;
				ssa.Write(writer);
				proc.Write(false, true, writer);
				writer.WriteLine();
			}
		}
Esempio n. 40
0
 public void TrfPropagateFlagsToProcedureSummary()
 {
     var proc = new Procedure("proc", program.Architecture.CreateFrame());
     program.CallGraph.AddProcedure(proc);
     var flags = program.Architecture.GetFlagGroup("SZ");
     var sz = m.Frame.EnsureFlagGroup(flags.FlagRegister, flags.FlagGroupBits, flags.Name, flags.DataType);
     var stm = m.Assign(sz, m.Int32(3));
     flow[proc] = new ProcedureFlow(proc, program.Architecture);
     trf = CreateTrashedRegisterFinder(program);
     CreateBlockFlow(m.Block, m.Frame);
     trf.StartProcessingBlock(m.Block);
     stm.Accept(trf);
     trf.PropagateToProcedureSummary(proc);
     Assert.AreEqual(" SZ", flow[proc].EmitFlagGroup(program.Architecture, "", flow[proc].grfTrashed));
 }
Esempio n. 41
0
        public void TrfCopy()
        {
            Identifier r1 = m.Register(1);
            Identifier r2 = m.Register(2);
            var ass = m.Assign(r2, r1);

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            ass.Accept(trf);
            Assert.AreEqual(r1, trf.RegisterSymbolicValues[(RegisterStorage) r2.Storage], "r2 should now be equal to r1");
        }
Esempio n. 42
0
        public void TrfPreserveEbp()
        {
            Identifier esp = m.Frame.EnsureRegister(Registers.esp);
            Identifier ebp = m.Frame.EnsureRegister(Registers.ebp);
            m.Store(esp, ebp);
            m.Assign(ebp, m.LoadDw(m.Int32(0x12345678)));
            m.Assign(ebp, m.LoadDw(esp));
            m.Return();

            Procedure proc = m.Procedure;
            program.Procedures.Add(Address.Ptr32(0x10000), proc);
            program.CallGraph.AddProcedure(proc);
            flow = new ProgramDataFlow(program);

            trf = CreateTrashedRegisterFinder(program);
            trf.Compute();
            ProcedureFlow pf = flow[proc];
            Assert.AreEqual(" ebp esp", pf.EmitRegisters(program.Architecture, "", pf.PreservedRegisters), "ebp should have been preserved");
        }
Esempio n. 43
0
        public void TrfCopyBack()
        {
            var esp = m.Frame.EnsureRegister(Registers.esp);
            var r2 = m.Register(2);
            var stm1 = m.Store(m.ISub(esp, 0x10), r2);
            var stm2 = m.Assign(r2, m.Int32(0));
            var stm3 = m.Assign(r2, m.LoadDw(m.ISub(esp, 0x10)));

            trf = CreateTrashedRegisterFinder();
            var flow = CreateBlockFlow(m.Block, m.Frame);
            flow.SymbolicIn.SetValue(esp, m.Frame.FramePointer);
            trf.StartProcessingBlock(m.Block);

            stm1.Instruction.Accept(trf);
            stm2.Accept(trf);
            stm3.Accept(trf);

            Assert.AreEqual(r2, trf.RegisterSymbolicValues[(RegisterStorage) r2.Storage]);
        }
Esempio n. 44
0
        public void TrfTerminatingProcedure()
        {
            var eax = m.Procedure.Frame.EnsureRegister(Registers.eax);
            m.Assign(eax, m.Word32(0x40));
            m.Call(exit, 4);

            flow[m.Block] = CreateBlockFlow(m.Block, m.Frame);
            flow[exit] = new ProcedureFlow(exit, program.Architecture);
            flow[exit].TerminatesProcess = true;
            trf = CreateTrashedRegisterFinder(program);
            trf.ProcessBlock(m.Block);
            Assert.AreEqual("", DumpValues());
        }
Esempio n. 45
0
 /// <summary>
 /// Finds all interprocedural register dependencies (in- and out-parameters) and
 /// abstracts them away by rewriting as calls.
 /// </summary>
 /// <returns>A RegisterLiveness object that summarizes the interprocedural register
 /// liveness analysis. This information can be used to generate SSA form.
 /// </returns>
 public void UntangleProcedures()
 {
     eventListener.ShowStatus("Eliminating intra-block dead registers.");
     var usb = new UserSignatureBuilder(program);
     usb.BuildSignatures();
     CallRewriter.Rewrite(program);
     IntraBlockDeadRegisters.Apply(program);
     eventListener.ShowStatus("Finding terminating procedures.");
     var term = new TerminationAnalysis(flow);
     term.Analyze(program);
     eventListener.ShowStatus("Finding trashed registers.");
     var trf = new TrashedRegisterFinder(program, program.Procedures.Values, flow, eventListener);
     trf.Compute();
     eventListener.ShowStatus("Rewriting affine expressions.");
     trf.RewriteBasicBlocks();
     eventListener.ShowStatus("Computing register liveness.");
     var rl = RegisterLiveness.Compute(program, flow, eventListener);
     eventListener.ShowStatus("Rewriting calls.");
     GlobalCallRewriter.Rewrite(program, flow);
 }