/* Capstone Disassembler Engine */ /* By Nguyen Anh Quynh , 2013> */ using System; using System.Runtime.InteropServices; public struct cs_insn { public UInt32 id; public UInt64 address; public UInt16 size; public string mnemonic; public string operands; public int[] regs_read; public int[] regs_write; public int[] groups; }; public class Capstone { [StructLayout(LayoutKind.Sequential)] struct _cs_insn { public UInt32 id; public UInt64 address; public UInt16 size; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public char[] mnemonic; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)] public char[] operands; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public int[] regs_read; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public int[] regs_write; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public int[] groups; }; public const int CS_ARCH_ARM = 0; public const int CS_ARCH_ARM64 = 1; public const int CS_ARCH_MIPS = 2; public const int CS_ARCH_X86 = 3; public const int CS_MODE_LITTLE_ENDIAN = 0; // default mode public const int CS_MODE_SYNTAX_INTEL = 0; // default X86 asm syntax (applicable for CS_ARCH_INTEL only) public const int CS_MODE_ARM = 0; public const int CS_MODE_16 = 1 << 1; public const int CS_MODE_32 = 1 << 2; public const int CS_MODE_64 = 1 << 3; public const int CS_MODE_THUMB = 1 << 4; public const int CS_MODE_SYNTAX_ATT = 1 << 30; // X86 ATT asm syntax (applicable for CS_ARCH_INTEL only) public const int CS_MODE_BIG_ENDIAN = 1 << 31; private UInt64 handle; [DllImport("capstone.so",CallingConvention=CallingConvention.Cdecl)] private static extern bool cs_open(int arch, int mode, ref UInt64 handle); [DllImport("capstone.so",CallingConvention=CallingConvention.Cdecl)] private static extern bool cs_close(UInt64 handle); [DllImport("capstone.so",CallingConvention=CallingConvention.Cdecl)] private static extern UInt64 cs_disasm_dyn(UInt64 handle, byte[] code, UInt64 code_len, UInt64 offset, UInt64 count, ref IntPtr insn); [DllImport("capstone.so",CallingConvention=CallingConvention.Cdecl)] private static extern bool cs_free(IntPtr insn); public Capstone(int arch, int mode) { cs_open(arch, mode, ref handle); } ~Capstone() { cs_close(handle); } public cs_insn[] disasm(byte[] code, UInt64 addr, UInt64 count) { IntPtr ptr = IntPtr.Zero; UInt64 c = cs_disasm_dyn(handle, code, (UInt64)code.Length, addr, count, ref ptr); if (c > 0) { UInt64 j; //UInt64 size = (UInt64)Marshal.SizeOf(typeof(_cs_insn)); UInt64 size = 1728; cs_insn[] insns = new cs_insn[c]; for (j = 0; j < c; j++) { IntPtr data = new IntPtr(ptr.ToInt64() + (Int64)(size * j)); _cs_insn _insn = (_cs_insn)Marshal.PtrToStructure(data, typeof(_cs_insn)); insns[j].id = _insn.id; insns[j].address = _insn.address; insns[j].size = _insn.size; insns[j].mnemonic = new string(_insn.mnemonic); insns[j].operands = new string(_insn.operands); //insns[j].regs_read = new int[insns[j].regs_read.Length]; //Array.Copy(_insn.regs_read, 0, insns[j].regs_read, 0, insns[j].regs_read.Length); //insns[j].regs_write = new int[insns[j].regs_write.Length]; //Array.Copy(_insn.regs_write, 0, insns[j].regs_write, 0, insns[j].regs_write.Length); //insns[j].groups = new int[insns[j].groups.Length]; //Array.Copy(_insn.groups, 0, insns[j].groups, 0, insns[j].groups.Length); } cs_free(ptr); return insns; } else return new cs_insn[0]; } }