Exemplo n.º 1
0
 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);
         }
     }
 }
Exemplo n.º 2
0
 private void AddNode(HeuristicBlock block)
 {
     if (!proc.Cfg.Nodes.Contains(block))
     {
         proc.Cfg.Nodes.Add(block);
     }
 }
Exemplo n.º 3
0
        public ISet <HeuristicBlock> GetAncestors(HeuristicBlock n)
        {
            var anc = new HashSet <HeuristicBlock>();

            foreach (var p in blocks.Predecessors(n))
            {
                GetAncestorsAux(p, n, anc);
            }
            return(anc);
        }
Exemplo n.º 4
0
 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);
 }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
 private void AddNode(HeuristicBlock block)
 {
     if (!proc.Cfg.Nodes.Contains(block))
         proc.Cfg.Nodes.Add(block);
 }
Exemplo n.º 7
0
 private void AddEdge(HeuristicBlock from, HeuristicBlock to)
 {
     proc.Cfg.AddEdge(from, to);
 }
Exemplo n.º 8
0
 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;
 }
Exemplo n.º 9
0
 private void RemoveBlockFromGraph(HeuristicBlock n)
 {
     Debug.Print("Removing block: {0}", n.Address);
     blocks.Nodes.Remove(n);
 }
Exemplo n.º 10
0
        /// <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);
        }
Exemplo n.º 11
0
        /// <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);
        }
Exemplo n.º 12
0
 private void RemoveEdge(HeuristicBlock from, HeuristicBlock to)
 {
     proc.Cfg.RemoveEdge(from, to);
 }
Exemplo n.º 13
0
 private void AddEdge(HeuristicBlock from, HeuristicBlock to)
 {
     proc.Cfg.AddEdge(from, to);
 }
Exemplo n.º 14
0
        /// <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);
        }
Exemplo n.º 15
0
 private void RemoveEdge(HeuristicBlock from, HeuristicBlock to)
 {
     proc.Cfg.RemoveEdge(from, to);
 }
Exemplo n.º 16
0
 /// <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;
 }
Exemplo n.º 17
0
 /// <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;
 }
Exemplo n.º 18
0
 /// <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;
 }