예제 #1
0
 private BlockFlow CreateBlockFlow(Block block, Frame frame)
 {
     return new BlockFlow(
         block,
         prog.Architecture.CreateRegisterBitset(),
         new SymbolicEvaluationContext(prog.Architecture, frame));
 }
 private BlockFlow CreateBlockFlow(Block block, Frame frame)
 {
     return new BlockFlow(
         block,
         new HashSet<RegisterStorage>(),
         new SymbolicEvaluationContext(program.Architecture, frame));
 }
예제 #3
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);
 }
예제 #4
0
 public void FixInboundEdges(Block blockToPromote)
 {
     // Get all blocks that are from "outside" blocks.
     var inboundBlocks = blockToPromote.Pred.Where(p => p.Procedure != ProcNew).ToArray();
     foreach (var inb in inboundBlocks)
     {
         if (inb.Statements.Count > 0)
         {
             var lastAddress = GetAddressOfLastInstruction(inb);
             var callRetThunkBlock = Scanner.CreateCallRetThunk(lastAddress, inb.Procedure, ProcNew);
             ReplaceSuccessorsWith(inb, blockToPromote, callRetThunkBlock);
             callRetThunkBlock.Pred.Add(inb);
         }
         else
         {
             inb.Statements.Add(0, new CallInstruction(
                             new ProcedureConstant(Program.Platform.PointerType, ProcNew),
                             new CallSite(ProcNew.Signature.ReturnAddressOnStack, 0)));
             Program.CallGraph.AddEdge(inb.Statements.Last, ProcNew);
             inb.Statements.Add(0, new ReturnInstruction());
             inb.Procedure.ControlGraph.AddEdge(inb, inb.Procedure.ExitBlock);
         }
     }
     foreach (var p in inboundBlocks)
     {
         blockToPromote.Pred.Remove(p);
     }
 }
예제 #5
0
		private bool EndsInBranch(Block block)
		{
			if (block.Succ.Count != 2)
				return false;
			if (block.Statements.Count < 1)
				return false;
			return block.Statements.Last.Instruction is Branch;
		}
예제 #6
0
		public Identifier InsertAssignmentNewId(Identifier idOld, Block b, int i)
		{
			Statement stm = new Statement(0, null, b);
            SsaIdentifier sidNew = ssaIds.Add((Identifier)ssaIds[idOld].OriginalIdentifier, stm, idOld, false);
			stm.Instruction = new Assignment(sidNew.Identifier, idOld);
			b.Statements.Insert(i, stm);
			return sidNew.Identifier;
		}
예제 #7
0
파일: BlockFlow.cs 프로젝트: smx-smx/reko
        public bool TerminatesProcess;                  // True if entering this block means the process/thread will be terminated.

        public BlockFlow(Block block, HashSet <RegisterStorage> dataOut, SymbolicEvaluationContext ctx)
        {
            this.Block         = block;
            this.DataOut       = dataOut;
            this.StackVarsOut  = new Dictionary <Storage, int>();
            this.FallbackStack = new Dictionary <Statement, Expression>();
            this.SymbolicIn    = ctx;
        }
예제 #8
0
		private void ReplaceJumpWithBranch(Block b1, Block b2)
		{
			Branch br = b2.Statements.Last.Instruction as Branch;
            proc.ControlGraph.RemoveEdge(b1, b2);
			b1.Statements.Add(b2.Statements.Last.LinearAddress, new Branch(br.Condition, b2.Succ[1]));
            proc.ControlGraph.AddEdge(b1, b2.Succ[0]);
            proc.ControlGraph.AddEdge(b1, b2.Succ[1]);
		}
예제 #9
0
		/// <summary>
		/// Creates a phi statement with slots for each predecessor block, then
		/// inserts the phi statement as the first statement of the block.
		/// </summary>
		/// <param name="b">Block into which the phi statement is inserted</param>
		/// <param name="v">Destination variable for the phi assignment</param>
		/// <returns>The inserted phi Assignment</returns>
		private Instruction InsertPhiStatement(Block b, Identifier v)
		{
			var stm = new Statement(
                0,
				new PhiAssignment(v, b.Pred.Count),
				b);
			b.Statements.Insert(0, stm);
			return stm.Instruction;
		}
예제 #10
0
		public bool IsLiveAtCopyPoint(Identifier id, Block b)
		{
			if (b.Statements.Count == 0)
				return sla.IsLiveOut(id, b);
			int i = IndexOfInsertedCopy(b);
			if (i >= b.Statements.Count)
				return sla.IsLiveOut(id, b.Statements[i-1]);
			else
				return sla.IsLiveIn(id, b.Statements[i]);
		}
예제 #11
0
 public void Analyze(Block b)
 {
     curBlock = b;
     foreach (var stm in b.Statements)
     {
         if (flow[b].TerminatesProcess)
             return;
         stm.Instruction.Accept(this);
     }
 }
예제 #12
0
		public int IndexOfInsertedCopy(Block b)
		{
			int i = b.Statements.Count;
			if (i > 0)
			{
				if (b.Statements[i-1].Instruction.IsControlFlow)
					--i;
			}
			return i;
		}
예제 #13
0
 private BlockFlow CreateBlockFlow(Block block, Frame frame)
 {
     var bflow = new BlockFlow(
         block,
         prog.Architecture.CreateRegisterBitset(),
         new SymbolicEvaluationContext(
             prog.Architecture,
             frame));
     flow[block] = bflow;
     return bflow;
 }
		public void EarInsertFrameReference()
		{
			Procedure proc = new Procedure("foo", new Frame(PrimitiveType.Word32));
			Block b = new Block(proc, "foo_1");
			proc.ControlGraph.AddEdge(proc.EntryBlock, b);
            proc.ControlGraph.AddEdge(b, proc.ExitBlock);
			EscapedAccessRewriter ear = new EscapedAccessRewriter(proc);
			ear.InsertFramePointerAssignment(new Mocks.FakeArchitecture());
			Block x = proc.EntryBlock.Succ[0];
			Assert.AreEqual(1, x.Statements.Count);
			Assert.AreEqual("fp = &foo_frame", x.Statements[0].Instruction.ToString());
		}
예제 #15
0
파일: Block.cs 프로젝트: gitter-badger/reko
		public static void Coalesce(Block block, Block next)
		{
			foreach (Statement stm in next.Statements)
			{
				block.Statements.Add(stm);
			}

			block.Succ = new List<Block>(next.Succ);
			ReplaceJumpsFrom(next, block);
			next.Pred.Clear();
			next.Statements.Clear();
			next.Succ.Clear();
		}
예제 #16
0
파일: Block.cs 프로젝트: gitter-badger/reko
		public static bool ReplaceJumpsFrom(Block block, Block next)
		{
			bool change = false;
			foreach (Block s in block.Succ)
			{
				for (int i = 0; i < s.Pred.Count; ++i)
				{
					if (s.Pred[i] == block)
					{
						s.Pred[i] = next;
						change = true;
					}
				}
			}
			return change;
		}
예제 #17
0
 public void FixOutboundEdges(Block block)
 {
     for (int i = 0; i < block.Succ.Count; ++i)
     {
         var s = block.Succ[i];
         if (s.Procedure == block.Procedure)
             continue;
         if (s.Procedure.EntryBlock.Succ[0] == s)
         {
             var lastAddress = GetAddressOfLastInstruction(block);
             var retCallThunkBlock = Scanner.CreateCallRetThunk(lastAddress, block.Procedure, s.Procedure);
             block.Succ[i] = retCallThunkBlock;
         }
         s.ToString();
     }
 }
예제 #18
0
        public void NavigateToBlock()
        {
            var proc = new Procedure("foo", null);
            var block = new Block(proc, "foo_block");

            var codeSvc = mr.DynamicMock<ICodeViewerService>();
            codeSvc.Expect(x => x.DisplayProcedure(
                Arg<Program>.Is.Same(program),
                Arg<Procedure>.Is.Same(proc)));
            mr.ReplayAll();

            var sc = new ServiceContainer();
            sc.AddService<ICodeViewerService>(codeSvc);
            var nav = new BlockNavigator(program, block, sc);
            nav.NavigateTo();
            mr.VerifyAll();
        }
예제 #19
0
파일: BlockTests.cs 프로젝트: nemerle/reko
        public void CreateStatements()
        {
            using (FileUnitTester fut = new FileUnitTester("Core/BlockCreateStatements.txt"))
            {
                Block bl = new Block(null, "block0");
                bl.Statements.Add(0,
                    new Assignment(
                    new Identifier("id3", PrimitiveType.Word16, null),
                    new Identifier("id4", PrimitiveType.Word16, null)));
                bl.Statements.Add(4,
                    new Assignment(
                    new Identifier("id4", PrimitiveType.Word16, null),
                    Constant.Word16(3)));

                bl.Write(fut.TextWriter);
                fut.AssertFilesEqual();
            }
        }
예제 #20
0
        public void Bwi_Branch_DelaySlot()
        {
            var l00100008 = new Block(proc, "l00100008");
            var l00100100 = new Block(proc, "l00101000");
            scanner.Stub(f => f.FindContainingBlock(Address.Ptr32(0x100000))).Return(block);
            scanner.Stub(f => f.FindContainingBlock(Address.Ptr32(0x100004))).Return(block);
            scanner.Stub(f => f.FindContainingBlock(Address.Ptr32(0x100008))).Return(l00100008);
            scanner.Stub(f => f.FindContainingBlock(Address.Ptr32(0x10000C))).Return(null);
            scanner.Stub(s => s.GetTrace(null, null, null)).IgnoreArguments().Return(trace);
            scanner.Stub(s => s.EnqueueJumpTarget(
                Arg<Address>.Is.Equal(Address.Ptr32(0x00100004)),
                Arg<Address>.Is.Equal(Address.Ptr32(0x00101000)),
                Arg<Procedure>.Is.Equal(proc),
                Arg<ProcessorState>.Is.NotNull)).Return(l00100100);
            scanner.Stub(s => s.EnqueueJumpTarget(
                Arg<Address>.Is.Equal(Address.Ptr32(0x00100004)),
                Arg<Address>.Is.Equal(Address.Ptr32(0x00100008)),
                Arg<Procedure>.Is.Equal(proc),
                Arg<ProcessorState>.Is.NotNull)).Return(l00100008);
            mr.ReplayAll();

            trace.Add(m => m.Branch(r1, Address.Ptr32(0x101000), RtlClass.ConditionalTransfer | RtlClass.Delay));
            trace.Add(m => m.Assign(r0, r1));   // 100004
            trace.Add(m => m.Assign(r2, r1));   // 100008

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

            Assert.AreEqual("branch r1 l00100000_ds_t",  block.Statements[0].ToString());
            var blFalse = block.ElseBlock;
            var blTrue = block.ThenBlock;
            proc.Dump(true);
            Assert.AreEqual("l00100000_ds_f", blFalse.Name);     // delay-slot-false
            Assert.AreEqual(1, blFalse.Statements.Count);
            Assert.AreEqual("r0 = r1", blFalse.Statements[0].ToString());
            Assert.AreEqual(1, blFalse.Succ.Count);
            Assert.AreEqual("l00100008", blFalse.Succ[0].Name);

            Assert.AreEqual("l00100000_ds_t", blTrue.Name);      // delay-slot-true
            Assert.AreEqual(1, blTrue.Statements.Count);
            Assert.AreEqual("r0 = r1", blTrue.Statements[0].ToString());
            Assert.AreEqual(1, blTrue.Succ.Count);
            Assert.AreEqual("l00101000", blTrue.Succ[0].Name);
        }
		private void BuildCompoundCondition(
			Block blockFirst,
			Block blockSecond,
			BinaryOperator op, 
			bool fInvertFirst, 
			bool fInvertSecond)
		{
			Branch brFirst = (Branch) blockFirst.Statements.Last.Instruction;
			Branch brSecond = (Branch) blockSecond.Statements.Last.Instruction;
			if (fInvertFirst)
			{
				brFirst.Condition = brFirst.Condition.Invert();
			}
			if (fInvertSecond)
			{
				brSecond.Condition = brSecond.Condition.Invert();
			}
			brFirst.Condition = new BinaryExpression(op, PrimitiveType.Bool, brFirst.Condition, brSecond.Condition);
		}
예제 #22
0
		private void BuildCompoundCondition(
			Block blockFirst,
			Block blockSecond,
			Func<Expression,Expression,Expression> op, 
			bool fInvertFirst, 
			bool fInvertSecond)
		{
			Branch brFirst = (Branch) blockFirst.Statements.Last.Instruction;
			Branch brSecond = (Branch) blockSecond.Statements.Last.Instruction;
			if (fInvertFirst)
			{
				brFirst.Condition = brFirst.Condition.Invert();
			}
			if (fInvertSecond)
			{
				brSecond.Condition = brSecond.Condition.Invert();
			}
			brFirst.Condition = op(brFirst.Condition, brSecond.Condition);
		}
예제 #23
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();
        }
예제 #24
0
        /// <summary>
        /// Walks backward along the <paramref name="block"/>, recording the operations done to the idx register.
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public List<BackwalkOperation> BackWalk(Block block)
        {
            if (Stride > 1)
                Operations.Add(new BackwalkOperation(BackwalkOperator.mul, Stride));

            bool continueBackwalking = BackwalkInstructions(Index, block);
            if ((Index == null || Index == RegisterStorage.None) && IndexExpression == null)
                return null;	// unable to find guard.

            if (continueBackwalking)
            {
                block = host.GetSinglePredecessor(block);
                if (block == null)
                    return null;	// seems unguarded to me.

                BackwalkInstructions(Index, block);
                if (Index == null && IndexExpression == null)
                    return null;
            }
            Operations.Reverse();
            return Operations;
        }
예제 #25
0
 public void Traverse(Block block)
 {
     var q = new Queue<Block>();
     q.Enqueue(block);
     while (q.Count > 0)
     {
         var b = q.Dequeue();
         if (visited.Contains(b))
             continue;
         visited.Add(b);
         Debug.Print("Node {0}", b.Name);
         visited.Add(b);
         CreateGraphNode(b);
         foreach (var pred in b.Pred.Where(p => p != block.Procedure.EntryBlock))
         {
             Debug.Print("Edge {0} - {1}", pred.Name, b.Name);
             graph.AddEdge(pred.Name, b.Name);
         }
         foreach (var succ in b.Succ)
         {
             q.Enqueue(succ);
         }
     }
 }
예제 #26
0
		public BlockFlow this[Block block]
		{
			get { return (BlockFlow) blockFlow[block]; }
            set { blockFlow[block] = value; }
		}
예제 #27
0
 public Block GetSinglePredecessor(Block block)
 {
     return block.Procedure.ControlGraph.Predecessors(block).ToArray()[0];
 }
예제 #28
0
 public void Scanner_IsLinearReturning_EmptyBlock()
 {
     var scanner = CreateScanner(0x1000, 0x1000);
     var proc = new Procedure("fn1000", arch.CreateFrame());
     var block = new Block(proc, "l1000");
     Assert.IsFalse(scanner.IsLinearReturning(block));
 }
예제 #29
0
        public void TrfPropagateStackValuesToSuccessor()
        {
            m.Label("Start");
            Identifier ecx = m.Register(1);
            trf = CreateTrashedRegisterFinder(program);
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            trf.StackSymbolicValues[-4] = ecx;
            trf.StackSymbolicValues[-8] = ecx;
            trf.StackSymbolicValues[-12] = ecx;
            trf.StackSymbolicValues[-16] = m.Word32(0x1234);
            trf.StackSymbolicValues[-20] = m.Word32(0x5678);
            trf.StackSymbolicValues[-24] = m.Word32(0x9ABC);

            var succ = new Block(m.Procedure, "succ");
            var sf = CreateBlockFlow(succ, m.Frame);
            flow[succ] = sf;
            sf.SymbolicIn.StackState[-8] = ecx;
            sf.SymbolicIn.StackState[-12] = Constant.Word32(1231);
            sf.SymbolicIn.StackState[-20] = Constant.Word32(0x5678);
            sf.SymbolicIn.StackState[-24] = Constant.Word32(0xCCCC);

            trf.PropagateToSuccessorBlock(succ);

            Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-4].ToString(), "Didn't have a value before");
            Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-8].ToString(), "Same value as before");
            Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-12].ToString());
            Assert.AreEqual("0x00001234", sf.SymbolicIn.StackState[-16].ToString());
            Assert.AreEqual("0x00005678", sf.SymbolicIn.StackState[-20].ToString());
            Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-24].ToString());
        }
예제 #30
0
		public void LiveOutAtStatement(Block block, int iStm, SsaIdentifier sid)
		{
            Dictionary<SsaIdentifier, SsaIdentifier> W = iStm >= 0 
				? VariablesDefinedByStatement(block.Statements[iStm])
				: new Dictionary<SsaIdentifier,SsaIdentifier>();

			foreach (SsaIdentifier w in W.Values)
			{
				if (w != sid)
					interference.Add(w.Identifier, sid.Identifier);

			}
			if (!W.ContainsKey(sid))
				LiveInAtStatement(block, iStm, sid);
		}
예제 #31
0
		private void LiveInAtStatement(Block block, int iStm, SsaIdentifier sid)
		{
			if (iStm <= 0)
			{
				foreach (Block p in block.Pred)
				{
					LiveOutAtBlock(p, sid);
				}
			}
			else
			{
				LiveOutAtStatement(block, --iStm, sid);
			}
		}