public void Setup()
        {
            exit = new ExternalProcedure("exit",
                                         new FunctionType(
                                             null,
                                             null,
                                             new Identifier("retCode", PrimitiveType.Int32, new StackArgumentStorage(0, PrimitiveType.Int32))));
            exit.Characteristics            = new ProcedureCharacteristics();
            exit.Characteristics.Terminates = true;

            progMock      = new ProgramBuilder();
            flow          = new ProgramDataFlow();
            eventListener = new FakeDecompilerEventListener();
        }
        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();
            }
        }
 public void Setup()
 {
     program = new Program();
     program.Architecture = new X86ArchitectureFlat32();
     program.Platform     = new DefaultPlatform(null, program.Architecture);
     m            = new ProcedureBuilder();
     proc         = m.Procedure;
     f            = proc.Frame;
     mpprocflow   = new ProgramDataFlow();
     terminates   = new HashSet <Procedure>();
     rl           = new RegisterLiveness(program, mpprocflow, null);
     rl.Procedure = proc;
     rl.IdentifierLiveness.Identifiers = new HashSet <RegisterStorage>();
 }
Beispiel #4
0
        public void CrwSinglePredecessorToExitBlock()
        {
            var m   = new ProcedureBuilder("CrwSinglePredecessorToExitBlock");
            var eax = m.Frame.EnsureRegister(Registers.eax);

            m.Assign(eax, m.Mem32(eax));
            m.Return();

            var flow = new ProgramDataFlow(program);
            var sst  = new SsaTransform(program, m.Procedure, new HashSet <Procedure>(), null, new ProgramDataFlow());

            sst.Transform();
            sst.AddUsesToExitBlock();
            sst.SsaState.Procedure.Signature = FunctionType.Func(
                new Identifier("", PrimitiveType.Word32, Registers.eax),
                new Identifier("eax", PrimitiveType.Word32, Registers.eax));

            var crw = new CallRewriter(this.platform, flow, new FakeDecompilerEventListener());

            crw.RewriteReturns(sst.SsaState);
            crw.RemoveStatementsFromExitBlock(sst.SsaState);

            var sExp =
                #region Expected
                @"eax:eax
    def:  def eax
    uses: eax_3 = Mem0[eax:word32]
Mem0:Mem
    def:  def Mem0
    uses: eax_3 = Mem0[eax:word32]
eax_3: orig: eax
    def:  eax_3 = Mem0[eax:word32]
    uses: return eax_3
// CrwSinglePredecessorToExitBlock
// Return size: 0
word32 CrwSinglePredecessorToExitBlock(word32 eax)
CrwSinglePredecessorToExitBlock_entry:
	def eax
	def Mem0
	// succ:  l1
l1:
	eax_3 = Mem0[eax:word32]
	return eax_3
	// succ:  CrwSinglePredecessorToExitBlock_exit
CrwSinglePredecessorToExitBlock_exit:
";

            #endregion
            AssertExpected(sExp, sst.SsaState);
        }
Beispiel #5
0
        public void ProcedureTerminatesIfBlockTerminates()
        {
            var proc = CompileProcedure("proc", delegate(ProcedureBuilder m)
            {
                m.Call(exit, 4);
                m.Return();
            });
            var prog = progMock.BuildProgram();

            flow = new ProgramDataFlow(prog);
            var a = new TerminationAnalysis(flow, eventListener);

            a.Analyze(proc);
            Assert.IsTrue(flow[proc].TerminatesProcess);
        }
Beispiel #6
0
        public void TerminatingApplication()
        {
            var test = CompileProcedure("test", m =>
            {
                m.SideEffect(m.Fn(new ProcedureConstant(PrimitiveType.Pointer32, exit)));
                m.FinishProcedure();
            });
            var prog = progMock.BuildProgram();

            flow = new ProgramDataFlow(prog);
            var a = new TerminationAnalysis(flow, eventListener);

            a.Analyze(test);
            Assert.IsTrue(flow[test].TerminatesProcess);
        }
        private void RunTest()
        {
            this.program  = builder.BuildProgram();
            this.dataFlow = new ProgramDataFlow(program);
            var sscf = new SccFinder <Procedure>(new ProcedureGraph(program), ProcessScc);

            foreach (var procedure in program.Procedures.Values)
            {
                sscf.Find(procedure);
            }
            var sbActual = new StringBuilder();
            var sw       = new StringWriter();

            foreach (var procedure in program.Procedures.Values)
            {
                var flow = dataFlow[procedure];
                sw.WriteLine("== {0} ====", procedure.Name);
                sw.Write("Preserved: ");
                sw.WriteLine(string.Join(",", flow.Preserved.OrderBy(p => p.ToString())));
                sw.Write("Trashed: ");
                sw.WriteLine(string.Join(",", flow.Trashed.OrderBy(p => p.ToString())));
                if (flow.Constants.Count > 0)
                {
                    sw.Write("Constants: ");
                    sw.Write(string.Join(
                                 ",",
                                 flow.Constants
                                 .OrderBy(kv => kv.Key.ToString())
                                 .Select(kv => string.Format(
                                             "{0}:{1}", kv.Key, kv.Value))));
                }
                sw.WriteLine();
            }
            var sExp    = sbExpected.ToString();
            var sActual = sw.ToString();

            if (sActual != sExp)
            {
                foreach (var proc in program.Procedures.Values)
                {
                    Debug.Print("------");
                    proc.Dump(true);
                }
                Debug.WriteLine(sActual);
                Assert.AreEqual(sExp, sActual);
            }
        }
Beispiel #8
0
        protected override void RunTest(Program prog, TextWriter writer)
        {
            var progFlow = new ProgramDataFlow();

            foreach (Procedure proc in prog.Procedures.Values)
            {
                var     gr    = proc.CreateBlockDominatorGraph();
                Aliases alias = new Aliases(proc, prog.Architecture);
                alias.Transform();
                SsaTransform sst = new SsaTransform(progFlow, proc, gr);
                SsaState     ssa = sst.SsaState;
                DumpProc(proc, ssa, writer);
                ValueNumbering vn = new ValueNumbering(ssa.Identifiers);
                vn.Write(writer);
                writer.WriteLine();
            }
        }
Beispiel #9
0
        public void ProcedureDoesntTerminatesIfOneBranchDoesnt()
        {
            var proc = CompileProcedure("proc", delegate(ProcedureBuilder m)
            {
                m.BranchIf(m.Eq(m.Local32("foo"), m.Word32(0)), "bye");
                m.Call(exit, 4);
                m.Label("bye");
                m.Return();
            });
            var prog = progMock.BuildProgram();

            flow = new ProgramDataFlow(prog);
            var a = new TerminationAnalysis(flow, eventListener);

            a.Analyze(proc);
            Assert.IsFalse(flow[proc].TerminatesProcess);
        }
Beispiel #10
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);
        }
Beispiel #11
0
        protected override void RunTest(Program program, TextWriter writer)
        {
            var progFlow = new ProgramDataFlow();

            foreach (Procedure proc in program.Procedures.Values)
            {
                var     gr    = proc.CreateBlockDominatorGraph();
                Aliases alias = new Aliases(proc);
                alias.Transform();
                SsaTransform sst = new SsaTransform(progFlow, proc, null, gr,
                                                    new HashSet <RegisterStorage>());
                SsaState ssa = sst.SsaState;
                DumpProc(proc, ssa, writer);
                ValueNumbering vn = new ValueNumbering(ssa.Identifiers, segmentMap, null);
                vn.Write(writer);
                writer.WriteLine();
            }
        }
Beispiel #12
0
        private void BuildTest(Action <ProcedureBuilder> builder)
        {
            var pb = new ProcedureBuilder();

            builder(pb);
            var dflow   = new ProgramDataFlow();
            var program = new Program()
            {
                Architecture = pb.Architecture,
            };
            var sst = new SsaTransform(
                program, pb.Procedure,
                new HashSet <Procedure>(),
                null,
                dflow);

            this.ssa = sst.Transform();
        }
        private void AssertSmallConst(string sExp, int shift, uint mult)
        {
            var m     = new ProcedureBuilder();
            var c     = Constant.Int32((int)mult);
            var r1    = m.Reg32("r1", 1);
            var r2    = m.Reg32("r2", 2);
            var r2_r1 = m.Frame.EnsureSequence(PrimitiveType.Word64, r2.Storage, r1.Storage);

            var ass = m.Assign(r2_r1, m.SMul(r1, c));

            m.Alias(r2, m.Slice(PrimitiveType.Word32, r2_r1, 32));
            if (shift != 0)
            {
                m.Assign(r2, m.Sar(r2, shift));
            }
            m.MStore(m.Word32(0x0402000), r2);       // Force use of r2
            m.Return();

            var proc    = m.Procedure;
            var flow    = new ProgramDataFlow();
            var program = new Program()
            {
                Architecture = m.Architecture,
            };
            var sst = new SsaTransform(
                program,
                proc,
                new HashSet <Procedure>(),
                null,
                flow);

            sst.Transform();

            proc.Dump(true);

            var ctx  = new SsaEvaluationContext(m.Architecture, sst.SsaState.Identifiers, null);
            var rule = new ConstDivisionImplementedByMultiplication(sst.SsaState);

            ctx.Statement = proc.EntryBlock.Succ[0].Statements[0];
            Assert.IsTrue(rule.Match(ctx.Statement.Instruction));
            var instr = rule.TransformInstruction();

            Assert.AreEqual(sExp, instr.Src.ToString());
        }
Beispiel #14
0
        public void ProcedureTerminatesIfAllBranchesDo()
        {
            var proc = CompileProcedure("proc", m =>
            {
                m.BranchIf(m.Eq(m.Local32("foo"), m.Word32(0)), "whee");
                m.Call(exit, 4);
                m.FinishProcedure();
                m.Label("whee");
                m.Call(exit, 4);
                m.FinishProcedure();
            });
            var prog = progMock.BuildProgram();

            flow = new ProgramDataFlow(prog);
            var a = new TerminationAnalysis(flow, eventListener);

            a.Analyze(proc);
            Assert.IsTrue(flow[proc].TerminatesProcess);
        }
        private void BuildTest(Action <ProcedureBuilder> bld)
        {
            var m = new ProcedureBuilder();

            bld(m);
            var proc    = m.Procedure;
            var flow    = new ProgramDataFlow();
            var program = new Program()
            {
                Architecture = m.Architecture,
            };
            var sst = new SsaTransform(
                program,
                proc,
                new HashSet <Procedure>(),
                null,
                flow);

            this.ssa = sst.Transform();
            this.ctx = new SsaEvaluationContext(m.Architecture, ssa.Identifiers, null);
        }
Beispiel #16
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");
        }
Beispiel #17
0
        private void AssertProgramFlow(string sExp, Program program, ProgramDataFlow flow)
        {
            var sw  = new StringWriter();
            var sep = "";

            foreach (var proc in program.Procedures.Values)
            {
                sw.Write(sep);
                var pflow = flow.ProcedureFlows[proc];
                sw.WriteLine("// Trashed   {0}", string.Join(", ", pflow.Trashed.OrderBy(s => s.ToString())));
                sw.WriteLine("// Preserved {0}", string.Join(", ", pflow.Preserved.OrderBy(s => s.ToString())));
                sw.WriteLine("// Used      {0}", string.Join(", ", pflow.BitsUsed.Select(s => string.Format("({0}:{1})", s.Key, s.Value)).OrderBy(s => s)));
                proc.Write(false, sw);
                sep = "===" + Environment.NewLine;
            }
            var sActual = sw.ToString();

            if (sExp != sActual)
            {
                Debug.WriteLine(sActual);
            }
            Assert.AreEqual(sExp, sw.ToString());
        }
Beispiel #18
0
        public void TerminatingSubProcedure()
        {
            var sub = CompileProcedure("sub", m =>
            {
                m.Call(exit, 4);
                m.FinishProcedure();
            });

            Procedure caller = CompileProcedure("caller", m =>
            {
                m.Call(sub, 4);
                m.Return();
            });

            var prog = progMock.BuildProgram();

            flow = new ProgramDataFlow(prog);
            var a = new TerminationAnalysis(flow, eventListener);

            a.Analyze(prog);
            Assert.IsTrue(flow[sub].TerminatesProcess);
            Assert.IsTrue(flow[caller].TerminatesProcess);
        }
Beispiel #19
0
        private void RunUnitTest(ProcedureBuilder m, string outfile)
        {
            var flow          = new ProgramDataFlow();
            var dynamicLinker = new Mock <IDynamicLinker>();

            var proc     = m.Procedure;
            var platform = new FakePlatform(null, m.Architecture)
            {
                Test_CreateTrashedRegisters = () =>
                                              new HashSet <RegisterStorage>()
                {
                    (RegisterStorage)r1.Storage,
                    (RegisterStorage)r2.Storage,
                }
            };
            var program = new Program()
            {
                Architecture = m.Architecture,
                Platform     = platform,
            };
            var sst = new SsaTransform(
                program,
                proc,
                new HashSet <Procedure>(),
                dynamicLinker.Object,
                flow);

            sst.Transform();
            ssa = sst.SsaState;
            using (var fut = new FileUnitTester(outfile))
            {
                ssa.Write(fut.TextWriter);
                proc.Write(false, fut.TextWriter);
                fut.AssertFilesEqual();
                ssa.Validate(s => Assert.Fail(s));
            }
        }
Beispiel #20
0
        protected override void RunTest(Program program, TextWriter writer)
        {
            var flow          = new ProgramDataFlow();
            var dynamicLinker = new Mock <IDynamicLinker>();

            foreach (Procedure proc in program.Procedures.Values)
            {
                var sst = new SsaTransform(
                    program,
                    proc,
                    new HashSet <Procedure>(),
                    dynamicLinker.Object,
                    flow);
                sst.Transform();
                sst.AddUsesToExitBlock();
                sst.RemoveDeadSsaIdentifiers();
                Debug.Print("SsaTest: {0}", new StackFrame(3).GetMethod().Name);
                ssa = sst.SsaState;
                ssa.Write(writer);
                proc.Write(false, true, writer);
                writer.WriteLine();
                ssa.Validate(s => Assert.Fail(s));
            }
        }
        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;
            }
        }
        public void RunTest(IEnumerable <Procedure> procs)
        {
            importResolver = MockRepository.GenerateStub <IImportResolver>();
            importResolver.Replay();
            var flow = new ProgramDataFlow(program);
            var scc  = new Dictionary <Procedure, SsaState>();

            foreach (var proc in procs)
            {
                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,
                    importResolver,
                    doms,
                    program.Platform.CreateImplicitArgumentRegisters());
                sst.AddUseInstructions = true;
                sst.Transform();
                var ssa = sst.SsaState;

                scc.Add(proc, ssa);
            }

            this.dataFlow = new DataFlow2();
            var regp = new RegisterPreservation(scc, dataFlow);

            regp.Compute();
        }
 private TrashedRegisterFinder CreateTrashedRegisterFinder(bool createFlow = false)
 {
     this.flow = createFlow ? new ProgramDataFlow(program) : this.flow;
     return(new TrashedRegisterFinder(program, program.Procedures.Values, this.flow, new FakeDecompilerEventListener()));
 }
Beispiel #24
0
 public void Setup()
 {
     this.pf          = new ProgramDataFlow();
     this.progBuilder = new ProgramBuilder();
     this.segmentMap  = new SegmentMap(Address.Ptr32(0));
 }
Beispiel #25
0
        public void CrwManyPredecessorsToExitBlock()
        {
            var m   = new ProcedureBuilder("CrwManyPredecessorsToExitBlock");
            var eax = m.Frame.EnsureRegister(Registers.eax);

            m.BranchIf(m.Ge0(eax), "m2Ge");

            m.Label("m1Lt");
            m.Assign(eax, -1);
            m.Return();

            m.Label("m2Ge");
            m.BranchIf(m.Ne0(eax), "m4Gt");

            m.Label("m3Eq");
            m.Return();

            m.Label("m4Gt");
            m.Assign(eax, 1);
            m.Return();

            var flow = new ProgramDataFlow(program);
            var sst  = new SsaTransform(program, m.Procedure, new HashSet <Procedure>(), null, new ProgramDataFlow());

            sst.Transform();
            sst.AddUsesToExitBlock();
            sst.SsaState.Procedure.Signature = FunctionType.Func(
                new Identifier("", PrimitiveType.Word32, Registers.eax),
                new Identifier("eax", PrimitiveType.Word32, Registers.eax));

            var crw = new CallRewriter(this.platform, flow, new FakeDecompilerEventListener());

            crw.RewriteReturns(sst.SsaState);
            crw.RemoveStatementsFromExitBlock(sst.SsaState);

            var sExp =
                #region Expected
                @"eax:eax
    def:  def eax
    uses: branch eax >= 0<32> m2Ge
          branch eax != 0<32> m4Gt
          return eax
eax_2: orig: eax
    def:  eax_2 = 1<32>
    uses: return eax_2
eax_3: orig: eax
    def:  eax_3 = 0xFFFFFFFF<32>
    uses: return eax_3
eax_4: orig: eax
// CrwManyPredecessorsToExitBlock
// Return size: 0
word32 CrwManyPredecessorsToExitBlock(word32 eax)
CrwManyPredecessorsToExitBlock_entry:
	def eax
	// succ:  l1
l1:
	branch eax >= 0<32> m2Ge
	// succ:  m1Lt m2Ge
m1Lt:
	eax_3 = 0xFFFFFFFF<32>
	return eax_3
	// succ:  CrwManyPredecessorsToExitBlock_exit
m2Ge:
	branch eax != 0<32> m4Gt
	// succ:  m3Eq m4Gt
m3Eq:
	return eax
	// succ:  CrwManyPredecessorsToExitBlock_exit
m4Gt:
	eax_2 = 1<32>
	return eax_2
	// succ:  CrwManyPredecessorsToExitBlock_exit
CrwManyPredecessorsToExitBlock_exit:
";

            #endregion
            AssertExpected(sExp, sst.SsaState);
        }
Beispiel #26
0
 public void Setup()
 {
     this.pf          = new ProgramDataFlow();
     this.progBuilder = new ProgramBuilder();
 }
Beispiel #27
0
 public void Setup()
 {
     m = new SsaProcedureBuilder();
     this.programDataFlow = new ProgramDataFlow();
     this.dynamicLinker   = new Mock <IDynamicLinker>();
 }
Beispiel #28
0
 public void Setup()
 {
     this.pb               = new ProgramBuilder();
     this.programFlow      = new ProgramDataFlow();
     this.importReferences = new Dictionary <Address, ImportReference>();
 }
Beispiel #29
0
 public void Setup()
 {
     m = new SsaProcedureBuilder();
     this.programDataFlow = new ProgramDataFlow();
     this.importResolver  = new Mock <IImportResolver>();
 }