Exemplo n.º 1
0
        List <Proc> AnalyseProc(Proc p, List <Proc> procList)
        {
            Instruction i          = p.firstInstruction;
            List <int>  dependants = new List <int>();

            while (true)
            {
                // Update the length of this proc
                p.lengthInBytes = i.addr - p.firstInstruction.addr + i.bytes;

                // If this is a return instruction, mark the proc as having at least one return
                if ((i.opCode.flags & OpCodeFlags.Returns) != 0)
                {
                    p.hasLocalReturn = true;
                }

                // Have we reached the start of another procedure?
                if (i.proc != null && i.proc != p)
                {
                    // Yes! procedure falls through into another, treat as a tail call into that proc
                    if (!dependants.Contains(i.addr))
                    {
                        dependants.Add(i.addr);
                    }
                    break;
                }

                // Remove any dependants that are within this proc (generated by local forward jumps)
                dependants.RemoveAll(x => x >= p.firstInstruction.addr && x < i.addr);

                // Does this instruction transfer control to somewhere else?
                if (i.next_addr_2.HasValue)
                {
                    // if transfers to before start of this proc, or after the current location
                    // then mark it as a dependant location
                    if (i.next_addr_2.Value < p.firstInstruction.addr ||
                        i.next_addr_2.Value > i.addr)
                    {
                        if (!dependants.Contains(i.next_addr_2.Value))
                        {
                            dependants.Add(i.next_addr_2.Value);
                        }
                    }
                }

                // Does this instruction continue?
                if (!i.next_addr_1.HasValue)
                {
                    // No, see if the next dependant address can be reached without hitting another proc
                    Instruction instContinue      = null;
                    List <int>  forwardDependants = dependants.Where(x => x > i.addr).ToList();
                    if (forwardDependants.Count > 0)
                    {
                        int nextDependantAddress = forwardDependants.Min();
                        for (int j = i.addr + 1; j <= nextDependantAddress; j++)
                        {
                            // Get the instruction at that address, ignore if none
                            Instruction i2 = null;
                            if (!_instructions.TryGetValue(j, out i2))
                            {
                                continue;
                            }

                            // Skip data instructions
                            if (i2.opCode == null)
                            {
                                continue;
                            }

                            // Quit if we hit another proc
                            if (i2.proc != null)
                            {
                                break;
                            }

                            // Have we reached the next dependant location?
                            if (i2.addr == nextDependantAddress)
                            {
                                // Yes, continue from here
                                instContinue = i2;
                            }
                        }
                    }

                    if (instContinue != null)
                    {
                        i = instContinue;
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }

                // Get the next instruction
                if (!_instructions.TryGetValue(i.next_addr_1.Value, out i))
                {
                    // ie: fall through to external location!
                    break;
                }
            }

            // Store the dependants with the proc
            p.dependants = dependants;

            // Create new procs for any dependants
            foreach (var addr in dependants.Where(x => !_procs.ContainsKey(x)))
            {
                // Get the dependant instruction, ignore if external
                Instruction dependantInstruction;
                if (!_instructions.TryGetValue(addr, out dependantInstruction))
                {
                    continue;
                }

                // Ignore if already a proc there
                if (dependantInstruction.proc != null)
                {
                    continue;
                }

                // Create new proc
                var newProc = new Proc(dependantInstruction);

                // Add to the list of procs still to be analyzed
                _procs.Add(addr, newProc);
                procList.Add(newProc);
            }

            return(null);
        }
Exemplo n.º 2
0
        List<Proc> AnalyseProc(Proc p, List<Proc> procList)
        {
            Instruction i = p.firstInstruction;
            List<int> dependants= new List<int>();
            while (true)
            {
                // Update the length of this proc
                p.lengthInBytes = i.addr - p.firstInstruction.addr + i.bytes;

                // If this is a return instruction, mark the proc as having at least one return
                if ((i.opCode.flags & OpCodeFlags.Returns)!=0)
                {
                    p.hasLocalReturn = true;
                }

                // Have we reached the start of another procedure?
                if (i.proc != null && i.proc != p)
                {
                    // Yes! procedure falls through into another, treat as a tail call into that proc
                    if (!dependants.Contains(i.addr))
                        dependants.Add(i.addr);
                    break;
                }

                // Remove any dependants that are within this proc (generated by local forward jumps)
                dependants.RemoveAll(x => x >= p.firstInstruction.addr && x < i.addr);

                // Does this instruction transfer control to somewhere else?
                if (i.next_addr_2.HasValue)
                {
                    // if transfers to before start of this proc, or after the current location
                    // then mark it as a dependant location
                    if (i.next_addr_2.Value < p.firstInstruction.addr ||
                                i.next_addr_2.Value > i.addr)
                    {
                        if (!dependants.Contains(i.next_addr_2.Value))
                            dependants.Add(i.next_addr_2.Value);
                    }
                }

                // Does this instruction continue?
                if (!i.next_addr_1.HasValue)
                {
                    // No, see if the next dependant address can be reached without hitting another proc
                    Instruction instContinue = null;
                    List<int> forwardDependants = dependants.Where(x => x > i.addr).ToList();
                    if (forwardDependants.Count>0)
                    {
                        int nextDependantAddress = forwardDependants.Min();
                        for (int j = i.addr+1; j <= nextDependantAddress; j++)
                        {
                            // Get the instruction at that address, ignore if none
                            Instruction i2 = null;
                            if (!_instructions.TryGetValue(j, out i2))
                                continue;

                            // Skip data instructions
                            if (i2.opCode == null)
                                continue;

                            // Quit if we hit another proc
                            if (i2.proc != null)
                                break;

                            // Have we reached the next dependant location?
                            if (i2.addr == nextDependantAddress)
                            {
                                // Yes, continue from here
                                instContinue = i2;
                            }
                        }
                    }

                    if (instContinue != null)
                    {
                        i = instContinue;
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }

                // Get the next instruction
                if (!_instructions.TryGetValue(i.next_addr_1.Value, out i))
                {
                    // ie: fall through to external location!
                    break;
                }
            }

            // Store the dependants with the proc
            p.dependants = dependants;

            // Create new procs for any dependants
            foreach (var addr in dependants.Where(x=>!_procs.ContainsKey(x)))
            {
                // Get the dependant instruction, ignore if external
                Instruction dependantInstruction;
                if (!_instructions.TryGetValue(addr, out dependantInstruction))
                    continue;

                // Ignore if already a proc there
                if (dependantInstruction.proc!=null)
                    continue;

                // Create new proc
                var newProc = new Proc(dependantInstruction);

                // Add to the list of procs still to be analyzed
                _procs.Add(addr, newProc);
                procList.Add(newProc);
            }

            return null;
        }