private IEnumerable <Address> GetValidSequences(Tuple <Address, Address> gap) { for (Address addr = gap.Item1; addr < gap.Item2; addr = addr + program.Architecture.InstructionBitSize / 8) { var block = new HeuristicBlock(addr, string.Format("l{0:X}" + addr)); var dasm = CreateRewriter(addr); bool isValid = false; foreach (var instr in dasm) { if (instr.Address + instr.Length > gap.Item2) { break; } var lastInstr = instr.Instructions.Last(); if (NonLocalTransferInstruction()) { isValid = true; break; } } if (isValid) { yield return(addr); } } }
private void AddNode(HeuristicBlock block) { if (!proc.Cfg.Nodes.Contains(block)) { proc.Cfg.Nodes.Add(block); } }
public ISet <HeuristicBlock> GetAncestors(HeuristicBlock n) { var anc = new HashSet <HeuristicBlock>(); foreach (var p in blocks.Predecessors(n)) { GetAncestorsAux(p, n, anc); } return(anc); }
private ISet <HeuristicBlock> GetAncestorsAux( HeuristicBlock n, HeuristicBlock orig, ISet <HeuristicBlock> ancestors) { if (ancestors.Contains(n) || n == orig) { return(ancestors); } ancestors.Add(n); foreach (var p in blocks.Predecessors(n)) { GetAncestorsAux(p, orig, ancestors); } return(ancestors); }
private HeuristicBlock SplitBlock(HeuristicBlock block, Address addr) { var newBlock = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); proc.Cfg.Nodes.Add(newBlock); newBlock.Instructions.AddRange( block.Instructions.Where(r => r.Address >= addr).OrderBy(r => r.Address)); foreach (var de in blockMap.Where(d => d.Key >= addr && d.Value == block).ToList()) { blockMap[de.Key] = newBlock; } block.Instructions.RemoveAll(r => r.Address >= addr); var succs = proc.Cfg.Successors(block).ToArray(); foreach (var s in succs) { AddEdge(newBlock, s); RemoveEdge(block, s); } AddEdge(block, newBlock); return(newBlock); }
private void AddNode(HeuristicBlock block) { if (!proc.Cfg.Nodes.Contains(block)) proc.Cfg.Nodes.Add(block); }
private void AddEdge(HeuristicBlock from, HeuristicBlock to) { proc.Cfg.AddEdge(from, to); }
private HeuristicBlock SplitBlock(HeuristicBlock block, Address addr) { var newBlock = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); proc.Cfg.Nodes.Add(newBlock); newBlock.Instructions.AddRange( block.Instructions.Where(r => r.Address >= addr).OrderBy(r => r.Address)); foreach (var de in blockMap.Where(d => d.Key >= addr && d.Value == block).ToList()) { blockMap[de.Key] = newBlock; } block.Instructions.RemoveAll(r => r.Address >= addr); var succs = proc.Cfg.Successors(block).ToArray(); foreach (var s in succs) { AddEdge(newBlock, s); RemoveEdge(block, s); } AddEdge(block, newBlock); return newBlock; }
private void RemoveBlockFromGraph(HeuristicBlock n) { Debug.Print("Removing block: {0}", n.Address); blocks.Nodes.Remove(n); }
/// <summary> /// Recursively disassembles the range of addresses specified by the guessed procedure. /// <paramref name="proc"/>. /// </summary> /// <param name="addr"></param> /// <param name="proc"></param> /// <returns></returns> public HeuristicBlock HeuristicDisassemble(Address addr, HeuristicProcedure proc) { var current = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); var rAddr = prog.Architecture.CreateRewriter( prog.CreateImageReader(addr), prog.Architecture.CreateProcessorState(), proc.Frame, host); foreach (var rtl in rAddr.TakeWhile(r => r.Address < proc.EndAddress)) { HeuristicBlock block; if (blockMap.TryGetValue(rtl.Address, out block)) { // This instruction was already disassembled before. if (rtl.Address.ToLinear() != block.Address.ToLinear()) { block = SplitBlock(block, rtl.Address, proc); } if (current.Statements.Count == 0) { // Coincides exactly, return the old block. return(block); } else { // Fell into 'block' while disassembling // 'current'. Create a fall-though edge if (!proc.Cfg.Nodes.Contains(current)) { proc.Cfg.Nodes.Add(current); } proc.Cfg.AddEdge(current, block); return(current); } } else { // Fresh instruction if (!proc.Cfg.Nodes.Contains(current)) { proc.Cfg.Nodes.Add(current); } current.Statements.Add(rtl); blockMap.Add(rtl.Address, current); var rtlLast = rtl.Instructions.Last(); if (rtlLast is RtlCall || rtlLast is RtlReturn) { // Since calls cannot be dependent on to return, // we stop disassembling. return(current); } var rtlJump = rtlLast as RtlGoto; if (rtlJump != null) { var target = rtlJump.Target as Address; if (target == null || target < proc.BeginAddress || target >= proc.EndAddress) { // Stop disassembling if you get outside // the procedure or a computed goto. return(current); } block = HeuristicDisassemble(target, proc); proc.Cfg.AddEdge(current, block); return(current); } var rtlBranch = rtlLast as RtlBranch; if (rtlBranch != null) { block = HeuristicDisassemble(rtlBranch.Target, proc); proc.Cfg.AddEdge(current, block); block = HeuristicDisassemble(rtl.Address + rtl.Length, proc); proc.Cfg.AddEdge(current, block); return(current); } } } return(current); }
/// <summary> /// Recursively disassembles the range of addresses. /// <paramref name="proc"/>. /// </summary> /// <param name="addr"></param> /// <param name="proc"></param> /// <returns></returns> public HeuristicBlock Disassemble(Address addr) { var current = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); var dasm = program.CreateDisassembler(addr); foreach (var instr in dasm.TakeWhile(r => r.Address < proc.EndAddress)) { HeuristicBlock block; if (blockMap.TryGetValue(instr.Address, out block)) { // This instruction was already disassembled before. if (instr.Address.ToLinear() != block.Address.ToLinear()) { block = SplitBlock(block, instr.Address); } if (current.Instructions.Count == 0) { // Coincides exactly, return the old block. return(block); } else { // Fell into 'block' while disassembling // 'current'. Create a fall-though edge if (!proc.Cfg.Nodes.Contains(current)) { AddNode(current); } AddEdge(current, block); return(current); } } else { // Fresh instruction AddNode(current); current.Instructions.Add(instr); blockMap.Add(instr.Address, current); var op0 = instr.GetOperand(0); var addrOp = op0 as AddressOperand; switch (instr.InstructionClass) { case InstructionClass.Invalid: current.IsValid = false; return(current); case InstructionClass.Transfer | InstructionClass.Call: return(current); case InstructionClass.Transfer: if (addrOp != null && proc.BeginAddress <= addrOp.Address && addrOp.Address < proc.EndAddress) { block = Disassemble(addrOp.Address); AddEdge(current, block); return(current); } return(current); case InstructionClass.Transfer | InstructionClass.Conditional: if (addrOp != null && program.ImageMap.IsValidAddress(addrOp.Address)) { block = Disassemble(addrOp.Address); Debug.Assert(proc.Cfg.Nodes.Contains(block)); AddEdge(current, block); } block = Disassemble(instr.Address + instr.Length); AddEdge(current, block); return(current); } } } AddNode(current); return(current); }
private void RemoveEdge(HeuristicBlock from, HeuristicBlock to) { proc.Cfg.RemoveEdge(from, to); }
private void AddEdge(HeuristicBlock from, HeuristicBlock to) { proc.Cfg.AddEdge(from, to); }
/// <summary> /// Recursively disassembles the range of addresses. /// <paramref name="proc"/>. /// </summary> /// <param name="addr"></param> /// <param name="proc"></param> /// <returns></returns> public HeuristicBlock Disassemble(Address addr) { var current = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); var rrAddr = program.Architecture.CreateRewriter( program.CreateImageReader(addr), program.Architecture.CreateProcessorState(), proc.Frame, host); var rAddr = new RobustRewriter(rrAddr, program.Architecture.InstructionBitSize / 8); foreach (var rtl in rAddr.TakeWhile(r => r.Address < proc.EndAddress)) { HeuristicBlock block; if (blockMap.TryGetValue(rtl.Address, out block)) { // This instruction was already disassembled before. if (rtl.Address.ToLinear() != block.Address.ToLinear()) { block = SplitBlock(block, rtl.Address); } if (current.Statements.Count == 0) { // Coincides exactly, return the old block. return(block); } else { // Fell into 'block' while disassembling // 'current'. Create a fall-though edge if (!proc.Cfg.Nodes.Contains(current)) { AddNode(current); } AddEdge(current, block); return(current); } } else { // Fresh instruction AddNode(current); current.Statements.Add(rtl); blockMap.Add(rtl.Address, current); switch (rtl.Class) { case RtlClass.Invalid: current.IsValid = false; return(current); case RtlClass.Transfer: var rtlLast = rtl.Instructions.Last(); if (rtlLast is RtlCall || rtlLast is RtlReturn) { // Since calls cannot be depended on to return, // we stop disassembling. return(current); } var rtlJump = rtl.Instructions.Last() as RtlGoto; if (rtlJump != null) { // Stop disassembling if you get outside // the procedure or a computed goto. var target = rtlJump.Target as Address; if (target == null || target < proc.BeginAddress || target >= proc.EndAddress) { return(current); } block = Disassemble(target); AddEdge(current, block); return(current); } break; case RtlClass.ConditionalTransfer: var rtlBranch = rtl.Instructions.Last() as RtlBranch; if (rtlBranch != null) { block = Disassemble(rtlBranch.Target); Debug.Assert(proc.Cfg.Nodes.Contains(block)); AddEdge(current, block); block = Disassemble(rtl.Address + rtl.Length); AddEdge(current, block); return(current); } break; } } } AddNode(current); return(current); }
private void RemoveEdge(HeuristicBlock from, HeuristicBlock to) { proc.Cfg.RemoveEdge(from, to); }
/// <summary> /// Recursively disassembles the range of addresses. /// <paramref name="proc"/>. /// </summary> /// <param name="addr"></param> /// <param name="proc"></param> /// <returns></returns> public HeuristicBlock Disassemble(Address addr) { var current = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); var rrAddr = program.Architecture.CreateRewriter( program.CreateImageReader(addr), program.Architecture.CreateProcessorState(), proc.Frame, host); var rAddr = new RobustRewriter(rrAddr, program.Architecture.InstructionBitSize / 8); foreach (var rtl in rAddr.TakeWhile(r => r.Address < proc.EndAddress)) { HeuristicBlock block; if (blockMap.TryGetValue(rtl.Address, out block)) { // This instruction was already disassembled before. if (rtl.Address.ToLinear() != block.Address.ToLinear()) { block = SplitBlock(block, rtl.Address); } if (current.Statements.Count == 0) { // Coincides exactly, return the old block. return block; } else { // Fell into 'block' while disassembling // 'current'. Create a fall-though edge if (!proc.Cfg.Nodes.Contains(current)) { AddNode(current); } AddEdge(current, block); return current; } } else { // Fresh instruction AddNode(current); current.Statements.Add(rtl); blockMap.Add(rtl.Address, current); switch (rtl.Class) { case RtlClass.Invalid: current.IsValid = false; return current; case RtlClass.Transfer: var rtlLast = rtl.Instructions.Last(); if (rtlLast is RtlCall || rtlLast is RtlReturn) { // Since calls cannot be depended on to return, // we stop disassembling. return current; } var rtlJump = rtl.Instructions.Last() as RtlGoto; if (rtlJump != null) { // Stop disassembling if you get outside // the procedure or a computed goto. var target = rtlJump.Target as Address; if (target == null || target < proc.BeginAddress || target >= proc.EndAddress) { return current; } block = Disassemble(target); AddEdge(current, block); return current; } break; case RtlClass.ConditionalTransfer: var rtlBranch = rtl.Instructions.Last() as RtlBranch; if (rtlBranch != null) { block = Disassemble(rtlBranch.Target); Debug.Assert(proc.Cfg.Nodes.Contains(block)); AddEdge(current, block); block = Disassemble(rtl.Address + rtl.Length); AddEdge(current, block); return current; } break; } } } AddNode(current); return current; }
/// <summary> /// Recursively disassembles the range of addresses. /// <paramref name="proc"/>. /// </summary> /// <param name="addr"></param> /// <param name="proc"></param> /// <returns></returns> public HeuristicBlock Disassemble(Address addr) { var current = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); var dasm = program.CreateDisassembler(addr); foreach (var instr in dasm.TakeWhile(r => r.Address < proc.EndAddress)) { HeuristicBlock block; if (blockMap.TryGetValue(instr.Address, out block)) { // This instruction was already disassembled before. if (instr.Address.ToLinear() != block.Address.ToLinear()) { block = SplitBlock(block, instr.Address); } if (current.Instructions.Count == 0) { // Coincides exactly, return the old block. return block; } else { // Fell into 'block' while disassembling // 'current'. Create a fall-though edge if (!proc.Cfg.Nodes.Contains(current)) { AddNode(current); } AddEdge(current, block); return current; } } else { // Fresh instruction AddNode(current); current.Instructions.Add(instr); blockMap.Add(instr.Address, current); var op0 = instr.GetOperand(0); var addrOp= op0 as AddressOperand; switch (instr.InstructionClass) { case InstructionClass.Invalid: current.IsValid = false; return current; case InstructionClass.Transfer | InstructionClass.Call: return current; case InstructionClass.Transfer: if (addrOp != null && proc.BeginAddress <= addrOp.Address && addrOp.Address < proc.EndAddress) { block = Disassemble(addrOp.Address); AddEdge(current, block); return current; } return current; case InstructionClass.Transfer | InstructionClass.Conditional: if (addrOp != null && program.SegmentMap.IsValidAddress(addrOp.Address)) { block = Disassemble(addrOp.Address); Debug.Assert(proc.Cfg.Nodes.Contains(block)); AddEdge(current, block); } block = Disassemble(instr.Address + instr.Length); AddEdge(current, block); return current; } } } AddNode(current); return current; }
/// <summary> /// Recursively disassembles the range of addresses specified by the guessed procedure. /// <paramref name="proc"/>. /// </summary> /// <param name="addr"></param> /// <param name="proc"></param> /// <returns></returns> public HeuristicBlock HeuristicDisassemble(Address addr, HeuristicProcedure proc) { var current = new HeuristicBlock(addr, string.Format("l{0:X}", addr)); var rAddr = prog.Architecture.CreateRewriter( prog.CreateImageReader(addr), prog.Architecture.CreateProcessorState(), proc.Frame, host); foreach (var rtl in rAddr.TakeWhile(r => r.Address < proc.EndAddress)) { HeuristicBlock block; if (blockMap.TryGetValue(rtl.Address, out block)) { // This instruction was already disassembled before. if (rtl.Address.ToLinear() != block.Address.ToLinear()) { block = SplitBlock(block, rtl.Address, proc); } if (current.Statements.Count == 0) { // Coincides exactly, return the old block. return block; } else { // Fell into 'block' while disassembling // 'current'. Create a fall-though edge if (!proc.Cfg.Nodes.Contains(current)) { proc.Cfg.Nodes.Add(current); } proc.Cfg.AddEdge(current, block); return current; } } else { // Fresh instruction if (!proc.Cfg.Nodes.Contains(current)) { proc.Cfg.Nodes.Add(current); } current.Statements.Add(rtl); blockMap.Add(rtl.Address, current); var rtlLast = rtl.Instructions.Last(); if (rtlLast is RtlCall || rtlLast is RtlReturn) { // Since calls cannot be dependent on to return, // we stop disassembling. return current; } var rtlJump = rtlLast as RtlGoto; if (rtlJump != null) { var target = rtlJump.Target as Address; if (target == null || target < proc.BeginAddress || target >= proc.EndAddress) { // Stop disassembling if you get outside // the procedure or a computed goto. return current; } block = HeuristicDisassemble(target, proc); proc.Cfg.AddEdge(current, block); return current; } var rtlBranch = rtlLast as RtlBranch; if (rtlBranch != null) { block = HeuristicDisassemble(rtlBranch.Target, proc); proc.Cfg.AddEdge(current, block); block = HeuristicDisassemble(rtl.Address + rtl.Length, proc); proc.Cfg.AddEdge(current, block); return current; } } } return current; }