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 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 = CapstoneDisassembler.CreateX86Disassembler(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.DisassembleAll(code); Assert.AreEqual(instructions.Length, 9); } }
public FmtX86(X86DisassembleMode mode) { disassembler = CapstoneDisassembler.CreateX86Disassembler(mode); disassembler.DisassembleSyntax = DisassembleSyntax.Intel; // Represent invalid instructions as "db 0x.." disassembler.EnableSkipDataMode = true; disassembler.SkipDataInstructionMnemonic = "db"; }
public void TestCreate() { var disassembler = CapstoneDisassembler.CreateX86Disassembler(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); }
private CapstoneX86Disassembler createCapstoneX86Eng(string mode) { if (mode == "32bit") { return(CapstoneDisassembler.CreateX86Disassembler(X86DisassembleMode.Bit32)); } else if (mode == "64bit") { return(CapstoneDisassembler.CreateX86Disassembler(X86DisassembleMode.Bit64)); } return(null); }
private static void RunTest(Byte[] code, Int64 address, Int32 mode) { using (var u = new Unicorn(Common.UC_ARCH_X86, mode)) using (var disassembler = CapstoneDisassembler.CreateX86Disassembler(DisassembleMode.Bit32)) { Console.WriteLine("Unicorn version: {0}", u.Version()); // map 2MB of memory for this emulation u.MemMap(address, 2 * 1024 * 1024, Common.UC_PROT_ALL); // initialize machine registers u.RegWrite(X86.UC_X86_REG_EAX, 0x1234); u.RegWrite(X86.UC_X86_REG_ECX, 0x1234); u.RegWrite(X86.UC_X86_REG_EDX, 0x7890); // write machine code to be emulated to memory u.MemWrite(address, code); // initialize machine registers u.RegWrite(X86.UC_X86_REG_ESP, Utils.Int64ToBytes(address + 0x200000)); // handle IN & OUT instruction u.AddInHook(InHookCallback); u.AddOutHook(OutHookCallback); // tracing all instructions by having @begin > @end u.AddCodeHook((uc, addr, size, userData) => CodeHookCallback(disassembler, uc, addr, size, userData), 1, 0); // handle interrupt ourself u.AddInterruptHook(InterruptHookCallback); // handle SYSCALL u.AddSyscallHook(SyscallHookCallback); // intercept invalid memory events u.AddEventMemHook(MemMapHookCallback, Common.UC_HOOK_MEM_READ_UNMAPPED | Common.UC_HOOK_MEM_WRITE_UNMAPPED); Console.WriteLine(">>> Start tracing code"); // emulate machine code in infinite time u.EmuStart(address, address + code.Length, 0u, 0u); // print registers var ecx = u.RegRead(X86.UC_X86_REG_ECX); var edx = u.RegRead(X86.UC_X86_REG_EDX); var eax = u.RegRead(X86.UC_X86_REG_EAX); Console.WriteLine("[!] EAX = {0}", eax.ToString("X")); Console.WriteLine("[!] ECX = {0}", ecx.ToString("X")); Console.WriteLine("[!] EDX = {0}", edx.ToString("X")); Console.WriteLine(">>> Emulation Done!"); } }
/// <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); }
private static void RunTest(Byte[] code, Int64 address) { try { using (var u = new Unicorn(Common.UC_ARCH_X86, Common.UC_MODE_32)) using (var disassembler = CapstoneDisassembler.CreateX86Disassembler(DisassembleMode.Bit32)) { Console.WriteLine("Unicorn version: {0}", u.Version()); // map 2MB of memory for this emulation u.MemMap(address, 2 * 1024 * 1024, Common.UC_PROT_ALL); // write machine code to be emulated to memory u.MemWrite(address, code); // initialize machine registers u.RegWrite(X86.UC_X86_REG_ESP, Utils.Int64ToBytes(address + 0x200000)); var regv = new Byte[4]; u.RegRead(X86.UC_X86_REG_ESP, regv); // tracing all instructions by having @begin > @end u.AddCodeHook((uc, addr, size, userData) => CodeHookCallback(disassembler, uc, addr, size, userData), 1, 0); // handle interrupt ourself u.AddInterruptHook(InterruptHookCallback); // handle SYSCALL u.AddSyscallHook(SyscallHookCallback); Console.WriteLine(">>> Start tracing code"); // emulate machine code in infinite time u.EmuStart(address, address + code.Length, 0u, 0u); Console.WriteLine(">>> Emulation Done!"); } } catch (UnicornEngineException ex) { Console.Error.WriteLine("Emulation FAILED! " + ex.Message); } }
private void HEX2ASM_Exec(object sender, ExecutedRoutedEventArgs e) { var HexText = this.HEXBox.Text.ToUpper(); var BinaryCode = StrToByteArray(HexText); dynamic disassembleMode; if (this.Arch.SelectedIndex == 0) { disassembleMode = X86DisassembleMode.Bit32; } else if (this.Arch.SelectedIndex == 1) { disassembleMode = X86DisassembleMode.Bit64; } else { disassembleMode = X86DisassembleMode.Bit32; } string disasmText = ""; try { using (var disassembler = CapstoneDisassembler.CreateX86Disassembler(disassembleMode)) { disassembler.EnableInstructionDetails = true; disassembler.DisassembleSyntax = DisassembleSyntax.Intel; dynamic instructions = disassembler.Disassemble(BinaryCode); foreach (var instruction in instructions) { var address = instruction.Address; var id = instruction.Id; var mnemonic = instruction.Mnemonic; var operand = instruction.Operand; disasmText += String.Format("{0} \t {1} \n", mnemonic, operand); } } this.ASMBox.Text = disasmText; } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Exception"); } }
internal static void ShowX86() { // 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 = CapstoneDisassembler.CreateX86Disassembler(DisassembleMode.Bit32)) { // 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 }; #if DISASSEMBLE_STREAM //$REVIEW: uxmal: This exercises the lazy stream implementation of the disassembler. // It isn't greed and tries to disassembly all the instructions at once, // but only on demand. var instructions = disassembler.DisassembleStream(code, 0, 0x1000); #else var instructions = disassembler.DisassembleAll(code); #endif 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 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); // Loop Through Each Instruction's Operands. // // ... 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); // Handle Memory Operand. // // ... 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); } Console.WriteLine(); } } }
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)); } } } }