示例#1
0
        private void RunTest(string sExp, Action<ProcedureBuilder> builder)
        {
            var pb = new ProcedureBuilder(this.pb.Program.Architecture);
            builder(pb);
            var proc = pb.Procedure;
            var dg = new DominatorGraph<Block>(proc.ControlGraph, proc.EntryBlock);
            var project = new Project
            {
                Programs = { this.pb.Program }
            };
            var importResolver = new ImportResolver(
                project,
                this.pb.Program,
                new FakeDecompilerEventListener());
            var arch = new FakeArchitecture();
            
            var platform = new FakePlatform(null, arch);

            // Register r1 is assumed to always be implicit when calling
            // another procedure.
            var implicitRegs = new HashSet<RegisterStorage>
            {
                arch.GetRegister(1)
            };
            Debug.Print("GetRegister(1) {0}", arch.GetRegister(1));
            this.pb.Program.Platform = platform;
            this.pb.Program.Platform = new FakePlatform(null, new FakeArchitecture());
            this.pb.Program.SegmentMap = new SegmentMap(
                Address.Ptr32(0x0000),
                new ImageSegment(
                    ".text",
                    Address.Ptr32(0), 
                    0x40000,
                    AccessMode.ReadWriteExecute));

            // Perform the initial transformation
            var ssa = new SsaTransform(programFlow, proc, importResolver, dg, implicitRegs);

            // Propagate values and simplify the results.
            // We hope the the sequence
            //   esp = fp - 4
            //   mov [esp-4],eax
            // will become
            //   esp_2 = fp - 4
            //   mov [fp - 8],eax

            var vp = new ValuePropagator(this.pb.Program.Architecture, ssa.SsaState);
            vp.Transform();

            ssa.RenameFrameAccesses = true;
            ssa.AddUseInstructions = true;
            ssa.Transform();

            var writer = new StringWriter();
            proc.Write(false, writer);
            var sActual = writer.ToString();
            if (sActual != sExp)
                Debug.Print(sActual);
            Assert.AreEqual(sExp, sActual);
        }
示例#2
0
        private void Given_Program()
        {
            this.arch = new FakeArchitecture();
            var platform = new FakePlatform(null, arch);

            this.program = new Program
            {
                SegmentMap = new SegmentMap(
                        Address.Ptr32(0x1000),
                        new ImageSegment(
                            ".text",
                            new MemoryArea(Address.Ptr32(0x1000), new byte[1000]),
                            AccessMode.ReadExecute)),
                Platform = platform,
                Architecture = arch,
            };
        }
示例#3
0
        public void EP_ConditionOf()
        {
            var p = new ProgramBuilder();
            var proc = p.Add("main", (m) =>
            {
                var szo = m.Frame.EnsureFlagGroup(Registers.eflags, 0x7, "SZO", PrimitiveType.Byte);
                var ebx = m.Frame.EnsureRegister(new RegisterStorage("ebx", 3, 0, PrimitiveType.Word32));
                var v4 = m.Frame.CreateTemporary(PrimitiveType.Word16);

                m.Assign(v4, m.IAdd(m.LoadW(ebx), 1));
                m.Store(ebx, v4);
                m.Assign(szo, m.Cond(v4));
                m.Return();
            });

            var arch = new X86ArchitectureFlat32();
            var platform = new FakePlatform(null, arch);
            var ctx = new SymbolicEvaluationContext(arch, proc.Frame);
            var simplifier = new ExpressionSimplifier(ctx);
            var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow());

            var newInstr = proc.EntryBlock.Succ[0].Statements[2].Instruction.Accept(ep);
            Assert.AreEqual("SZO = cond(v4)", newInstr.ToString());
        }
        public void Dfa2_UserDefinedStackArgs()
        {
            var arch = new X86ArchitectureFlat32();
            var pb = new ProgramBuilder(arch);
            var test = pb.Add(
                new Procedure_v1
                {
                    CSignature = "void test(int a, int b)"
                },
                m => {
                    var sp = m.Register(m.Architecture.StackRegister);
                    var r1 = m.Reg32("r1", 1);
                    var r2 = m.Reg32("r2", 2);
                    var fp = m.Frame.FramePointer;
                    m.Assign(r1, m.LoadDw(m.IAdd(fp, 4)));
                    m.Assign(r2, m.LoadDw(m.IAdd(fp, 8)));
                    m.Assign(r1, m.IAdd(r1, r2));
                    m.Store(m.Word32(0x010008), r1);
                    m.Return();
                });
            var program = pb.BuildProgram();
            var platform = new FakePlatform(null, arch);
            platform.Test_CreateProcedureSerializer = (t, d) =>
            {
                var typeLoader = new TypeLibraryDeserializer(platform, false, new TypeLibrary());
                return new X86ProcedureSerializer((IntelArchitecture)program.Architecture, typeLoader, "");
            };

            program.Platform = platform;
            var dfa = new DataFlowAnalysis(program, new FakeDecompilerEventListener());
            dfa.AnalyzeProgram2();
            var sExp = @"// test
// Return size: 4
void test(int32 a, int32 b)
test_entry:
	// succ:  l1
l1:
	word32 r1_4 = a + b
	Mem5[0x00010008:word32] = r1_4
	return
	// succ:  test_exit
test_exit:
";
            AssertProgram(sExp, pb.Program);
        }
示例#5
0
        public void EP_LValue()
        {
            var arch = new FakeArchitecture();
            var platform = new FakePlatform(null, arch);
            var p = new ProgramBuilder(arch);
            Identifier r2 = null;
            Identifier sp = null;
            var proc = p.Add("main", (m) =>
            {
                r2 = m.Register("r2");
                sp = m.Frame.EnsureRegister(arch.StackRegister);
                m.Store(m.ISub(sp, 12), m.ISub(sp, 16));
                m.Store(m.ISub(sp, 12), 2);
            });

            var ctx = new SymbolicEvaluationContext (arch, proc.Frame);
            var simplifier = new ExpressionSimplifier(ctx);
            var ep = new ExpressionPropagator(platform, simplifier,ctx, new ProgramDataFlow());

            ctx.RegisterState[arch.StackRegister]= proc.Frame.FramePointer;

            var stms = proc.EntryBlock.Succ[0].Statements;
            var instr1 = stms[0].Instruction.Accept(ep);
            Assert.AreEqual("dwLoc0C = fp - 0x00000010", instr1.ToString());
            var instr2 = stms[1].Instruction.Accept(ep);
            Assert.AreEqual("dwLoc0C = 0x00000002", instr2.ToString());
        }
示例#6
0
        public void EP_AddrOf()
        {
            var arch = new FakeArchitecture();
            var platform = new FakePlatform(null, arch);
            var p = new ProgramBuilder(arch);
            Identifier r2 = null, r3 = null;
            var proc = p.Add("main", (m) =>
            {
                r2 = m.Register("r2");
                r3 = m.Register("r3");
                m.Assign(r2, 0x1234);                       // after which R2 has a definite value
                m.SideEffect(m.Fn("Foo", m.Out(PrimitiveType.Pointer32, r2)));    // Can't promise R2 is preserved after call, so should be invalid.
                m.Assign(r3, r2);
            });

            var ctx = new SymbolicEvaluationContext(arch, proc.Frame);
            var simplifier = new ExpressionSimplifier(ctx);
            var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow());

            ctx.RegisterState[arch.StackRegister] = proc.Frame.FramePointer;

            var stms = proc.EntryBlock.Succ[0].Statements;
            stms[0].Instruction.Accept(ep);
            Assert.AreEqual("0x00001234", ctx.GetValue(r2).ToString());
            var instr2 = stms[1].Instruction.Accept(ep);
            Assert.AreEqual("Foo(out r2)", instr2.ToString());
            Assert.AreEqual("<invalid>", ctx.GetValue(r2).ToString());
            var instr3 = stms[2].Instruction.Accept(ep);
            Assert.AreEqual("r3 = r2", instr3.ToString());
            Assert.AreEqual("<invalid>", ctx.GetValue(r2).ToString());
            Assert.AreEqual("<invalid>", ctx.GetValue(r3).ToString());
        }
示例#7
0
        public void EP_StackReference()
        {
            var arch = new FakeArchitecture();
            var platform = new FakePlatform(null, arch);
            var p = new ProgramBuilder(arch);
            var proc = p.Add("main", (m) =>
            {
                var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister);
                var r1 = m.Register(1);
                m.Assign(sp, m.ISub(sp, 4));
                m.Assign(r1, m.LoadDw(m.IAdd(sp, 8)));
                m.Return();
            });

            var ctx = new SymbolicEvaluationContext(arch, proc.Frame);
            var simplifier = new ExpressionSimplifier(ctx);
            var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow());

            ctx.RegisterState[arch.StackRegister] = proc.Frame.FramePointer;

            var stms = proc.EntryBlock.Succ[0].Statements;
            var newInstr = stms[0].Instruction.Accept(ep);
            Assert.AreEqual("r63 = fp - 0x00000004", newInstr.ToString());
            newInstr = stms[1].Instruction.Accept(ep);
            Assert.AreEqual("r1 = dwArg04", newInstr.ToString());
        }
示例#8
0
        public void EP_IndirectCall()
        {
            var arch = new FakeArchitecture();
            var p = new ProgramBuilder(arch);
            var proc = p.Add("main", (m) =>
            {
                var r1 = m.Register("r1");

                m.Assign(r1, m.Word32(0x42));
                m.Emit(new CallInstruction(r1, new CallSite(4, 0)));
                m.Return();
            });

            var platform = new FakePlatform(null, arch)
            {
                Test_CreateTrashedRegisters = () => new HashSet<RegisterStorage>()
            };
            var ctx = new SymbolicEvaluationContext(arch, proc.Frame);
            var simplifier = new ExpressionSimplifier(ctx);
            var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow());

            ctx.RegisterState[arch.StackRegister] = proc.Frame.FramePointer;
            var stms = proc.EntryBlock.Succ[0].Statements;
            stms[0].Instruction.Accept(ep);
            var newInstr = stms[1].Instruction.Accept(ep);
            Assert.AreEqual("call 0x00000042 (retsize: 4; depth: 4)", newInstr.ToString());
        }
示例#9
0
 private void Given_Program(Address address, byte[] bytes)
 {
     var mem = new MemoryArea(address, bytes);
     var segmentMap = new SegmentMap(
         mem.BaseAddress,
         new ImageSegment("proggie", mem, AccessMode.ReadExecute));
     var arch = new X86ArchitectureFlat32();
     var platform = new FakePlatform(null, arch);
     this.program = new Program
     {
         Architecture = arch,
         SegmentMap = segmentMap,
         Platform = platform
     };
     platform.Test_CreateProcedureSerializer = (t, d) =>
     {
         var typeLoader = new TypeLibraryDeserializer(platform, false, new TypeLibrary());
         return new X86ProcedureSerializer((IntelArchitecture)program.Architecture, typeLoader, "");
     };
 }