public void TestDisassemble() { // Create X86 Disassembler. // // Creating the disassembler in a "using" statement ensures that resources get cleaned up automatically // when it is no longer needed. using (var disassembler = new CapstoneX86Disassembler(DisassembleMode.Bit32)) { Assert.IsNotNull(disassembler); // 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; // Disassemble All Binary Code. // // ... var code = new byte[] { 0x8d, 0x4c, 0x32, 0x08, 0x01, 0xd8, 0x81, 0xc6, 0x34, 0x12, 0x00, 0x00, 0x05, 0x23, 0x01, 0x00, 0x00, 0x36, 0x8b, 0x84, 0x91, 0x23, 0x01, 0x00, 0x00, 0x41, 0x8d, 0x84, 0x39, 0x89, 0x67, 0x00, 0x00, 0x8d, 0x87, 0x89, 0x67, 0x00, 0x00, 0xb4, 0xc6 }; var instructions = disassembler.Disassemble(code); Assert.AreEqual(instructions.Length, 9); } }
public static string DissasembleIl2CppMethod(MethodInfo method, UnitorModel module) { StringBuilder output = new StringBuilder(); if (!method.VirtualAddress.HasValue) { return(""); } X86DisassembleMode mode = module.AppModel.Image.Arch == "x64" ? X86DisassembleMode.Bit64 : X86DisassembleMode.Bit32; CapstoneX86Disassembler disassembler = CapstoneDisassembler.CreateX86Disassembler(mode); disassembler.EnableInstructionDetails = true; var asm = disassembler.Disassemble(method.GetMethodBody(), (long)method.VirtualAddress.Value.Start); foreach (X86Instruction ins in asm) { if (ShouldCheckInstruction(ins.Id)) { output.AppendLine(ins.Mnemonic + " " + ins.Operand + " " + GetTooltipFromInstruction(method, ins, module)); } else { output.AppendLine(ins.Mnemonic + " " + ins.Operand); } } disassembler.Dispose(); return(output.ToString()); }
public FmtX86(X86DisassembleMode mode) { disassembler = CapstoneDisassembler.CreateX86Disassembler(mode); disassembler.DisassembleSyntax = DisassembleSyntax.Intel; // Represent invalid instructions as "db 0x.." disassembler.EnableSkipDataMode = true; disassembler.SkipDataInstructionMnemonic = "db"; }
/// <summary> /// Create a basic block processing worker /// </summary> /// <param name="binaryTarg">Binary target associated with the trace</param> /// <param name="runrecord">TraceRecord associated with the trace</param> /// <param name="remotePipeID">ID of the pipe receiving basic block data</param> public BlockHandlerThread(BinaryTarget binaryTarg, TraceRecord runrecord, uint?remotePipeID = null) { target = binaryTarg; trace = runrecord; bitWidth = target.BitWidth; _remotePipeID = remotePipeID; //todo don't create in headless mode X86DisassembleMode disasMode = (bitWidth == 32) ? X86DisassembleMode.Bit32 : X86DisassembleMode.Bit64; disassembler = CapstoneDisassembler.CreateX86Disassembler(disasMode); }
static void Main(string[] args) { X86DisassembleMode disassembleMode = X86DisassembleMode.Bit32; if (args.Length == 2) { switch (args[0]) { case "16": { disassembleMode = X86DisassembleMode.Bit16; break; } case "32": { disassembleMode = X86DisassembleMode.Bit32; break; } case "64": { disassembleMode = X86DisassembleMode.Bit64; break; } default: break; } } else { Console.Write("Must use arguments: <bit-length[16|32|64]> <target file path>"); return; } string filePath = args[1]; BinaryReader reader = new BinaryReader(File.Open(filePath, FileMode.Open)); var fileSize = Convert.ToInt32(new FileInfo(filePath).Length); var codeBytes = reader.ReadBytes(fileSize); var sw = Stopwatch.StartNew(); CapstoneX86Disassembler disassembler = CapstoneX86Disassembler.CreateX86Disassembler(disassembleMode); disassembler.EnableSkipDataMode = true; disassembler.EnableInstructionDetails = false; disassembler.DisassembleSyntax = DisassembleSyntax.Intel; foreach (X86Instruction instruction in disassembler.Iterate(codeBytes)) { var address = instruction.Address; var mnemonic = instruction.Mnemonic; var operand = instruction.Operand; Console.WriteLine("{0:X}:\t{1}\t{2}", address, mnemonic, operand); } sw.Stop(); Console.Error.WriteLine("Total dump time: {0:F} sec.", sw.Elapsed.TotalSeconds); }
public void TestCreate() { try { using (var disassembler = new CapstoneX86Disassembler(DisassembleMode.Bit32)) { Assert.IsNotNull(disassembler); Assert.AreEqual(disassembler.Architecture, DisassembleArchitecture.X86); Assert.AreEqual(disassembler.EnableDetails, false); Assert.AreEqual(disassembler.Mode, DisassembleMode.Bit32); Assert.AreEqual(disassembler.Syntax, DisassembleSyntaxOptionValue.Default); } } catch (System.Exception e) { for (System.Exception ex = e; null != ex; ex = ex.InnerException) { System.Console.Write(ex.StackTrace); } throw; } }
/// <summary> /// Create an X86 Disassembler. /// </summary> /// <param name="mode"> /// The disassembler's mode. /// </param> /// <returns> /// A capstone disassembler. /// </returns> public static CapstoneDisassembler <X86Instruction, X86Register, X86InstructionGroup, X86InstructionDetail> CreateX86Disassembler(DisassembleMode mode) { var @object = new CapstoneX86Disassembler(mode); return(@object); }
private void ps4KernelDlSymRetrieveSymbols(Byte[] buffer) { using (CapstoneX86Disassembler disassembler = CapstoneDisassembler.CreateX86Disassembler(X86DisassembleMode.Bit64)) { disassembler.EnableInstructionDetails = true; disassembler.DisassembleSyntax = DisassembleSyntax.Intel; //disassembler.EnableSkipDataMode = true; X86Instruction[] instructions = disassembler.Disassemble(buffer); int i = 0; foreach (X86Instruction instruction in instructions) { i++; X86Instruction lastInsn = (i > 1) ? instructions[i - 2] : null; long address = instruction.Address; X86InstructionId id = instruction.Id; String curr_instruction = GetInstructionTxt(instruction); String last_instruction = GetInstructionTxt(lastInsn); //if (address == 0x14362) // MessageBox.Show(curr_instruction); if (!instruction.IsSkippedData) { String ps4KernelDlSym = GetMemoryAddress((UInt64)ps4KernelDlSym_offset).ToString("x"); //if (instruction.Operand.Contains(ps4KernelDlSym)) // MessageBox.Show("call to ps4KernelDlSym: " + curr_instruction); //if(id == X86InstructionId.X86_INS_MOVABS) // MessageBox.Show("moveabs: " + curr_instruction); //MessageBox.Show(ps4KernelDlSym); if (instruction.Operand.Contains(ps4KernelDlSym) && id == X86InstructionId.X86_INS_MOVABS) { String ps4KernelDlSym_call = instructions[i + 1].Operand;//instructions[i + 1].Id == X86InstructionId.X86_INS_CALL ? string last_operand = lastInsn.Operand; if (lastInsn.Id == X86InstructionId.X86_INS_MOVABS) { String symbolReg = ""; var symbolName = ParseSymbolReference(lastInsn, out symbolReg); if (symbolName != "") { sympool.Add(lastInsn.Address, symbolName);//ps4KernelDlSym_Symbols.Add(symbolName); } // after we have got a symbol, find for near ps4KernelDlSym references var targetReg = instructions[i].Operand; var targetBytes = instructions[i].Bytes; //MessageBox.Show(targetReg); //MessageBox.Show(GetInstructionTxt(instructions[i+1])); for (int x = i + 2; x < instructions.Count(); x++) { var instruct = instructions[x]; if (instruct == null || instruct.IsSkippedData || instruct.Id == X86InstructionId.X86_INS_RET || instruct.Id == X86InstructionId.X86_INS_MOVABS & instruct.Operand.Split(',')[0] == targetReg)//GetInstructionTxt(instruct).Contains("ret")) { break; } if (instruct.Id == X86InstructionId.X86_INS_CALL)// && instruct.Operand == ps4KernelDlSym_call.Split(',')[0]) { //MessageBox.Show(GetInstructionTxt(instruct)); //MessageBox.Show(instruct.Operand + "\n\n" + ps4KernelDlSym_call); var reg = instruct.Operand; var prev_sym_reg = symbolReg; if (reg == targetReg & (symbolName = ParseSymbolReference(instructions[x - 1], out symbolReg)) != "") { if (targetBytes.SequenceEqual(instruct.Bytes))//if ((symbolName = ParseSymbolReference(instructions[x - 1], out symbolReg)) != "") { if (symbolReg == prev_sym_reg) { sympool.Add(instructions[x - 1].Address, symbolName); /* * var addr = GetMemoryAddress((ulong)instructions[x - 1].Address) - 0x1000; * Clipboard.SetText(addr.ToString("X2")); * MessageBox.Show("Addr: " + addr.ToString("X2") + ", " + symbolName + "\n\n" + GetInstructionTxt(instructions[x-1])); */ } //MessageBox.Show(last_instruction + "\n" + curr_instruction + "\n\n" + GetInstructionTxt(instructions[x-1]) + "\n" + GetInstructionTxt(instruct), "Near " + symbolName); } } //MessageBox.Show(curr_instruction + "\n" + GetInstructionTxt(instruct)); } //MessageBox.Show(last_instruction + "\n" + curr_instruction + "\n\n" + targetReg); } } /*else if (id == X86InstructionId.X86_INS_CALL) * { * MessageBox.Show(last_instruction + "\n" + curr_instruction); * }*/ } } } } }
public void Analyse() { if (IsEmpty) { return; } if (Il2CppMethod != null) { if (!Il2CppMethod.VirtualAddress.HasValue) { return; } X86DisassembleMode mode = Owner.AppModel.Image.Arch == "x64" ? X86DisassembleMode.Bit64 : X86DisassembleMode.Bit32; CapstoneX86Disassembler disassembler = CapstoneDisassembler.CreateX86Disassembler(mode); disassembler.EnableInstructionDetails = true; var asm = disassembler.Disassemble(Il2CppMethod.GetMethodBody(), (long)Il2CppMethod.VirtualAddress.Value.Start); foreach (X86Instruction ins in asm) { if (Dissasembler.ShouldCheckInstruction(ins.Id)) { UnitorMethod m = Dissasembler.GetMethodFromInstruction(ins, Owner); if (m != null) { MethodCalls.Add(m); Owner.MethodReferences.AddOrUpdate(m, new List <UnitorMethod>(), (key, references) => { references.Add(this); return(references); }); } var s = Dissasembler.GetStringFromInstruction(ins, Owner.StringTable); if (!string.IsNullOrEmpty(s.Item2)) { Strings.Add(new KeyValuePair <ulong, string>(s.Item1, s.Item2)); } } } disassembler.Dispose(); } else { if (!MonoMethod.HasBody) { return; } foreach (Instruction ins in MonoMethod.Body.Instructions) { if ((ins.OpCode.Code == Code.Call || ins.OpCode.Code == Code.Calli || ins.OpCode.Code == Code.Callvirt) && ins.Operand is MethodDef calledMethod) { if (Owner.MonoTypeMatches.TryGetValue(calledMethod.DeclaringType, out UnitorType type)) { if (type.Methods == null) { continue; } UnitorMethod method = type.Methods.FirstOrDefault(m => calledMethod.Name == m.Name); MethodCalls.Add(method); Owner.MethodReferences.AddOrUpdate(method, new List <UnitorMethod>(), (key, references) => { references.Add(this); return(references); }); } } if (ins.OpCode.Code == Code.Ldstr && ins.Operand is string s) { Strings.Add(new KeyValuePair <ulong, string>((ulong)(MonoMethod.RVA + ins.Offset), s)); } } } }
internal static void ShowX86(bool iteratively = false) { using (CapstoneX86Disassembler disassembler = new CapstoneX86Disassembler(DisassembleMode.Bit32)) { disassembler.EnableDetails = true; disassembler.Syntax = DisassembleSyntaxOptionValue.Intel; var code = new byte[] {0x8d, 0x4c, 0x32, 0x08, 0x01, 0xd8, 0x81, 0xc6, 0x34, 0x12, 0x00, 0x00, 0x05, 0x23, 0x01, 0x00, 0x00, 0x36, 0x8b, 0x84, 0x91, 0x23, 0x01, 0x00, 0x00, 0x41, 0x8d, 0x84, 0x39, 0x89, 0x67, 0x00, 0x00, 0x8d, 0x87, 0x89, 0x67, 0x00, 0x00, 0xb4, 0xc6}; if (iteratively) { disassembler.Disassemble(code, OnX86DisassembledInstruction); return; } var instructions = disassembler.Disassemble(code); var 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 Address Size = {0}", instruction.ArchitectureDetail.AddressSize); Console.WriteLine("\t AVX Code Condition = {0}", instruction.ArchitectureDetail.AvxCodeCondition); Console.WriteLine("\t AVX Rounding Mode = {0}", instruction.ArchitectureDetail.AvxRoundingMode); Console.WriteLine("\t Displacement = {0:X}", instruction.ArchitectureDetail.Displacement); Console.WriteLine("\t Mod/Rm = {0:X}", instruction.ArchitectureDetail.ModRm); Console.WriteLine("\t Operand Count: {0}", instruction.ArchitectureDetail.Operands.Length); foreach (var operand in instruction.ArchitectureDetail.Operands) { string operandValue = null; switch (operand.Type) { case X86InstructionOperandType.FloatingPoint: operandValue = operand.FloatingPointValue.Value.ToString("X"); break; case X86InstructionOperandType.Immediate: operandValue = operand.ImmediateValue.Value.ToString("X"); break; case X86InstructionOperandType.Memory: operandValue = "-->"; break; case X86InstructionOperandType.Register: operandValue = operand.RegisterValue.Value.ToString(); break; } Console.WriteLine("\t\t {0} = {1}", operand.Type, operandValue); if (operand.Type == X86InstructionOperandType.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("\t\t\t Segment Register = {0}", operand.MemoryValue.SegmentRegister); Console.WriteLine(); } Console.WriteLine("\t\t\t AVX Broadcast = {0}", operand.AvxBroadcast); Console.WriteLine("\t\t\t AVX Zero Operation Mask? {0}", operand.AvxZeroOperationMask); } var hexOperationCode = BitConverter.ToString(instruction.ArchitectureDetail.OperationCode).Replace("-", " "); Console.WriteLine("\t Operation Code = {0}", hexOperationCode); var hexPrefix = String.Join(" ", instruction.ArchitectureDetail.Prefix); Console.WriteLine("\t Prefix = {0}", hexPrefix); Console.WriteLine("\t REX = {0}", instruction.ArchitectureDetail.Rex); Console.WriteLine("\t SIB = {0}", instruction.ArchitectureDetail.Sib); Console.WriteLine("\t SIB Base Register = {0}", instruction.ArchitectureDetail.SibBaseRegister); Console.WriteLine("\t SIB Index Register = {0}", instruction.ArchitectureDetail.SibIndexRegister); Console.WriteLine("\t SIB Scale = {0}", instruction.ArchitectureDetail.SibScale); Console.WriteLine("\t SSE Code Condition = {0}", instruction.ArchitectureDetail.SseCodeCondition); Console.WriteLine("\t Suppress All AVX Exceptions? {0}", instruction.ArchitectureDetail.SuppressAllAvxExceptions); } } } }
internal static void ShowX86(bool iteratively = false) { using (CapstoneX86Disassembler disassembler = new CapstoneX86Disassembler(DisassembleMode.Bit32)) { disassembler.EnableDetails = true; disassembler.Syntax = DisassembleSyntaxOptionValue.Intel; var code = new byte[] { 0x8d, 0x4c, 0x32, 0x08, 0x01, 0xd8, 0x81, 0xc6, 0x34, 0x12, 0x00, 0x00, 0x05, 0x23, 0x01, 0x00, 0x00, 0x36, 0x8b, 0x84, 0x91, 0x23, 0x01, 0x00, 0x00, 0x41, 0x8d, 0x84, 0x39, 0x89, 0x67, 0x00, 0x00, 0x8d, 0x87, 0x89, 0x67, 0x00, 0x00, 0xb4, 0xc6 }; if (iteratively) { disassembler.Disassemble(code, OnX86DisassembledInstruction); return; } var instructions = disassembler.Disassemble(code); var 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 Address Size = {0}", instruction.ArchitectureDetail.AddressSize); Console.WriteLine("\t AVX Code Condition = {0}", instruction.ArchitectureDetail.AvxCodeCondition); Console.WriteLine("\t AVX Rounding Mode = {0}", instruction.ArchitectureDetail.AvxRoundingMode); Console.WriteLine("\t Displacement = {0:X}", instruction.ArchitectureDetail.Displacement); Console.WriteLine("\t Mod/Rm = {0:X}", instruction.ArchitectureDetail.ModRm); Console.WriteLine("\t Operand Count: {0}", instruction.ArchitectureDetail.Operands.Length); foreach (var operand in instruction.ArchitectureDetail.Operands) { string operandValue = null; switch (operand.Type) { case X86InstructionOperandType.FloatingPoint: operandValue = operand.FloatingPointValue.Value.ToString("X"); break; case X86InstructionOperandType.Immediate: operandValue = operand.ImmediateValue.Value.ToString("X"); break; case X86InstructionOperandType.Memory: operandValue = "-->"; break; case X86InstructionOperandType.Register: operandValue = operand.RegisterValue.Value.ToString(); break; } Console.WriteLine("\t\t {0} = {1}", operand.Type, operandValue); if (operand.Type == X86InstructionOperandType.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("\t\t\t Segment Register = {0}", operand.MemoryValue.SegmentRegister); Console.WriteLine(); } Console.WriteLine("\t\t\t AVX Broadcast = {0}", operand.AvxBroadcast); Console.WriteLine("\t\t\t AVX Zero Operation Mask? {0}", operand.AvxZeroOperationMask); } var hexOperationCode = BitConverter.ToString(instruction.ArchitectureDetail.OperationCode).Replace("-", " "); Console.WriteLine("\t Operation Code = {0}", hexOperationCode); var hexPrefix = String.Join(" ", instruction.ArchitectureDetail.Prefix); Console.WriteLine("\t Prefix = {0}", hexPrefix); Console.WriteLine("\t REX = {0}", instruction.ArchitectureDetail.Rex); Console.WriteLine("\t SIB = {0}", instruction.ArchitectureDetail.Sib); Console.WriteLine("\t SIB Base Register = {0}", instruction.ArchitectureDetail.SibBaseRegister); Console.WriteLine("\t SIB Index Register = {0}", instruction.ArchitectureDetail.SibIndexRegister); Console.WriteLine("\t SIB Scale = {0}", instruction.ArchitectureDetail.SibScale); Console.WriteLine("\t SSE Code Condition = {0}", instruction.ArchitectureDetail.SseCodeCondition); Console.WriteLine("\t Suppress All AVX Exceptions? {0}", instruction.ArchitectureDetail.SuppressAllAvxExceptions); } } } }