Beispiel #1
0
        private void DisassembleFunction(object sender, RoutedEventArgs e)
        {
            ListViewFunction item = (ListViewFunction)FunctionsView.SelectedItem;
            Function         f    = item.Details;

            if (f.Size == 0xFFFFFFFF || f.Blocks == null)
            {
                f.FindSize();
                FindDominators(f.Blocks);
            }

            _InstrCollection.Clear();
            foreach (FunctionBlock block in f.Blocks)
            {
                uint offset = state.Pe.Rva2Offset(block.StartAddress - (uint)state.Pe.optHdr.ImageBase);

                for (uint i = 0; i < block.InstrCount; i++)
                {
                    uint instruction = state.Pe.ReadInstruction(offset + i * 4);

                    XenonInstructions.OpCodeInfo info = state.Instructions.GetInfo(instruction);
                    ListViewInstr instr = new ListViewInstr("0x" + (block.StartAddress + i * 4).ToString("X8"), info.Name, "");
                    _InstrCollection.Add(instr);
                }
            }
        }
Beispiel #2
0
        void AddLazyCalls()
        {
            for (int i = 0; i < Blocks.Count - 1; i++)
            {
                uint lastInstructionAddr = Blocks[i].StartAddress + (Blocks[i].InstrCount - 1) * 4;
                uint rva    = lastInstructionAddr - (uint)decompiler.Pe.GetImageBase();
                uint offset = decompiler.Pe.Rva2Offset(rva);

                uint instruction = decompiler.Pe.ReadInstruction(offset);
                XenonInstructions.OpCodeInfo info = decompiler.Instructions.GetInfo(instruction);
                switch (info.Id)
                {
                case XenonInstructions.Mnemonics.PPC_OP_B:
                case XenonInstructions.Mnemonics.PPC_OP_BC:
                case XenonInstructions.Mnemonics.PPC_OP_BCCTR:
                case XenonInstructions.Mnemonics.PPC_OP_BCLR:
                    break;

                default:
                    Blocks[i].Successors.Add(Blocks[i + 1]);
                    Blocks[i + 1].Predecessors.Add(Blocks[i]);
                    break;
                }
            }
        }
Beispiel #3
0
        public uint FindSize()
        {
            /* Functions can't cross each other, so the maximum size is on the next function boundary */
            uint addr = Address - (uint)decompiler.Pe.GetImageBase();
            uint diff;

            int index = decompiler.Functions.IndexOf(this);

            if (index != decompiler.Functions.Count - 1)
            {
                diff = decompiler.Functions[index + 1].Address - Address;
            }
            else
            {
                diff = decompiler.Pe.Rva2SectionEnd(addr) - addr;
            }

            diff = (uint)(diff & (~3));

            /* Check that all instructions are valid, and stop at the first invalid instruction (if any) */
            uint i      = 0;
            uint offset = decompiler.Pe.Rva2Offset(addr);

            for (; i < diff / 4; i++)
            {
                uint instruction = decompiler.Pe.ReadInstruction(offset + i * 4);
                XenonInstructions.OpCodeInfo info = decompiler.Instructions.GetInfo(instruction);
                if (info.Id == XenonInstructions.Mnemonics.PPC_OP_INVALID)
                {
                    break;
                }
            }
            diff = i * 4;

            /* Build a call tree and find the maximum address */
            BuildCallTree(Address, diff);

            FunctionBlock lastBlock = Blocks[Blocks.Count - 1];
            uint          maxAddr   = lastBlock.StartAddress + lastBlock.InstrCount * 4;

            return(maxAddr - Address);
        }
Beispiel #4
0
        private void DecompileEasy(Function f)
        {
            foreach (FunctionBlock block in f.Blocks)
            {
                uint offset = state.Pe.Rva2Offset(block.StartAddress - (uint)state.Pe.optHdr.ImageBase);

                for (uint i = 0; i < block.InstrCount; i++)
                {
                    uint instruction = state.Pe.ReadInstruction(offset + i * 4);
                    XenonInstructions.OpCodeInfo info = state.Instructions.GetInfo(instruction);

                    if (info.CEquivalent != null)
                    {
                        List <CStatement> cEquiv = info.CEquivalent(block.StartAddress + i * 4, instruction);
                        block.Statements.AddRange(cEquiv);
                    }
                    else
                    {
                        MessageBox.Show("Can't translate instruction " + info.Name);
                    }
                }
            }
        }
Beispiel #5
0
        private void LoopPhase2(List <FunctionBlock> blocks, List <Loop> loops)
        {
            /* Take loops in reverse order (inner loops are processed before outer loops */
            loops.Sort(LoopSortDesc);

            foreach (Loop loop in loops)
            {
                FunctionBlock lastBlock = loop.Blocks[loop.Blocks.Count - 1];

                CStatement doWhile = new CStatement();
                doWhile.Kind = CStatement.Kinds.DoWhile;

                doWhile.Condition     = FindLastCondition(lastBlock.Statements);
                doWhile.SubBlocks     = loop.Blocks;
                doWhile.BreakBlock    = blocks[lastBlock.Id + 1];
                doWhile.ContinueBlock = lastBlock;

                doWhile.ExpandBlocks();

                if (doWhile.ContinueBlock.Statements.Count != 1)
                {
                    doWhile.ContinueBlock = null;
                }
                else
                {
                    CStatement stat = doWhile.ContinueBlock.Statements[0];
                    if (stat.Kind != CStatement.Kinds.Conditional)
                    {
                        doWhile.ContinueBlock = null;
                    }
                    else
                    {
                        if (stat.InnerBlock[0].BranchDestinationAddr != loop.Blocks[0].StartAddress)
                        {
                            doWhile.ContinueBlock = null;
                        }
                    }
                }

                /* Remove all blocks in the loop from the main block list. It is replaced by a single while block */
                int           firstIndex = blocks.IndexOf(loop.Blocks[0]);
                FunctionBlock firstBlock = blocks[firstIndex];
                foreach (FunctionBlock b in loop.Blocks)
                {
                    blocks.Remove(b);
                }

                FunctionBlock fake = new FunctionBlock();
                fake.StartAddress = firstBlock.StartAddress;
                fake.InstrCount   = 0;
                fake.Statements.Add(doWhile);

                loop.LoopBlock = fake;
                blocks.Insert(firstIndex, fake);

                StructureBreakContinue(doWhile, doWhile.ContinueBlock, doWhile.BreakBlock);
            }

            foreach (Loop loop in loops)
            {
                FunctionBlock precBlock = blocks.Find(delegate(FunctionBlock b) { return(b.Id == loop.Blocks[0].Id - 1); });

                uint precedingBlockStart = precBlock.StartAddress;
                uint lastInstruction     = precedingBlockStart + (precBlock.InstrCount - 1) * 4;
                uint offset      = state.Pe.Rva2Offset(lastInstruction - (uint)state.Pe.optHdr.ImageBase);
                uint instruction = state.Pe.ReadInstruction(offset);
                XenonInstructions.OpCodeInfo info = state.Instructions.GetInfo(instruction);

                if (info.Id == XenonInstructions.Mnemonics.PPC_OP_B)
                {
                    uint bDest = (instruction & 0xFFFFFF) + lastInstruction;
                    if (bDest == loop.Header.StartAddress)
                    {
                        loop.LoopBlock.Statements[0].Kind = CStatement.Kinds.While;
                        precBlock.InstrCount--;
                        precBlock.Statements.RemoveAt(precBlock.Statements.Count - 1);
                    }
                }
            }

            foreach (Loop loop in loops)
            {
                int           cnt  = loop.LoopBlock.Statements[0].SubBlocks.Count;
                FunctionBlock last = loop.LoopBlock.Statements[0].SubBlocks[cnt - 1];
                loop.LoopBlock.Statements[0].SubBlocks.RemoveAt(cnt - 1);

                last.Statements.RemoveAt(0);
                if (last.Statements.Count != 0)
                {
                    blocks.Add(last);
                    blocks.Sort(Function.FunctionBlockSorter);
                }

                /* This will have removed some statements, reexpand the blocks */
                loop.LoopBlock.Statements[0].ExpandBlocks();
            }
        }
Beispiel #6
0
        void AnalyzeBlock(FunctionBlock block, uint minFunctionAddr, uint maxFunctionAddr)
        {
            block.Analyzed = true;

            uint rva    = block.StartAddress - (uint)decompiler.Pe.GetImageBase();
            uint offset = decompiler.Pe.Rva2Offset(rva);

            bool cont = true;

            for (uint i = 0; i < block.InstrCount && cont; i++)
            {
                uint instruction = decompiler.Pe.ReadInstruction(offset + i * 4);
                XenonInstructions.OpCodeInfo  info  = decompiler.Instructions.GetInfo(instruction);
                XenonInstructions.Instruction instr = new XenonInstructions.Instruction(instruction);

                /* A branch signals end of block. However a branch with link is just a call, and it doesn't end a block */
                uint pc = block.StartAddress + i * 4;

                if (instr.LK())
                {
                    continue;
                }

                switch (info.Id)
                {
                case XenonInstructions.Mnemonics.PPC_OP_B:
                {
                    uint npc = (uint)SignExtend26(instr.LI() << 2);
                    if (!instr.AA())
                    {
                        npc += pc;
                    }

                    AddBlock(block, npc, minFunctionAddr, maxFunctionAddr);
                    block.InstrCount = i + 1;
                    cont             = false;

                    break;
                }

                case XenonInstructions.Mnemonics.PPC_OP_BC:
                {
                    uint npc = (uint)(int)(short)(instr.BD() << 2);
                    if (!instr.AA())
                    {
                        npc += pc;
                    }

                    AddBlock(block, npc, minFunctionAddr, maxFunctionAddr);
                    AddBlock(block, pc + 4, minFunctionAddr, maxFunctionAddr);
                    block.InstrCount = i + 1;
                    cont             = false;

                    break;
                }

                case XenonInstructions.Mnemonics.PPC_OP_BCCTR:
                case XenonInstructions.Mnemonics.PPC_OP_BCLR:
                {
                    if (instr.BO() != 20)
                    {
                        AddBlock(block, pc + 4, minFunctionAddr, maxFunctionAddr);
                    }

                    block.InstrCount = i + 1;
                    cont             = false;
                    break;
                }
                }
            }

            CleanupBlockList();
        }