Example #1
0
        public Block CloneBlock(Block blockOrig)
        {
            if (blockOrig == blockOrig.Procedure.ExitBlock)
            {
                return(null);
            }

            var succ     = blockOrig.Succ.Count > 0 ? CloneBlock(blockOrig.Succ[0]) : null;
            var blockNew = new Block(procCalling, blockOrig.Name + "_in_" + procCalling.Name);

            foreach (var stm in blockOrig.Statements)
            {
                Statement = stm;
                blockNew.Statements.Add(new Statement(
                                            stm.LinearAddress,
                                            stm.Instruction.Accept(this),
                                            blockNew));
            }
            procCalling.AddBlock(blockNew);
            if (succ == null)
            {
                procCalling.ControlGraph.AddEdge(blockNew, procCalling.ExitBlock);
            }
            else
            {
                procCalling.ControlGraph.AddEdge(blockNew, succ);
            }
            return(blockNew);
        }
Example #2
0
        public void Bwi_CallTerminatingProcedure_StopScanning()
        {
            proc = Procedure.Create(program.Architecture, "proc", Address.Ptr32(0x102000), new Frame(PrimitiveType.Ptr32));
            var terminator = Procedure.Create(program.Architecture, "terminator", Address.Ptr32(0x0001000), new Frame(PrimitiveType.Ptr32));

            terminator.Characteristics = new ProcedureCharacteristics {
                Terminates = true,
            };
            block = proc.AddBlock("the_block");
            arch.Setup(a => a.PointerType).Returns(PrimitiveType.Word32);
            scanner.Setup(s => s.FindContainingBlock(It.IsAny <Address>())).Returns(block);
            Given_NoImportedProcedure();
            Given_NoInlinedCall();
            scanner.Setup(s => s.ScanProcedure(
                              It.IsNotNull <IProcessorArchitecture>(),
                              It.IsAny <Address>(),
                              It.IsAny <string>(),
                              It.IsAny <ProcessorState>()))
            .Returns(terminator)
            .Verifiable();
            scanner.Setup(s => s.TerminateBlock(It.IsNotNull <Block>(), It.IsNotNull <Address>())).Verifiable();
            arch.Setup(a => a.FramePointerType).Returns(PrimitiveType.Ptr32);
            Given_SimpleTrace(trace);

            trace.Add(m => m.Call(Address.Ptr32(0x00102000), 4));
            trace.Add(m => m.SideEffect(new ProcedureConstant(VoidType.Instance, new PseudoProcedure("shouldnt_decompile_this", VoidType.Instance, 0))));

            var wi = CreateWorkItem(Address.Ptr32(0x2000));

            wi.Process();

            Assert.AreEqual(1, block.Statements.Count, "Should only have rewritten the Call to 'terminator'");
            scanner.Verify();
        }
Example #3
0
        public void Bwi_CallTerminatingProcedure_StopScanning()
        {
            proc = Procedure.Create(program.Architecture, "proc", Address.Ptr32(0x102000), new Frame(PrimitiveType.Ptr32));
            var terminator = Procedure.Create(program.Architecture, "terminator", Address.Ptr32(0x0001000), new Frame(PrimitiveType.Ptr32));

            terminator.Characteristics = new ProcedureCharacteristics {
                Terminates = true,
            };
            block = proc.AddBlock("the_block");
            arch.Stub(a => a.PointerType).Return(PrimitiveType.Word32);
            scanner.Stub(s => s.FindContainingBlock(Arg <Address> .Is.Anything)).Return(block);
            scanner.Stub(s => s.GetImportedProcedure(Arg <Address> .Is.Anything, Arg <Address> .Is.NotNull)).Return(null);
            scanner.Expect(s => s.ScanProcedure(
                               Arg <Address> .Is.Anything,
                               Arg <string> .Is.Anything,
                               Arg <ProcessorState> .Is.Anything))
            .Return(terminator);
            scanner.Expect(s => s.TerminateBlock(Arg <Block> .Is.NotNull, Arg <Address> .Is.NotNull));
            arch.Stub(a => a.FramePointerType).Return(PrimitiveType.Ptr32);
            scanner.Stub(s => s.GetTrace(null, null, null)).IgnoreArguments().Return(trace);
            mr.ReplayAll();

            trace.Add(m => m.Call(Address.Ptr32(0x00102000), 4));
            trace.Add(m => m.SideEffect(new ProcedureConstant(VoidType.Instance, new PseudoProcedure("shouldnt_decompile_this", VoidType.Instance, 0))));

            var wi = CreateWorkItem(Address.Ptr32(0x2000));

            wi.Process();

            Assert.AreEqual(1, block.Statements.Count, "Should only have rewritten the Call to 'terminator'");
            mr.VerifyAll();
        }
Example #4
0
        public Block BlockOf(string label, bool defer)
        {
            Block b;

            if (deferredBlocks.TryGetValue(label, out b))
            {
                if (!defer)
                {
                    deferredBlocks.Remove(label);
                    labelMap.Add(label, b);
                }
                return(b);
            }
            if (!labelMap.TryGetValue(label, out b))
            {
                b = proc.AddBlock("l" + label);
                if (defer)
                {
                    deferredBlocks.Add(label, b);
                }
                else
                {
                    labelMap.Add(label, b);
                }
            }
            return(b);
        }
Example #5
0
        /// <summary>
        /// Creates a small basic block, consisting solely of a 'call' followed by a 'return'
        /// instruction.
        /// </summary>
        /// <remarks>
        /// This is done when encountering tail calls (i.e. jumps) from one
        /// procedure into another.
        /// </remarks>
        /// <param name="addrFrom"></param>
        /// <param name="procOld"></param>
        /// <param name="procNew"></param>
        /// <returns></returns>
        public Block CreateCallRetThunk(Address addrFrom, Procedure procOld, Procedure procNew)
        {
            //$BUG: ReturnAddressOnStack property needs to be properly set, the
            // EvenOdd sample shows how this doesn't work currently.
            var blockName = string.Format(
                "{0}_thunk_{1}",
                Block.GenerateName(addrFrom),
                procNew.Name);
            var callRetThunkBlock = procOld.AddBlock(blockName);

            callRetThunkBlock.IsSynthesized = true;

            var linFrom = addrFrom.ToLinear();

            callRetThunkBlock.Statements.Add(
                linFrom,
                new CallInstruction(
                    new ProcedureConstant(Program.Platform.PointerType, procNew),
                    new CallSite(
                        procNew.Signature.ReturnAddressOnStack,
                        0)));
            Program.CallGraph.AddEdge(callRetThunkBlock.Statements.Last, procNew);

            callRetThunkBlock.Statements.Add(linFrom, new ReturnInstruction());
            procOld.ControlGraph.AddEdge(callRetThunkBlock, procOld.ExitBlock);
            SetProcedureReturnAddressBytes(procOld, procNew.Frame.ReturnAddressSize, addrFrom);
            return(callRetThunkBlock);
        }
Example #6
0
 public void Setup()
 {
     mr = new MockRepository();
     program = new Program();
     proc = new Procedure("testProc", new Frame(PrimitiveType.Word32));
     block = proc.AddBlock("l00100000");
     trace = new RtlTrace(0x00100000);
     r0 = new Identifier("r0", PrimitiveType.Word32, new RegisterStorage("r0", 0, 0, PrimitiveType.Word32));
     r1 = new Identifier("r1", PrimitiveType.Word32, new RegisterStorage("r1", 1, 0, PrimitiveType.Word32));
     r2 = new Identifier("r2", PrimitiveType.Word32, new RegisterStorage("r2", 2, 0, PrimitiveType.Word32));
     sp = new Identifier("sp", PrimitiveType.Word32, new RegisterStorage("sp", 15, 0, PrimitiveType.Word32));
     grf = proc.Frame.EnsureFlagGroup(Registers.eflags, 3, "SCZ", PrimitiveType.Byte);
     var sc = new ServiceContainer();
     var listener = mr.Stub<DecompilerEventListener>();
     scanner = mr.StrictMock<IScanner>();
     arch = mr.Stub<IProcessorArchitecture>();
     program.Architecture = arch;
     program.SegmentMap = new SegmentMap(
         Address.Ptr32(0x00100000),
         new ImageSegment(
             ".text",
             new MemoryArea(Address.Ptr32(0x00100000), new byte[0x20000]),
             AccessMode.ReadExecute));
     arch.Replay();
     program.Platform = new DefaultPlatform(null, arch);
     arch.BackToRecord();
     arch.Stub(s => s.StackRegister).Return((RegisterStorage)sp.Storage);
     arch.Stub(s => s.PointerType).Return(PrimitiveType.Pointer32);
     scanner.Stub(s => s.Services).Return(sc);
     sc.AddService<DecompilerEventListener>(listener);
 }
Example #7
0
        public void Setup()
        {
            mr      = new MockRepository();
            program = new Program();
            proc    = new Procedure(program.Architecture, "testProc", new Frame(PrimitiveType.Word32));
            block   = proc.AddBlock("l00100000");
            trace   = new RtlTrace(0x00100000);
            r0      = new Identifier("r0", PrimitiveType.Word32, new RegisterStorage("r0", 0, 0, PrimitiveType.Word32));
            r1      = new Identifier("r1", PrimitiveType.Word32, new RegisterStorage("r1", 1, 0, PrimitiveType.Word32));
            r2      = new Identifier("r2", PrimitiveType.Word32, new RegisterStorage("r2", 2, 0, PrimitiveType.Word32));
            sp      = new Identifier("sp", PrimitiveType.Word32, new RegisterStorage("sp", 15, 0, PrimitiveType.Word32));
            grf     = proc.Frame.EnsureFlagGroup(Registers.eflags, 3, "SCZ", PrimitiveType.Byte);
            var sc       = new ServiceContainer();
            var listener = mr.Stub <DecompilerEventListener>();

            scanner = mr.StrictMock <IScanner>();
            arch    = mr.Stub <IProcessorArchitecture>();
            program.Architecture = arch;
            program.SegmentMap   = new SegmentMap(
                Address.Ptr32(0x00100000),
                new ImageSegment(
                    ".text",
                    new MemoryArea(Address.Ptr32(0x00100000), new byte[0x20000]),
                    AccessMode.ReadExecute));
            arch.Replay();
            program.Platform = new DefaultPlatform(null, arch);
            arch.BackToRecord();
            arch.StackRegister = (RegisterStorage)sp.Storage;
            arch.Stub(s => s.PointerType).Return(PrimitiveType.Ptr32);
            scanner.Stub(s => s.Services).Return(sc);
            sc.AddService <DecompilerEventListener>(listener);
        }
Example #8
0
        public void BwiUsePatch()
        {
            var addrStart = Address.Ptr32(0x00100000);

            trace.Add(m => m.Assign(r0, m.Mem8(m.Word16(0x0042))));
            trace.Add(m => m.Assign(r1, 42));
            Given_SimpleTrace(trace);
            Given_TransferPatch(addrStart.ToUInt32() + 4, 8, m => {
                m.BranchInMiddleOfInstruction(m.Eq(r0, 1), Address.Ptr32(0x00100100), InstrClass.ConditionalTransfer);
                m.BranchInMiddleOfInstruction(m.Eq(r0, 2), Address.Ptr32(0x00100200), InstrClass.ConditionalTransfer);
                m.BranchInMiddleOfInstruction(m.Eq(r0, 3), Address.Ptr32(0x00100300), InstrClass.ConditionalTransfer);
                m.Goto(Address.Ptr32(0x00100400));
            });
            Given_ExpectedBranchTarget(0x00100100, proc.AddBlock("case1"));
            Given_ExpectedBranchTarget(0x00100200, proc.AddBlock("case2"));
            Given_ExpectedBranchTarget(0x00100300, proc.AddBlock("case3"));
            Given_ExpectedBranchTarget(0x00100400, proc.AddBlock("default"));

            scanner.Setup(s => s.FindContainingBlock(addrStart)).Returns(block);
            scanner.Setup(s => s.FindContainingBlock(addrStart + 4)).Returns(block);

            var wi = CreateWorkItem(addrStart);

            wi.Process();

            var expected =
                @"testProc_entry:
case1:
case2:
case3:
default:
l00100000:
	r0 = Mem0[0x42<16>:byte]
	branch r0 == 1<32> case1
l00100004_1:
	branch r0 == 2<32> case2
l00100004_2:
	branch r0 == 3<32> case3
l00100004_3:
	goto 0x00100400<p32>
	goto default
testProc_exit:
";

            AssertProcedureCode(expected, block.Procedure);
        }
Example #9
0
        private void BuildTest(IntelArchitecture arch, Address addr, IPlatform platform, Action <X86Assembler> m)
        {
            proc  = new Procedure(arch, "test", addr, arch.CreateFrame());
            block = proc.AddBlock("testblock");
            var asm = new X86Assembler(sc, new DefaultPlatform(sc, arch), addr, new List <ImageSymbol>());

            scanner = new Mock <IScanner>();
            scanner.Setup(s => s.Services).Returns(sc);
            m(asm);
            lr         = asm.GetImage();
            this.state = arch.CreateProcessorState();
            host       = new RewriterHost(
                asm.ImportReferences,
                new Dictionary <string, FunctionType>
            {
                {
                    "GetDC",
                    new FunctionType(
                        new Identifier("", new Pointer(VoidType.Instance, 32), new RegisterStorage("eax", 0, 0, PrimitiveType.Word32)),
                        new [] {
                        new Identifier("arg",
                                       new TypeReference(
                                           "HWND",
                                           new Pointer(VoidType.Instance, 32)),
                                       new StackArgumentStorage(4, new TypeReference(
                                                                    "HWND",
                                                                    new Pointer(VoidType.Instance, 32))))
                    })
                    {
                        StackDelta = 4,
                    }
                }
            },
                new Dictionary <string, DataType>());
            var rw = arch.CreateRewriter(
                lr.SegmentMap.Segments.Values.First().MemoryArea.CreateLeReader(addr),
                this.state,
                proc.Frame,
                host);

            this.program = new Program
            {
                Architecture = arch,
                SegmentMap   = lr.SegmentMap,
                ImageMap     = lr.ImageMap,
                Platform     = platform,
            };

            scanner.Setup(x => x.FindContainingBlock(It.IsAny <Address>())).Returns(block);
            scanner.Setup(x => x.GetTrace(
                              It.IsAny <IProcessorArchitecture>(),
                              It.IsAny <Address>(),
                              It.IsAny <ProcessorState>(),
                              It.IsAny <IStorageBinder>())).Returns(rw);
            scanner.Setup(x => x.Services).Returns(sc);

            wi = new BlockWorkitem(scanner.Object, program, arch, state, addr);
        }
Example #10
0
 protected Block BlockOf(string label)
 {
     if (!blocks.TryGetValue(label, out Block b))
     {
         b = Procedure.AddBlock(label);
         blocks.Add(label, b);
     }
     return(b);
 }
Example #11
0
        private Block BlockOf(string label)
        {
            Block b;

            if (!blocks.TryGetValue(label, out b))
            {
                b = Procedure.AddBlock(label);
                blocks.Add(label, b);
            }
            return(b);
        }
Example #12
0
        private void Given_ExpectedBranchTarget(uint uAddrDst, string blockName)
        {
            var block = proc.AddBlock(Address.Ptr32(uAddrDst), blockName);

            scanner.Setup(x => x.EnqueueJumpTarget(
                              It.IsNotNull <Address>(),
                              It.Is <Address>(a => a.ToUInt32() == uAddrDst),
                              block.Procedure,
                              It.IsAny <ProcessorState>()))
            .Returns(block);
        }
Example #13
0
        public void Bwi_RtlIf()
        {
            var followBlock = proc.AddBlock("l00100004");

            using (mr.Record())
            {
                arch.Stub(a => a.GetRegister(1)).Return((RegisterStorage)r1.Storage);
                arch.Stub(a => a.GetRegister(2)).Return((RegisterStorage)r2.Storage);
                arch.Stub(a => a.StackRegister).Return((RegisterStorage)r1.Storage);
                scanner.Stub(s => s.FindContainingBlock(
                                 Arg <Address> .Matches(a => a.ToLinear() == 0x00100000))).Return(block);
                scanner.Stub(s => s.FindContainingBlock(
                                 Arg <Address> .Matches(a => a.ToLinear() == 0x00100004))).Return(followBlock);
                scanner.Stub(s => s.Warn(null, null)).IgnoreArguments().WhenCalled(m =>
                {
                    var d = (Diagnostic)m.Arguments[1];
                    Debug.Print("{0}: {1}", d.GetType().Name, d.Message);
                });
                scanner.Stub(s => s.EnqueueJumpTarget(
                                 Arg <Address> .Is.NotNull,
                                 Arg <Address> .Matches(a => a.ToLinear() == 0x00100004),
                                 Arg <Procedure> .Is.NotNull,
                                 Arg <ProcessorState> .Is.Anything)).Return(followBlock);

                scanner.Stub(s => s.GetTrace(null, null, null)).IgnoreArguments().Return(trace);
            }
            trace.Add(m => m.If(new TestCondition(ConditionCode.GE, grf), new RtlAssignment(r2, r1)));
            var wi = CreateWorkItem(Address.Ptr32(0x00100000), new FakeProcessorState(arch));

            wi.Process();

            var sw = new StringWriter();

            mr.VerifyAll();
            proc.Write(false, sw);
            var sExp =
                @"// testProc
// Return size: 0
void testProc()
testProc_entry:
l00100000:
	branch Test(LT,SCZ) l00100004
	// succ:  l00100000_1 l00100004
l00100000_1:
	r2 = r1
	// succ:  l00100004
l00100004:
testProc_exit:
";

            Assert.AreEqual(sExp, sw.ToString());
        }
Example #14
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");
        }
Example #15
0
        private void BuildTest(IntelArchitecture arch, Address addr, IPlatform platform, Action <X86Assembler> m)
        {
            this.arch  = new X86ArchitectureFlat32();
            proc       = new Procedure("test", arch.CreateFrame());
            block      = proc.AddBlock("testblock");
            this.state = arch.CreateProcessorState();
            var asm = new X86Assembler(sc, new DefaultPlatform(sc, arch), addr, new List <ImageSymbol>());

            scanner = mr.StrictMock <IScanner>();
            m(asm);
            lr   = asm.GetImage();
            host = new RewriterHost(asm.ImportReferences,
                                    new Dictionary <string, ProcedureSignature>
            {
                {
                    "GetDC",
                    new ProcedureSignature(
                        new Identifier("", new Pointer(VoidType.Instance, 4), new RegisterStorage("eax", 0, 0, PrimitiveType.Word32)),
                        new Identifier("arg",
                                       new TypeReference(
                                           "HWND",
                                           new Pointer(VoidType.Instance, 4)),
                                       new StackArgumentStorage(0, new TypeReference(
                                                                    "HWND",
                                                                    new Pointer(VoidType.Instance, 4)))))
                    {
                        StackDelta = 4,
                    }
                }
            });
            var rw = arch.CreateRewriter(
                lr.SegmentMap.Segments.Values.First().MemoryArea.CreateLeReader(addr),
                this.state,
                proc.Frame,
                host);
            var prog = new Program
            {
                Architecture = arch,
                SegmentMap   = lr.SegmentMap,
                ImageMap     = lr.ImageMap,
                Platform     = platform,
            };

            using (mr.Record())
            {
                scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Is.Anything)).Return(block);
                scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(rw);
            }
            wi = new BlockWorkitem(scanner, prog, state, addr);
        }
Example #16
0
        public override void Process()
        {
            var movedBlocks = new HashSet <Block>();
            var stack       = new Stack <IEnumerator <Block> >();

            stack.Push(new Block[] { Block }.Cast <Block>().GetEnumerator());
            while (stack.Count != 0)
            {
                DumpBlocks(Block.Procedure);
                var e = stack.Peek();
                if (!e.MoveNext())
                {
                    stack.Pop();
                    continue;
                }
                var b = e.Current;
                if (b.Procedure == ProcNew || b == b.Procedure.ExitBlock || b.Procedure.EntryBlock.Succ[0] == b)
                {
                    continue;
                }

                trace.Verbose("PBW:     Visiting block {0}, stack depth {1}", b.DisplayName, stack.Count);
                var replacer = new IdentifierRelocator(b.Procedure.Frame, ProcNew.Frame);
                b.Procedure.RemoveBlock(b);
                ProcNew.AddBlock(b);
                b.Procedure = ProcNew;
                movedBlocks.Add(b);
                foreach (var stm in b.Statements)
                {
                    if (stm.LinearAddress == 0x00000000000009c4)
                    {
                        stm.ToString();
                    }
                    stm.Instruction = replacer.ReplaceIdentifiers(stm.Instruction);
                }
                if (b.Succ.Count > 0)
                {
                    stack.Push(b.Succ.GetEnumerator());
                }
            }
            foreach (var b in movedBlocks)
            {
                FixExitEdges(b);
                FixInboundEdges(b);
                FixOutboundEdges(b);
                //  SanityCheck(b);
            }
        }
Example #17
0
        /// <summary>
        /// Inserts a frame pointer assignment at the beginning of the procedure
        /// </summary>
        /// <remarks>
        /// The frame pointer assignment needs a block of its own, as placing it in the
        /// "entryBlock" wreaks havoc with SSA assignments &c.
        /// </remarks>
        public void InsertFramePointerAssignment(IProcessorArchitecture arch)
        {
            Block b = proc.AddBlock(proc.Name + "_frame_asgn");
            Block s = proc.EntryBlock.Succ[0];

            proc.ControlGraph.RemoveEdge(proc.EntryBlock, s);
            proc.ControlGraph.AddEdge(proc.EntryBlock, b);
            proc.ControlGraph.AddEdge(b, s);
            StructureType st    = new StructureType(proc.Name + "_frame_t", 0);
            Identifier    frame = proc.Frame.CreateTemporary(proc.Name + "_frame", st);

            b.Statements.Add(
                0,
                new Assignment(
                    proc.Frame.FramePointer,
                    new UnaryExpression(Operator.AddrOf, arch.FramePointerType, frame)));
        }
Example #18
0
        /// <summary>
        /// Creates a small basic block, consisting solely of a 'call' followed by a 'return'
        /// instruction.
        /// </summary>
        /// <param name="addrFrom"></param>
        /// <param name="procOld"></param>
        /// <param name="procNew"></param>
        /// <returns></returns>
        public Block CreateCallRetThunk(Address addrFrom, Procedure procOld, Procedure procNew)
        {
            var blockName = string.Format(
                "{0}_thunk_{1}",
                GenerateBlockName(addrFrom),
                procNew.Name);
            var callRetThunkBlock = procOld.AddBlock(blockName);

            callRetThunkBlock.Statements.Add(0, new CallInstruction(
                                                 new ProcedureConstant(program.Platform.PointerType, procNew),
                                                 new CallSite(procNew.Signature.ReturnAddressOnStack, 0)));
            program.CallGraph.AddEdge(callRetThunkBlock.Statements.Last, procNew);
            callRetThunkBlock.Statements.Add(0, new ReturnInstruction());
            procOld.ControlGraph.AddEdge(callRetThunkBlock, procOld.ExitBlock);
            SetProcedureReturnAddressBytes(procOld, procNew.Frame.ReturnAddressSize, addrFrom);
            return(callRetThunkBlock);
        }
Example #19
0
        public override void Process()
        {
            var movedBlocks = new HashSet <Block>();
            var stack       = new Stack <IEnumerator <Block> >();

            stack.Push(new Block[] { Block }.Cast <Block>().GetEnumerator());
            var replacer = new IdentifierReplacer(ProcNew.Frame);

            while (stack.Count != 0)
            {
                DumpBlocks(Block.Procedure);
                var e = stack.Peek();
                if (!e.MoveNext())
                {
                    stack.Pop();
                    continue;
                }
                var b = e.Current;
                if (b.Procedure == ProcNew || b == b.Procedure.ExitBlock || b.Procedure.EntryBlock.Succ[0] == b)
                {
                    continue;
                }

                Debug.Print("PromoteBlock visiting block {0}", b.Name);
                b.Procedure.RemoveBlock(b);
                ProcNew.AddBlock(b);
                b.Procedure = ProcNew;
                movedBlocks.Add(b);
                foreach (var stm in b.Statements)
                {
                    stm.Instruction = replacer.ReplaceIdentifiers(stm.Instruction);
                }
                if (b.Succ.Count > 0)
                {
                    stack.Push(b.Succ.GetEnumerator());
                }
            }
            foreach (var b in movedBlocks)
            {
                FixExitEdges(b);
                FixInboundEdges(b);
                FixOutboundEdges(b);
            }
        }
Example #20
0
        public void Setup()
        {
            mr = new MockRepository();
            program = new Program();
            proc = new Procedure("testProc", new Frame(PrimitiveType.Word32));
            block = proc.AddBlock("l00100000");
            trace = new RtlTrace(0x00100000);
            r0 = new Identifier("r0", PrimitiveType.Word32, new RegisterStorage("r0", 0, 0, PrimitiveType.Word32));
            r1 = new Identifier("r1", PrimitiveType.Word32, new RegisterStorage("r1", 1, 0, PrimitiveType.Word32));
            r2 = new Identifier("r2", PrimitiveType.Word32, new RegisterStorage("r2", 2, 0, PrimitiveType.Word32));
            grf = proc.Frame.EnsureFlagGroup(Registers.eflags, 3, "SCZ", PrimitiveType.Byte);

            scanner = mr.StrictMock<IScanner>();
            arch = mr.DynamicMock<IProcessorArchitecture>();
            arch.Stub(s => s.PointerType).Return(PrimitiveType.Pointer32);
            program.Architecture = arch;
            arch.Replay();
            program.Platform = new DefaultPlatform(null, arch);
            arch.BackToRecord();
        }
Example #21
0
        public void Setup()
        {
            mr      = new MockRepository();
            program = new Program();
            proc    = new Procedure("testProc", new Frame(PrimitiveType.Word32));
            block   = proc.AddBlock("l00100000");
            trace   = new RtlTrace(0x00100000);
            r0      = new Identifier("r0", PrimitiveType.Word32, new RegisterStorage("r0", 0, 0, PrimitiveType.Word32));
            r1      = new Identifier("r1", PrimitiveType.Word32, new RegisterStorage("r1", 1, 0, PrimitiveType.Word32));
            r2      = new Identifier("r2", PrimitiveType.Word32, new RegisterStorage("r2", 2, 0, PrimitiveType.Word32));
            grf     = proc.Frame.EnsureFlagGroup(Registers.eflags, 3, "SCZ", PrimitiveType.Byte);

            scanner = mr.StrictMock <IScanner>();
            arch    = mr.DynamicMock <IProcessorArchitecture>();
            arch.Stub(s => s.PointerType).Return(PrimitiveType.Pointer32);
            program.Architecture = arch;
            arch.Replay();
            program.Platform = new DefaultPlatform(null, arch);
            arch.BackToRecord();
        }
Example #22
0
        public Block CloneBlock(Block blockOrig)
        {
            if (blockOrig == blockOrig.Procedure.ExitBlock)
            {
                return(null);
            }

            Block blockNew;

            if (mpBlocks.TryGetValue(blockOrig, out blockNew))
            {
                return(blockNew);
            }
            blockNew         = new Block(procCalling, blockOrig.Name + "_in_" + procCalling.Name);
            blockNew.Address = blockOrig.Address;
            mpBlocks.Add(blockOrig, blockNew);
            var succ = blockOrig.Succ.Count > 0 ? CloneBlock(blockOrig.Succ[0]) : null;

            foreach (var stm in blockOrig.Statements)
            {
                Statement    = stm;
                StatementNew = new Statement(
                    stm.LinearAddress,
                    null,
                    blockNew);
                StatementNew.Instruction = stm.Instruction.Accept(this);

                blockNew.Statements.Add(StatementNew);
            }
            procCalling.AddBlock(blockNew);
            if (succ == null)
            {
                procCalling.ControlGraph.AddEdge(blockNew, procCalling.ExitBlock);
            }
            else
            {
                procCalling.ControlGraph.AddEdge(blockNew, succ);
            }
            return(blockNew);
        }
Example #23
0
        public void Setup()
        {
            program = new Program();
            trace   = new RtlTrace(0x00100000);
            r0      = new Identifier("r0", PrimitiveType.Word32, new RegisterStorage("r0", 0, 0, PrimitiveType.Word32));
            r1      = new Identifier("r1", PrimitiveType.Word32, new RegisterStorage("r1", 1, 0, PrimitiveType.Word32));
            r2      = new Identifier("r2", PrimitiveType.Word32, new RegisterStorage("r2", 2, 0, PrimitiveType.Word32));
            sp      = new Identifier("sp", PrimitiveType.Word32, new RegisterStorage("sp", 15, 0, PrimitiveType.Word32));
            var sc       = new ServiceContainer();
            var listener = new Mock <DecompilerEventListener>();

            scanner = new Mock <IScanner>();
            arch    = new Mock <IProcessorArchitecture>();
            arch.Setup(a => a.Name).Returns("FakeArch");
            proc  = new Procedure(arch.Object, "testProc", Address.Ptr32(0x00100000), new Frame(PrimitiveType.Word32));
            block = proc.AddBlock(proc.EntryAddress, "l00100000");
            grf   = proc.Frame.EnsureFlagGroup(Registers.eflags, 3, "SCZ", PrimitiveType.Byte);
            program.Architecture = arch.Object;
            program.SegmentMap   = new SegmentMap(
                Address.Ptr32(0x00100000),
                new ImageSegment(
                    ".text",
                    new ByteMemoryArea(Address.Ptr32(0x00100000), new byte[0x20000]),
                    AccessMode.ReadExecute));
            program.Platform = new DefaultPlatform(sc, arch.Object);
            arch.Setup(a => a.StackRegister).Returns((RegisterStorage)sp.Storage);
            arch.Setup(s => s.PointerType).Returns(PrimitiveType.Ptr32);
            arch.Setup(s => s.CreateFrameApplicationBuilder(
                           It.IsAny <IStorageBinder>(),
                           It.IsAny <CallSite>(),
                           It.IsAny <Expression>()))
            .Returns((IStorageBinder frame, CallSite site, Expression callee) =>
                     new FrameApplicationBuilder(arch.Object, frame, site, callee, false));
            scanner.Setup(s => s.Services).Returns(sc);
            sc.AddService <DecompilerEventListener>(listener.Object);
        }
Example #24
0
 private StructureNode NewNode(string name)
 {
     return(new StructureNode(proc.AddBlock(name), nodeCount++));
 }
        private void BuildTest(IntelArchitecture arch, Address addr, Platform platform, Action<X86Assembler> m)
        {
            this.arch = new IntelArchitecture(ProcessorMode.Protected32);
            proc = new Procedure("test", arch.CreateFrame());
            block = proc.AddBlock("testblock");
            this.state = arch.CreateProcessorState();
            var asm = new X86Assembler(arch, addr, new List<EntryPoint>());
            scanner = repository.StrictMock<IScanner>();
            m(asm);
            lr = asm.GetImage();
            host = new RewriterHost(asm.ImportReferences,
                new Dictionary<string, ProcedureSignature>
                {
                {
                    "GetDC", 
                    new ProcedureSignature(
                        new Identifier("", new Pointer(VoidType.Instance, 4), new RegisterStorage("eax", 0, PrimitiveType.Word32)),
                        new Identifier("arg", 
                            new TypeReference(
                                "HWND",
                                new Pointer(VoidType.Instance, 4)),
                            new StackArgumentStorage(0, new TypeReference(
                                "HWND",
                                new Pointer(VoidType.Instance, 4)))))
                                {
                                    StackDelta = 4,
}
                }
              });
            var rw = arch.CreateRewriter(lr.Image.CreateLeReader(addr), this.state, proc.Frame, host);
            var prog = new Program
            {
                Architecture = arch,
                Image = lr.Image,
                ImageMap = lr.ImageMap,
                Platform = platform,
            };
            using (repository.Record())
            {
                scanner.Stub(x => x.FindContainingBlock(Arg<Address>.Is.Anything)).Return(block);
                scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(rw);
            }
            wi = new BlockWorkitem(scanner, prog, state, addr);
        }
        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");
        }
Example #27
0
        /// <summary>
        /// Creates a small basic block, consisting solely of a 'call' followed by a 'return'
        /// instruction. 
        /// </summary>
        /// <param name="addrFrom"></param>
        /// <param name="procOld"></param>
        /// <param name="procNew"></param>
        /// <returns></returns>
        public Block CreateCallRetThunk(Address addrFrom, Procedure procOld, Procedure procNew)
        {
            //$BUG: ReturnAddressOnStack property needs to be properly set, the
            // EvenOdd sample shows how this doesn't work currently. 
            var blockName = string.Format(
                "{0}_thunk_{1}", 
                Block.GenerateName(addrFrom),
                procNew.Name);
            var callRetThunkBlock = procOld.AddBlock(blockName);
            callRetThunkBlock.IsSynthesized = true;

            var linFrom = addrFrom.ToLinear();
            callRetThunkBlock.Statements.Add(
                addrFrom.ToLinear(), 
                new CallInstruction(
                    new ProcedureConstant(program.Platform.PointerType, procNew),
                    new CallSite(
                        procNew.Signature.ReturnAddressOnStack,
                        0)));
            program.CallGraph.AddEdge(callRetThunkBlock.Statements.Last, procNew);

            callRetThunkBlock.Statements.Add(linFrom, new ReturnInstruction());
            procOld.ControlGraph.AddEdge(callRetThunkBlock, procOld.ExitBlock);
            SetProcedureReturnAddressBytes(procOld, procNew.Frame.ReturnAddressSize, addrFrom);
            return callRetThunkBlock;
        }
Example #28
0
 /// <summary>
 /// Creates a small basic block, consisting solely of a 'call' followed by a 'return'
 /// instruction. 
 /// </summary>
 /// <param name="addrFrom"></param>
 /// <param name="procOld"></param>
 /// <param name="procNew"></param>
 /// <returns></returns>
 public Block CreateCallRetThunk(Address addrFrom, Procedure procOld, Procedure procNew)
 {
     var blockName = string.Format(
         "{0}_thunk_{1}", 
         GenerateBlockName(addrFrom),
         procNew.Name);
     var callRetThunkBlock = procOld.AddBlock(blockName);
     callRetThunkBlock.Statements.Add(0, new CallInstruction(
             new ProcedureConstant(program.Platform.PointerType, procNew),
             new CallSite(procNew.Signature.ReturnAddressOnStack, 0)));
     program.CallGraph.AddEdge(callRetThunkBlock.Statements.Last, procNew);
     callRetThunkBlock.Statements.Add(0, new ReturnInstruction());
     procOld.ControlGraph.AddEdge(callRetThunkBlock, procOld.ExitBlock);
     SetProcedureReturnAddressBytes(procOld, procNew.Frame.ReturnAddressSize, addrFrom);
     return callRetThunkBlock;
 }
Example #29
0
        private void Given_DummyBlock(Procedure proc)
        {
            var block = proc.AddBlock(Address.Ptr32(0x100), "0x100");

            proc.ControlGraph.AddEdge(proc.EntryBlock, block);
        }
Example #30
0
        public void Bwi_CallTerminatingProcedure_StopScanning()
        {
            proc = Procedure.Create("proc", Address.Ptr32(0x002000), new Frame(PrimitiveType.Pointer32));
            var terminator = Procedure.Create("terminator", Address.Ptr32(0x0001000), new Frame(PrimitiveType.Pointer32));
            terminator.Characteristics = new ProcedureCharacteristics {
                Terminates = true,
             };
            block = proc.AddBlock("the_block");
            scanner = mr.StrictMock<IScanner>();
            arch.Stub(a => a.PointerType).Return(PrimitiveType.Word32);
            scanner.Stub(s => s.FindContainingBlock(Arg<Address>.Is.Anything)).Return(block);
            scanner.Stub(s => s.GetCallSignatureAtAddress(Arg<Address>.Is.Anything)).Return(null);
            scanner.Stub(s => s.GetImportedProcedure(Arg<Address>.Is.Anything, Arg<Address>.Is.NotNull)).Return(null);
            scanner.Expect(s => s.ScanProcedure(
                Arg<Address>.Is.Anything, 
                Arg<string>.Is.Anything,
                Arg<ProcessorState>.Is.Anything))
                .Return(terminator);
            scanner.Expect(s => s.TerminateBlock(Arg<Block>.Is.NotNull, Arg<Address>.Is.NotNull));
            arch.Stub(a => a.FramePointerType).Return(PrimitiveType.Pointer32);
            scanner.Stub(s => s.GetTrace(null, null, null)).IgnoreArguments().Return(trace);
            mr.ReplayAll();

            trace.Add(m => m.Call(Address.Ptr32(0x0001000), 4));
            trace.Add(m => m.SideEffect(new ProcedureConstant(VoidType.Instance, new PseudoProcedure("shouldnt_decompile_this", VoidType.Instance, 0)))); 

            var wi = CreateWorkItem(Address.Ptr32(0x2000), new FakeProcessorState(arch));
            wi.ProcessInternal();

            Assert.AreEqual(1, block.Statements.Count, "Should only have rewritten the Call to 'terminator'");
            mr.VerifyAll();
        }
Example #31
0
 private void BuildTest(IntelArchitecture arch, Address addr, IPlatform platform, Action<X86Assembler> m)
 {
     proc = new Procedure("test", arch.CreateFrame());
     block = proc.AddBlock("testblock");
     this.state = arch.CreateProcessorState();
     var asm = new X86Assembler(sc, new DefaultPlatform(sc, arch), addr, new List<ImageSymbol>());
     scanner = mr.StrictMock<IScanner>();
     scanner.Stub(s => s.Services).Return(sc);
     m(asm);
     lr = asm.GetImage();
     host = new RewriterHost(
         asm.ImportReferences,
         new Dictionary<string, FunctionType>
         {
             {
                 "GetDC",
                 new FunctionType(
                     new Identifier("", new Pointer(VoidType.Instance, 4), new RegisterStorage("eax", 0, 0, PrimitiveType.Word32)),
                     new [] {
                         new Identifier("arg",
                             new TypeReference(
                                 "HWND",
                                 new Pointer(VoidType.Instance, 4)),
                             new StackArgumentStorage(4, new TypeReference(
                                 "HWND",
                                 new Pointer(VoidType.Instance, 4))))
                     })
                 {
                     StackDelta = 4,
                 }
             }
        },
        new Dictionary<string, DataType>());
     var rw = arch.CreateRewriter(
         lr.SegmentMap.Segments.Values.First().MemoryArea.CreateLeReader(addr), 
         this.state, 
         proc.Frame,
         host);
     this.program = new Program
     {
         Architecture = arch,
         SegmentMap = lr.SegmentMap,
         ImageMap = lr.ImageMap,
         Platform = platform,
     };
     using (mr.Record())
     {
         scanner.Stub(x => x.FindContainingBlock(Arg<Address>.Is.Anything)).Return(block);
         scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(rw);
         scanner.Stub(x => x.Services).Return(sc);
     }
     wi = new BlockWorkitem(scanner, program, state, addr);
 }