106 lines
3.6 KiB
C#
106 lines
3.6 KiB
C#
/* Capstone Disassembler Engine */
|
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 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];
|
|
}
|
|
}
|