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)); }
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); }
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); } }
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; }
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; }
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; }
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]); }
/// <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; }
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]); }
public void Analyze(Block b) { curBlock = b; foreach (var stm in b.Statements) { if (flow[b].TerminatesProcess) return; stm.Instruction.Accept(this); } }
public int IndexOfInsertedCopy(Block b) { int i = b.Statements.Count; if (i > 0) { if (b.Statements[i-1].Instruction.IsControlFlow) --i; } return i; }
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()); }
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(); }
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; }
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(); } }
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(); }
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(); } }
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); }
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); }
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(); }
/// <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; }
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); } } }
public BlockFlow this[Block block] { get { return (BlockFlow) blockFlow[block]; } set { blockFlow[block] = value; } }
public Block GetSinglePredecessor(Block block) { return block.Procedure.ControlGraph.Predecessors(block).ToArray()[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)); }
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()); }
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); }
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); } }