public void SrtSimpleLoop()
        {
            Procedure proc = BuildSimpleLoop();

            var dom = proc.CreateBlockDominatorGraph();
            SsaTransform ssa = new SsaTransform(new ProgramDataFlow(), proc, dom);
            proc.Write(false, Console.Out);
            LinearInductionVariableFinder lif = new LinearInductionVariableFinder(proc, ssa.SsaState.Identifiers, dom);
            lif.Find();

            Assert.AreEqual(1, lif.InductionVariables.Count, "Should have found one induction variable");
            Assert.AreEqual(1, lif.Contexts.Count);
            LinearInductionVariableContext ctx = lif.Contexts[lif.InductionVariables[0]];

            StrengthReduction str = new StrengthReduction(ssa.SsaState,lif.InductionVariables[0], ctx);
            str.ClassifyUses();
            Assert.AreEqual(1, str.IncrementedUses.Count);
            str.ModifyUses();
            Assert.AreEqual("(0x00003000 0x00000004 0x00007000)", lif.InductionVariables[0].ToString());
            using (FileUnitTester fut = new FileUnitTester("Analysis/SrtSimpleLoop.txt"))
            {
                proc.Write(false, fut.TextWriter);
                fut.AssertFilesEqual();
            }
        }
 public void Create1()
 {
     Prepare(new WhileLtIncMock().Procedure);
     var doms = proc.CreateBlockDominatorGraph();
     LinearInductionVariableFinder liv = new LinearInductionVariableFinder(proc, ssaIds, doms);
     Assert.IsNull(liv.Context.PhiIdentifier);
     Assert.IsNull(liv.Context.PhiStatement);
     Assert.Fail(); /*
     liv.Context.PhiStatement = ssaIds[5].DefStatement;
     liv.Context.PhiIdentifier = (Identifier) ((PhiAssignment) liv.Context.PhiStatement.Instruction).Dst;
     liv.Context.TestStatement = proc.ControlGraph.Blocks[2].Statements[1];
     liv.Context.DeltaStatement = ssaIds[8].DefStatement;
     liv.Context.InitialValue = Constant.Word32(0);
     liv.Context.DeltaValue = Constant.Word32(1);
     liv.Context.TestValue = Constant.Word32(10);
     LinearInductionVariable iv = liv.CreateInductionVariable();
     Assert.AreEqual("X", iv.ToString()); */
 }
        public void Create1()
        {
            Prepare(new WhileLtIncMock().Procedure);
            var doms = proc.CreateBlockDominatorGraph();
            LinearInductionVariableFinder liv = new LinearInductionVariableFinder(proc, ssaIds, doms);

            Assert.IsNull(liv.Context.PhiIdentifier);
            Assert.IsNull(liv.Context.PhiStatement);
            Assert.Fail(); /*
                            * liv.Context.PhiStatement = ssaIds[5].DefStatement;
                            * liv.Context.PhiIdentifier = (Identifier) ((PhiAssignment) liv.Context.PhiStatement.Instruction).Dst;
                            * liv.Context.TestStatement = proc.ControlGraph.Blocks[2].Statements[1];
                            * liv.Context.DeltaStatement = ssaIds[8].DefStatement;
                            * liv.Context.InitialValue = Constant.Word32(0);
                            * liv.Context.DeltaValue = Constant.Word32(1);
                            * liv.Context.TestValue = Constant.Word32(10);
                            * LinearInductionVariable iv = liv.CreateInductionVariable();
                            * Assert.AreEqual("X", iv.ToString()); */
        }
        public void Liv_CreateDecTest()
        {
            Prepare(m =>
            {
                Identifier id = m.Local32("id");
                m.Assign(id, Constant.Word32(10));
                m.Label("loop");
                m.Assign(id, m.ISub(id, 1));
                m.BranchIf(m.Ge(id, 0), "loop");
                m.MStore(m.Word32(0x4232), id);
                m.Return(id);
            });
            var liv = new LinearInductionVariableFinder(proc, ssaIds, doms);

            liv.Find();
            var iv = liv.InductionVariables[0];

            Assert.AreEqual("(0x00000009 -1 0xFFFFFFFF signed)", iv.ToString());
        }
        public void Liv_PreTestedUge()
        {
            Prepare(m =>
            {
                Identifier i = m.Local32("i");
                m.Label("test");
                m.BranchIf(m.Uge(i, 10), "done");
                m.MStore(m.Word32(0x4204), i);
                m.Assign(i, m.IAdd(i, 1));
                m.Goto("test");
                m.Label("done");
                m.MStore(m.Word32(0x4200), i);
                m.Return();
            });
            var liv = new LinearInductionVariableFinder(proc, ssaIds, doms);

            liv.Find();
            Assert.AreEqual("(? 0x00000001 0x0000000A)", liv.InductionVariables[0].ToString());
        }
        public void Liv_CreateBareMinimum()
        {
            ssaIds = new SsaIdentifierCollection();
            Identifier id0 = new Identifier("foo", PrimitiveType.Word32, new TemporaryStorage("foo", 1, PrimitiveType.Word32));
            Identifier id1 = new Identifier("bar", PrimitiveType.Word32, new TemporaryStorage("bar", 1, PrimitiveType.Word32));
            Identifier phi = new Identifier("i_3", PrimitiveType.Word32, null);

            ssaIds.Add(id0, new SsaIdentifier(id0, id0, null, null, false));
            ssaIds.Add(id1, new SsaIdentifier(id1, id1, null, null, false));
            ssaIds.Add(phi, new SsaIdentifier(phi, phi, null, null, false));
            LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, ssaIds, null);

            liv.Context.PhiStatement  = new Statement(0, null, null);
            liv.Context.PhiIdentifier = phi;
            liv.Context.DeltaValue    = Constant.Word32(1);
            LinearInductionVariable iv = liv.CreateInductionVariable();

            Assert.AreEqual("(? 0x00000001 ?)", iv.ToString());
        }
        public void Liv_CreateIncInitialValue()
        {
            var pb = new ProcedureBuilder();

            ssa = new SsaState(pb.Procedure);
            LinearInductionVariableFinder liv = new LinearInductionVariableFinder(ssa, null);

            liv.Context.InitialValue  = Constant.Word32(0);
            liv.Context.PhiStatement  = new Statement(0, null, null);
            liv.Context.PhiIdentifier = new Identifier("foo_0", PrimitiveType.Word32, null);
            ssa.Identifiers.Add(liv.Context.PhiIdentifier, new SsaIdentifier(liv.Context.PhiIdentifier, liv.Context.PhiIdentifier, liv.Context.PhiStatement, null, false));
            liv.Context.DeltaValue     = Constant.Word32(1);
            liv.Context.DeltaStatement = new Statement(0, new Assignment(new Identifier("foo_1", PrimitiveType.Word32, null),
                                                                         new BinaryExpression(Operator.IAdd, PrimitiveType.Word32, liv.Context.PhiIdentifier, liv.Context.DeltaValue)), null);
            ssa.Identifiers[liv.Context.PhiIdentifier].Uses.Add(liv.Context.DeltaStatement);

            LinearInductionVariable iv = liv.CreateInductionVariable();

            Assert.AreEqual("(1<32> 1<32> ?)", iv.ToString());
        }
        public void Liv_CreateBareMinimum()
        {
            var pb = new ProcedureBuilder();

            ssa = new SsaState(pb.Procedure);
            Identifier id0 = new Identifier("foo", PrimitiveType.Word32, new TemporaryStorage("foo", 1, PrimitiveType.Word32));
            Identifier id1 = new Identifier("bar", PrimitiveType.Word32, new TemporaryStorage("bar", 1, PrimitiveType.Word32));
            Identifier phi = new Identifier("i_3", PrimitiveType.Word32, null);

            ssa.Identifiers.Add(id0, new SsaIdentifier(id0, id0, null, null, false));
            ssa.Identifiers.Add(id1, new SsaIdentifier(id1, id1, null, null, false));
            ssa.Identifiers.Add(phi, new SsaIdentifier(phi, phi, null, null, false));
            var liv = new LinearInductionVariableFinder(ssa, null);

            liv.Context.PhiStatement  = new Statement(0, null, null);
            liv.Context.PhiIdentifier = phi;
            liv.Context.DeltaValue    = Constant.Word32(1);
            LinearInductionVariable iv = liv.CreateInductionVariable();

            Assert.AreEqual("(? 1<32> ?)", iv.ToString());
        }
        public void CreateNoincInitialValue()
        {
            ProcedureBuilder m = new ProcedureBuilder();

            ssa = new SsaState(m.Procedure);
            SsaId(new Identifier("id0", PrimitiveType.Word32, new TemporaryStorage("id0", 0, PrimitiveType.Word32)), null, null, false);
            SsaId(new Identifier("id1", PrimitiveType.Word32, new TemporaryStorage("id1", 1, PrimitiveType.Word32)), null, null, false);
            LinearInductionVariableFinder liv = new LinearInductionVariableFinder(ssa, null);

            liv.Context.InitialValue = Constant.Word32(0);
            Identifier id2 = m.Local32("id_2");

            SsaId(id2, new Statement(0, null, null), null, false);
            Assert.AreEqual(3, ssa.Identifiers.Count);

            Identifier id3 = m.Local32("id_3");
            Identifier id4 = m.Local32("id_4");

            liv.Context.PhiStatement  = m.Phi(id3, (id2, "block2"), (id4, "block4"));
            liv.Context.PhiIdentifier = id3;
            SsaId(id3, liv.Context.PhiStatement, ((PhiAssignment)liv.Context.PhiStatement.Instruction).Src, false);
            Assert.AreEqual(4, ssa.Identifiers.Count);

            Statement use = new Statement(0, null, null);

            ssa.Identifiers[id3].Uses.Add(use);

            liv.Context.DeltaValue = m.Word32(1);
            m.Assign(id4, m.IAdd(id3, liv.Context.DeltaValue));
            liv.Context.DeltaStatement = m.Block.Statements.Last;
            ssa.Identifiers[id3].Uses.Add(liv.Context.DeltaStatement);

            LinearInductionVariable iv = liv.CreateInductionVariable();

            Assert.AreEqual("(0<32> 1<32> ?)", iv.ToString());
        }
		public void Liv_CreateIncInitialValue()
		{
			ssaIds = new SsaIdentifierCollection();
			LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, ssaIds, null);
			liv.Context.InitialValue = Constant.Word32(0);
			liv.Context.PhiStatement = new Statement(0, null, null);
			liv.Context.PhiIdentifier = new Identifier("foo_0", PrimitiveType.Word32, null);
            ssaIds.Add(liv.Context.PhiIdentifier, new SsaIdentifier(liv.Context.PhiIdentifier, liv.Context.PhiIdentifier, liv.Context.PhiStatement, null, false));
			liv.Context.DeltaValue = Constant.Word32(1);
			liv.Context.DeltaStatement = new Statement(0, new Assignment(new Identifier("foo_1", PrimitiveType.Word32, null), 
				new BinaryExpression(Operator.IAdd, PrimitiveType.Word32, liv.Context.PhiIdentifier, liv.Context.DeltaValue)), null);
			ssaIds[liv.Context.PhiIdentifier].Uses.Add(liv.Context.DeltaStatement);

			LinearInductionVariable iv = liv.CreateInductionVariable();
			Assert.AreEqual("(0x00000001 0x00000001 ?)", iv.ToString());
		}
		public void Liv_FindLinearIncrement()
		{
            List<SsaIdentifier> a = BuildScc();
			LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, null, dom);
			Constant c = liv.FindLinearIncrement(a);
			Assert.AreEqual(4, c.ToInt32());
            Assert.AreEqual("a_2 = a_1 + 0x00000004", liv.Context.DeltaStatement.ToString());
		}
		public void Liv_FindPhi()
		{
			List<SsaIdentifier> a = BuildScc();
			LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, null, dom);
			PhiFunction p = liv.FindPhiFunction(a);
			Assert.IsNotNull(p, "Didn't find phi function!");
		}
		public void Liv_FindInitialValue()
		{
			List<SsaIdentifier> a = BuildScc();
			LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, ssaIds, dom);
			PhiFunction phi = liv.FindPhiFunction(a);
			Constant c = liv.FindInitialValue(phi);
            Assert.AreEqual(0, c.ToInt32());
            Assert.AreEqual("a_0 = 0x00000000", liv.Context.InitialStatement.ToString());
		}
        public void Liv_CreateNo()
        {
            var liv = new LinearInductionVariableFinder(null, null);

            Assert.IsNull(liv.CreateInductionVariable());
        }
		private void RunTest(Procedure proc, string outputFile)
		{
			Prepare(proc);
			var liv = new LinearInductionVariableFinder(proc, ssaIds, doms);
			liv.Find();
			using (FileUnitTester fut = new FileUnitTester(outputFile))
			{
				proc.Write(false, fut.TextWriter);
				fut.TextWriter.WriteLine();
				foreach (LinearInductionVariable iv in liv.InductionVariables)
				{
					fut.TextWriter.WriteLine(iv);
				}
				fut.AssertFilesEqual();
			}
		}
		public void Liv_FindFinalValue()
		{
			Prepare(new ByteArrayLoopMock().Procedure);
			var liv = new LinearInductionVariableFinder(proc, ssaIds, null);
			var a = new List<SsaIdentifier>();
			a.Add(ssaIds.Where(s => s.Identifier.Name == "i_1").Single());
			a.Add(ssaIds.Where(s => s.Identifier.Name == "i_4").Single());
			Constant c = liv.FindFinalValue(a);
			Assert.AreEqual(10, c.ToInt32());
            Assert.AreEqual("branch i_1 < 0x0000000A body", liv.Context.TestStatement.ToString());
		}
		public void Liv_CreateDecTest()
		{
            Prepare(delegate(ProcedureBuilder m)
            {
                Identifier id = m.Local32("id");
                m.Assign(id, Constant.Word32(10));
                m.Label("loop");
                m.Assign(id, m.ISub(id, 1));
                m.BranchIf(m.Ge(id, 0), "loop");
                m.Store(m.Word32(0x4232), id);
                m.Return(id);
            });
            proc.Dump(true);
            var liv = new LinearInductionVariableFinder(proc, ssaIds, doms);
            liv.Find();
			var iv = liv.InductionVariables[0];
			Assert.AreEqual("(0x00000009 -1 0xFFFFFFFF signed)", iv.ToString());
		}
 public void Liv_PreTestedUge()
 {
     Prepare(delegate(ProcedureBuilder m)
     {
         Identifier i = m.Local32("i");
         m.Label("test");
         m.BranchIf(m.Uge(i, 10), "done");
         m.Store(m.Word32(0x4204), i);
         m.Assign(i, m.IAdd(i, 1));
         m.Goto("test");
         m.Label("done");
         m.Store(m.Word32(0x4200), i);
         m.Return();
     });
     var liv = new LinearInductionVariableFinder(proc, ssaIds, doms);
     liv.Find();
     Assert.AreEqual("(? 0x00000001 0x0000000A)", liv.InductionVariables[0].ToString());
 }
		public void Liv_CreateNo()
		{
			LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, null, null);
			Assert.IsNull(liv.CreateInductionVariable());
		}
Beispiel #20
0
        private void UntangleProcedureScc(IList<Procedure> procs)
        {
            if (procs.Count == 1)
            {
                var proc = procs[0];
                Aliases alias = new Aliases(proc, program.Architecture, flow);
                alias.Transform();

                // Transform the procedure to SSA state. When encountering 'call' instructions,
                // they can be to functions already visited. If so, they have a "ProcedureFlow"
                // associated with them. If they have not been visited, or are computed destinations
                // (e.g. vtables) they will have no "ProcedureFlow" associated with them yet, in
                // which case the the SSA treats the call as a "hell node".
                var doms = proc.CreateBlockDominatorGraph();
                var sst = new SsaTransform(flow, proc, doms);
                var ssa = sst.SsaState;

                // Propagate condition codes and registers. At the end, the hope is that
                // all statements like (x86) mem[esp_42+4] will have been converted to
                // mem[fp - 30]. We also hope that procedure constants kept in registers
                // are propagated to the corresponding call sites.
                var cce = new ConditionCodeEliminator(ssa.Identifiers, program.Platform);
                cce.Transform();
                var vp = new ValuePropagator(program.Architecture, ssa.Identifiers, proc);
                vp.Transform();

                // Now compute SSA for the stack-based variables as well. That is:
                // mem[fp - 30] becomes wLoc30, while
                // mem[fp + 30] becomes wArg30.
                // This allows us to compute the dataflow of this procedure.
                sst.RenameFrameAccesses = true;
                sst.AddUseInstructions = true;
                sst.Transform();

                // Propagate those newly discovered identifiers.
                vp.Transform();

                // At this point, the computation of _actual_ ProcedureFlow should be possible.
                var tid = new TrashedRegisterFinder2(program.Architecture, flow, proc, ssa.Identifiers, this.eventListener);
                tid.Compute();
                DeadCode.Eliminate(proc, ssa);

                // Build expressions. A definition with a single use can be subsumed
                // into the using expression.

                var coa = new Coalescer(proc, ssa);
                coa.Transform();
                DeadCode.Eliminate(proc, ssa);

                var liv = new LinearInductionVariableFinder(
                    proc,
                    ssa.Identifiers,
                    new BlockDominatorGraph(proc.ControlGraph, proc.EntryBlock));
                liv.Find();

                foreach (var de in liv.Contexts)
                {
                    var str = new StrengthReduction(ssa, de.Key, de.Value);
                    str.ClassifyUses();
                    str.ModifyUses();
                }

                //var opt = new OutParameterTransformer(proc, ssa.Identifiers);
                //opt.Transform();
                DeadCode.Eliminate(proc, ssa);

                // Definitions with multiple uses and variables joined by PHI functions become webs.
                var web = new WebBuilder(proc, ssa.Identifiers, program.InductionVariables);
                web.Transform();
                ssa.ConvertBack(false);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
		public void Liv_CreateBareMinimum()
		{
			ssaIds = new SsaIdentifierCollection();
            Identifier id0 = new Identifier("foo", PrimitiveType.Word32, new TemporaryStorage("foo", 1, PrimitiveType.Word32));
            Identifier id1 = new Identifier("bar", PrimitiveType.Word32, new TemporaryStorage("bar", 1, PrimitiveType.Word32));
            Identifier phi = new Identifier("i_3", PrimitiveType.Word32, null);
			ssaIds.Add(id0, new SsaIdentifier(id0, id0, null, null, false));
			ssaIds.Add(id1, new SsaIdentifier(id1, id1, null, null, false));
            ssaIds.Add(phi, new SsaIdentifier(phi, phi, null, null, false));
			LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, ssaIds, null);
			liv.Context.PhiStatement = new Statement(0, null, null);
            liv.Context.PhiIdentifier = phi;
			liv.Context.DeltaValue = Constant.Word32(1);
			LinearInductionVariable iv = liv.CreateInductionVariable();
			Assert.AreEqual("(? 0x00000001 ?)", iv.ToString());
		}
Beispiel #22
0
        /// <summary>
        /// Processes procedures individually, building complex expression trees out
        /// of the simple, close-to-the-machine code generated by the disassembly.
        /// </summary>
        /// <param name="rl"></param>
        public void BuildExpressionTrees()
        {
            int i = 0;
            foreach (Procedure proc in program.Procedures.Values)
            {
                eventListener.ShowProgress("Building complex expressions.", i, program.Procedures.Values.Count);
                ++i;

                try
                {
                    var larw = new LongAddRewriter(proc, program.Architecture);
                    larw.Transform();

                    Aliases alias = new Aliases(proc, program.Architecture, flow);
                    alias.Transform();

                    var doms = new DominatorGraph<Block>(proc.ControlGraph, proc.EntryBlock);
                    var sst = new SsaTransform(flow, proc, doms);
                    var ssa = sst.SsaState;

                    var cce = new ConditionCodeEliminator(ssa.Identifiers, program.Platform);
                    cce.Transform();
                    DeadCode.Eliminate(proc, ssa);

                    var vp = new ValuePropagator(program.Architecture, ssa.Identifiers, proc);
                    vp.Transform();
                    DeadCode.Eliminate(proc, ssa);

                    // Build expressions. A definition with a single use can be subsumed
                    // into the using expression.

                    var coa = new Coalescer(proc, ssa);
                    coa.Transform();
                    DeadCode.Eliminate(proc, ssa);

                    var liv = new LinearInductionVariableFinder(
                        proc,
                        ssa.Identifiers,
                        new BlockDominatorGraph(proc.ControlGraph, proc.EntryBlock));
                    liv.Find();

                    foreach (KeyValuePair<LinearInductionVariable, LinearInductionVariableContext> de in liv.Contexts)
                    {
                        var str = new StrengthReduction(ssa, de.Key, de.Value);
                        str.ClassifyUses();
                        str.ModifyUses();
                    }
                    var opt = new OutParameterTransformer(proc, ssa.Identifiers);
                    opt.Transform();
                    DeadCode.Eliminate(proc, ssa);

                    // Definitions with multiple uses and variables joined by PHI functions become webs.
                    var web = new WebBuilder(proc, ssa.Identifiers, program.InductionVariables);
                    web.Transform();
                    ssa.ConvertBack(false);
                }
                catch (Exception ex)
                {
                    eventListener.Error(new NullCodeLocation(proc.Name), ex, "An error occurred during data flow analysis.");
                }
            }
        }
		public void CreateNoincInitialValue()
		{
			ProcedureBuilder m = new ProcedureBuilder();
			ssaIds = new SsaIdentifierCollection();
			SsaId(new Identifier("id0", PrimitiveType.Word32, new TemporaryStorage("id0", 0, PrimitiveType.Word32)), null, null, false);
			SsaId(new Identifier("id1", PrimitiveType.Word32, new TemporaryStorage("id1", 1, PrimitiveType.Word32)), null, null, false);
			LinearInductionVariableFinder liv = new LinearInductionVariableFinder(null, ssaIds, null);

			liv.Context.InitialValue = Constant.Word32(0);
			Identifier id2 = m.Local32("id_2");
			SsaId(id2, new Statement(0, null, null), null, false);
			Assert.AreEqual(3, ssaIds.Count);

			Identifier id3 = m.Local32("id_3");
			Identifier id4 = m.Local32("id_4");
			liv.Context.PhiStatement = m.Phi(id3, id2, id4);
			liv.Context.PhiIdentifier = id3;
			SsaId(id3, liv.Context.PhiStatement, ((PhiAssignment)liv.Context.PhiStatement.Instruction).Src, false);
			Assert.AreEqual(4, ssaIds.Count);

			Statement use = new Statement(0, null, null);
			ssaIds[id3].Uses.Add(use);

			liv.Context.DeltaValue = m.Int32(1);
            m.Assign(id4, m.IAdd(id3, liv.Context.DeltaValue));
            liv.Context.DeltaStatement = m.Block.Statements.Last;
			ssaIds[id3].Uses.Add(liv.Context.DeltaStatement);

			LinearInductionVariable iv = liv.CreateInductionVariable();
			Assert.AreEqual("(0x00000000 0x00000001 ?)", iv.ToString());

		}