Example #1
0
 public ThumbDisassembler(ImageReader rdr)
 {
     this.rdr           = rdr;
     this.dasm          = CapstoneDisassembler.CreateArmDisassembler(DisassembleMode.ArmThumb);
     dasm.EnableDetails = true;
     this.stream        = dasm.DisassembleStream(
         rdr.Bytes,
         (int)rdr.Offset,
         (long)(rdr.Address.ToLinear()))
                          .GetEnumerator();
 }
Example #2
0
        public Arm32Disassembler(Arm32ProcessorArchitecture arch, EndianImageReader rdr)
        {
            var dasm = CapstoneDisassembler.CreateArmDisassembler(
                DisassembleMode.Arm32 | DisassembleMode.LittleEndian);

            dasm.EnableDetails = true;
            this.stream        = dasm.DisassembleStream(
                rdr.Bytes,
                (int)rdr.Offset,
                (long)rdr.Address.ToLinear() - rdr.Offset)
                                 .GetEnumerator();
        }
Example #3
0
        internal static void ShowArm(DisassembleMode mode)
        {
            // Create ARM Disassembler.
            //
            // Creating the disassembler in a "using" statement ensures that resources get cleaned up automatically
            // when it is no longer needed.
            using (var disassembler = CapstoneDisassembler.CreateArmDisassembler(mode)) {
                // Enable Disassemble Details.
                //
                // Enables disassemble details, which are disabled by default, to provide more detailed information on
                // disassembled binary code.
                disassembler.EnableDetails = true;

                // Set Disassembler's Syntax.
                //
                // Make the disassembler generate instructions in Intel syntax.
                disassembler.Syntax = DisassembleSyntaxOptionValue.Intel;

                var code = new byte[0];
                switch (mode)
                {
                case DisassembleMode.Arm32:
                    code = new byte[] { 0xED, 0xFF, 0xFF, 0xEB, 0x04, 0xe0, 0x2d, 0xe5, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x83, 0x22, 0xe5, 0xf1, 0x02, 0x03, 0x0e, 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x30, 0xc1, 0xe7, 0x00, 0x00, 0x53, 0xe3, 0x00, 0x02, 0x01, 0xf1, 0x05, 0x40, 0xd0, 0xe8, 0xf4, 0x80, 0x00, 0x00 };
                    break;

                case (int)DisassembleMode.Arm32 + DisassembleMode.ArmV8:
                    code = new byte[] { 0xe0, 0x3b, 0xb2, 0xee, 0x42, 0x00, 0x01, 0xe1, 0x51, 0xf0, 0x7f, 0xf5 };
                    break;

                case DisassembleMode.ArmThumb:
                    code = new byte[] { 0x70, 0x47, 0xeb, 0x46, 0x83, 0xb0, 0xc9, 0x68, 0x1f, 0xb1, 0x30, 0xbf, 0xaf, 0xf3, 0x20, 0x84 };
                    break;

                case DisassembleMode.ArmThumbArmCortexM:
                    code = new byte[] { 0xef, 0xf3, 0x02, 0x80 };
                    break;
                }

                // Disassemble All Binary Code.
                //
                // ...
                var instructions = disassembler.DisassembleAll(code);

                var hexCode = BitConverter.ToString(code).Replace("-", " ");
                Console.WriteLine(hexCode);
                Console.WriteLine();

                // Loop Through Each Disassembled Instruction.
                // ...
                foreach (var instruction in instructions)
                {
                    Console.WriteLine("{0:X}: \t {1} \t {2}", instruction.Address, instruction.Mnemonic, instruction.Operand);
                    Console.WriteLine("\t Id = {0}", instruction.Id);

                    if (instruction.ArchitectureDetail != null)
                    {
                        Console.WriteLine("\t CPS Flag = {0}", instruction.ArchitectureDetail.CpsFlag);
                        Console.WriteLine("\t CPS Mode = {0}", instruction.ArchitectureDetail.CpsMode);
                        Console.WriteLine("\t Code Condition = {0}", instruction.ArchitectureDetail.CodeCondition);
                        Console.WriteLine("\t Load User Mode Registers? {0}", instruction.ArchitectureDetail.LoadUserModeRegisters);
                        Console.WriteLine("\t Memory Barrier = {0}", instruction.ArchitectureDetail.MemoryBarrier);
                        Console.WriteLine("\t Operand Count: {0}", instruction.ArchitectureDetail.Operands.Length);

                        // Loop Through Each Instruction's Operands.
                        //
                        // ...
                        foreach (var operand in instruction.ArchitectureDetail.Operands)
                        {
                            string operandValue = null;
                            switch (operand.Type)
                            {
                            case ArmInstructionOperandType.CImmediate:
                                operandValue = operand.ImmediateValue.Value.ToString("X");
                                break;

                            case ArmInstructionOperandType.FloatingPoint:
                                operandValue = operand.FloatingPointValue.Value.ToString();
                                break;

                            case ArmInstructionOperandType.Immediate:
                                operandValue = operand.ImmediateValue.Value.ToString("X");
                                break;

                            case ArmInstructionOperandType.PImmediate:
                                operandValue = operand.ImmediateValue.Value.ToString("X");
                                break;

                            case ArmInstructionOperandType.Memory:
                                operandValue = "-->";
                                break;

                            case ArmInstructionOperandType.Register:
                                operandValue = operand.RegisterValue.Value.ToString();
                                break;

                            case ArmInstructionOperandType.SetEnd:
                                operandValue = operand.SetEndValue.Value.ToString();
                                break;

                            case ArmInstructionOperandType.SysRegister:
                                operandValue = operand.SysRegisterValue.Value.ToString();
                                break;
                            }

                            Console.WriteLine("\t\t {0} = {1}", operand.Type, operandValue);

                            // Handle Memory Operand.
                            //
                            // ...
                            if (operand.Type == ArmInstructionOperandType.Memory)
                            {
                                Console.WriteLine("\t\t\t Base Register = {0} ", operand.MemoryValue.BaseRegister);
                                Console.WriteLine("\t\t\t Displacement = {0:X} ", operand.MemoryValue.Displacement);
                                Console.WriteLine("\t\t\t Index Register = {0} ", operand.MemoryValue.IndexRegister);
                                Console.WriteLine("\t\t\t Index Register Scale = {0} ", operand.MemoryValue.IndexRegisterScale);
                                Console.WriteLine();
                            }

                            Console.WriteLine("\t\t\t Is Subtracted? = {0}", operand.IsSubtracted);
                            Console.WriteLine("\t\t\t Shifter = -->");
                            Console.WriteLine("\t\t\t\t Type = {0}", operand.Shifter.Type);
                            Console.WriteLine("\t\t\t\t Value = {0:X}", operand.Shifter.Value);

                            Console.WriteLine("\t\t\t Vector Index = {0}", operand.VectorIndex);
                        }

                        Console.WriteLine("\t Update Flags? {0}", instruction.ArchitectureDetail.UpdateFlags);
                        Console.WriteLine("\t Vector Data Type = {0}", instruction.ArchitectureDetail.VectorDataType);
                        Console.WriteLine("\t Vector Size= {0}", instruction.ArchitectureDetail.VectorSize);
                        Console.WriteLine("\t Write Back? {0}", instruction.ArchitectureDetail.WriteBack);
                    }

                    Console.WriteLine();
                }
            }
        }
Example #4
0
        private void ReloadListButton_Click(object sender, EventArgs e)
        {
            ArmDisassembleMode disassembleMode = ArmDisassembleMode.Arm;

            if (thumb.Checked)
            {
                disassembleMode = ArmDisassembleMode.Thumb;
            }
            uint addr = (uint)ReadStartAddress.Value;

            if ((addr & 1) == 1)
            {
                disassembleMode = ArmDisassembleMode.Thumb;
                addr--;
            }
            if (addr >= GBAMemory.ROM_ADDR)
            {
                addr -= GBAMemory.ROM_ADDR;
                U.ForceUpdate(ReadStartAddress, addr);
            }
            if (addr >= (uint)Program.ROM.Data.Length)
            {
                return;
            }
            int count = (int)ReadCount.Value;

            if (count == 0)
            {
                count = 1;
                U.ForceUpdate(ReadCount, count);
            }

            assembly.Clear();
            using (CapstoneArmDisassembler disassembler = CapstoneDisassembler.CreateArmDisassembler(disassembleMode))
            {
                disassembler.DisassembleSyntax = DisassembleSyntax.Intel;
                if (syntax_att.Checked)
                {
                    disassembler.DisassembleSyntax = DisassembleSyntax.Att;
                }
                if (syntax_msam.Checked)
                {
                    disassembler.DisassembleSyntax = DisassembleSyntax.Masm;
                }
                // ...
                //
                // By enabling Skip Data Mode, we let Capstone will automatically skip over data and continue
                // disassembling at the next valid instruction it finds.
                if (skip_data.Checked)
                {
                    disassembler.EnableSkipDataMode = true;
                }
                ArmInstruction[] instructions = disassembler.Disassemble(Program.ROM.Data.Skip((int)addr).ToArray(), GBAMemory.ROM_ADDR + addr, count);
                foreach (ArmInstruction instruction in instructions)
                {
                    if (!instruction.IsSkippedData)
                    {
                        var address         = instruction.Address;
                        ArmInstructionId id = instruction.Id;
                        if (!instruction.IsDietModeEnabled)
                        {
                            // ...
                            //
                            // An instruction's mnemonic and operand text are only available when Diet Mode is disabled.
                            // An exception is thrown otherwise!
                            var mnemonic = instruction.Mnemonic;
                            var operand  = instruction.Operand;
                            assembly.AppendText(string.Format("/* {0:X} */ \t {1} \t {2}", address, mnemonic, operand));
                        }
                        assembly.AppendText(System.Environment.NewLine);
                    }
                }
            }

            return;
        }
Example #5
0
        public static AnalyzedFile Analyze(string FilePath, string AsmPath = null)
        {
            PeFile File = new PeFile(FilePath);

            SortedList <UInt32, ArmInstruction> AnalyzedCode = new SortedList <uint, ArmInstruction>(0x1000000); // Default capacity of 0x100000 was not enough for analyzing ntoskrnl.exe

            if ((AsmPath != null) && System.IO.File.Exists(AsmPath))
            {
                using (StreamReader Reader = new StreamReader(AsmPath))
                {
                    while (Reader.Peek() >= 0)
                    {
                        ArmInstruction Instruction = new ArmInstruction(Reader.ReadLine());
                        AnalyzedCode.Add(Instruction.Address, Instruction);
                    }
                }
            }
            else
            {
                CapstoneDisassembler <Gee.External.Capstone.Arm.ArmInstruction, ArmRegister, ArmInstructionGroup, ArmInstructionDetail> Disassembler = CapstoneDisassembler.CreateArmDisassembler(DisassembleMode.ArmThumb);

                // Initially use a Dictionary and sort it afterwards. For analyzing ntoskrnl.exe this is about 60 times faster than using a SortedList from the start.
                // Default capacity of 0x100000 was not enough for analyzing ntoskrnl.exe
                Dictionary <UInt32, ArmInstruction> TempCode = new Dictionary <uint, ArmInstruction>(0x1000000);

                // Analyze from entrypoint
                Analyze(Disassembler, File.Sections, TempCode, (UInt32)(File.ImageBase + File.EntryPoint));

                // Analyze from exports
                foreach (FunctionDescriptor Function in File.Exports)
                {
                    Analyze(Disassembler, File.Sections, TempCode, (UInt32)(Function.VirtualAddress));
                }

                // Analyze from imports
                foreach (FunctionDescriptor Function in File.Imports)
                {
                    Analyze(Disassembler, File.Sections, TempCode, (UInt32)(Function.VirtualAddress));
                }

                // Analyze from runtime-functions
                foreach (FunctionDescriptor Function in File.RuntimeFunctions)
                {
                    Analyze(Disassembler, File.Sections, TempCode, (UInt32)(Function.VirtualAddress));
                }

                // Sort the instructions.
                // SortedList is used, because it can be indexed by value (not only by key).
                List <UInt32> Keys = TempCode.Keys.ToList();
                Keys.Sort();
                foreach (UInt32 Key in Keys)
                {
                    AnalyzedCode.Add(Key, TempCode[Key]);
                }

                if (AsmPath != null)
                {
                    System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(AsmPath));

                    using (StreamWriter Writer = new StreamWriter(AsmPath, false))
                    {
                        for (int i = 0; i < AnalyzedCode.Count; i++)
                        {
                            Writer.WriteLine(AnalyzedCode.Values[i].ToString());
                        }
                    }
                }
            }

            return(new AnalyzedFile()
            {
                File = File, Code = AnalyzedCode
            });
        }