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()); }
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(); } }
/// <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()); }