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); }
/// <summary> /// Create an X86 Disassembler. /// </summary> /// <param name="disassembleMode"> /// The hardware mode for the disassembler to use. /// </param> /// <returns> /// An X86 disassembler. /// </returns> /// <exception cref="Capstone.Net.CapstoneException"> /// Thrown if a disassembler could not be created. /// </exception> /// <exception cref="System.OutOfMemoryException"> /// Thrown if sufficient memory cannot be allocated to perform the operation as a rare indication that the /// system is under heavy load. /// </exception> public static CapstoneX86Disassembler CreateX86Disassembler(X86DisassembleMode disassembleMode) { return(new CapstoneX86Disassembler(disassembleMode)); }
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)); } } } }