/// <summary> /// Create an ARM Disassembler. /// </summary> /// <param name="mode"> /// The disassembler's mode. /// </param> /// <returns> /// A capstone disassembler. /// </returns> public static CapstoneDisassembler <ArmInstruction, ArmRegister, ArmInstructionGroup, ArmInstructionDetail> CreateArmDisassembler(DisassembleMode mode) { var @object = new CapstoneArmDisassembler(mode); return(@object); }
internal static void ShowArm(DisassembleMode mode) { using (CapstoneArmDisassembler disassembler = new CapstoneArmDisassembler(mode)) { disassembler.EnableDetails = true; disassembler.Syntax = DisassembleSyntaxOptionValue.Intel; byte[] 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 (int) DisassembleMode.ArmThumb + DisassembleMode.ArmCortexM: code = new byte[] {0xef, 0xf3, 0x02, 0x80}; break; } var instructions = disassembler.Disassemble(code); string hexCode = BitConverter.ToString(code).Replace("-", " "); Console.WriteLine(hexCode); Console.WriteLine(); 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); foreach (ArmInstructionOperand 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); 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(); } } }
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; }
internal static void ShowArm(DisassembleMode mode) { using (CapstoneArmDisassembler disassembler = new CapstoneArmDisassembler(mode)) { disassembler.EnableDetails = true; disassembler.Syntax = DisassembleSyntaxOptionValue.Intel; byte[] 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 (int)DisassembleMode.ArmThumb + DisassembleMode.ArmCortexM: code = new byte[] { 0xef, 0xf3, 0x02, 0x80 }; break; } var instructions = disassembler.Disassemble(code); string hexCode = BitConverter.ToString(code).Replace("-", " "); Console.WriteLine(hexCode); Console.WriteLine(); 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); foreach (ArmInstructionOperand 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); 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(); } } }