// Capstone Java binding
// By Nguyen Anh Quynh & Dang Hoang Vu,  2013

package capstone;

import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.NativeLongByReference;
import com.sun.jna.Structure;
import com.sun.jna.Union;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.ptr.IntByReference;

import java.util.List;
import java.util.Arrays;
import java.lang.RuntimeException;

public class Capstone {

  protected static abstract class OpInfo {};
  protected static abstract class UnionOpInfo extends Structure {};

  public static class UnionArch extends Union {
    public static class ByValue extends UnionArch implements Union.ByValue {};

    public Arm.UnionOpInfo arm;
    public Arm64.UnionOpInfo arm64;
    public X86.UnionOpInfo x86;
    public Mips.UnionOpInfo mips;
    public Ppc.UnionOpInfo ppc;
    public Sparc.UnionOpInfo sparc;
    public Systemz.UnionOpInfo sysz;
    public Xcore.UnionOpInfo xcore;
    public M680x.UnionOpInfo m680x;
  }

  protected static class _cs_insn extends Structure {
    // instruction ID.
    public int id;
    // instruction address.
    public long address;
    // instruction size.
    public short size;
    // machine bytes of instruction.
    public byte[] bytes;
    // instruction mnemonic. NOTE: irrelevant for diet engine.
    public byte[] mnemonic;
    // instruction operands. NOTE: irrelevant for diet engine.
    public byte[] op_str;
    // detail information of instruction.
    public _cs_detail.ByReference cs_detail;

    public _cs_insn() {
      bytes = new byte[16];
      mnemonic = new byte[32];
      op_str = new byte[160];
      java.util.Arrays.fill(mnemonic, (byte) 0);
      java.util.Arrays.fill(op_str, (byte) 0);
    }

    public _cs_insn(Pointer p) {
      this();
      useMemory(p);
      read();
    }

    @Override
    public List getFieldOrder() {
      return Arrays.asList("id", "address", "size", "bytes", "mnemonic", "op_str", "cs_detail");
    }
  }

  protected static class _cs_detail extends Structure {
    public static class ByReference extends _cs_detail implements Structure.ByReference {};

    // list of all implicit registers being read.
    public short[] regs_read = new short[12];
    public byte regs_read_count;
    // list of all implicit registers being written.
    public short[] regs_write = new short[20];
    public byte regs_write_count;
    // list of semantic groups this instruction belongs to.
    public byte[] groups = new byte[8];
    public byte groups_count;

    public UnionArch arch;

    @Override
    public List getFieldOrder() {
      return Arrays.asList("regs_read", "regs_read_count", "regs_write", "regs_write_count", "groups", "groups_count", "arch");
    }
  }

  public static class CsInsn {
    private NativeLong csh;
    private CS cs;
    private _cs_insn raw;
    private int arch;

    // instruction ID.
    public int id;
    // instruction address.
    public long address;
    // instruction size.
    public short size;
    // Machine bytes of this instruction, with number of bytes indicated by size above
    public byte[] bytes;
    // instruction mnemonic. NOTE: irrelevant for diet engine.
    public String mnemonic;
    // instruction operands. NOTE: irrelevant for diet engine.
    public String opStr;
    // list of all implicit registers being read.
    public short[] regsRead;
    // list of all implicit registers being written.
    public short[] regsWrite;
    // list of semantic groups this instruction belongs to.
    public byte[] groups;
    public OpInfo operands;

    public CsInsn (_cs_insn insn, int _arch, NativeLong _csh, CS _cs, boolean diet) {
      id = insn.id;
      address = insn.address;
      size = insn.size;

      if (!diet) {
        int lm = 0;
        while (insn.mnemonic[lm++] != 0);
        int lo = 0;
        while (insn.op_str[lo++] != 0);
        mnemonic = new String(insn.mnemonic, 0, lm-1);
        opStr = new String(insn.op_str, 0, lo-1);
        bytes = Arrays.copyOf(insn.bytes, insn.size);
      }

      cs = _cs;
      arch = _arch;
      raw = insn;
      csh = _csh;

      if (insn.cs_detail != null) {
        if (!diet) {
          regsRead = new short[insn.cs_detail.regs_read_count];
          for (int i=0; i<regsRead.length; i++)
            regsRead[i] = insn.cs_detail.regs_read[i];
          regsWrite = new short[insn.cs_detail.regs_write_count];
          for (int i=0; i<regsWrite.length; i++)
            regsWrite[i] = insn.cs_detail.regs_write[i];
          groups = new byte[insn.cs_detail.groups_count];
          for (int i=0; i<groups.length; i++)
            groups[i] = insn.cs_detail.groups[i];
        }

        operands = getOptInfo(insn.cs_detail);
      }
    }

    private OpInfo getOptInfo(_cs_detail detail) {
      OpInfo op_info = null;

      switch (this.arch) {
        case CS_ARCH_ARM:
          detail.arch.setType(Arm.UnionOpInfo.class);
          detail.arch.read();
          op_info = new Arm.OpInfo((Arm.UnionOpInfo) detail.arch.arm);
          break;
        case CS_ARCH_ARM64:
          detail.arch.setType(Arm64.UnionOpInfo.class);
          detail.arch.read();
          op_info = new Arm64.OpInfo((Arm64.UnionOpInfo) detail.arch.arm64);
          break;
        case CS_ARCH_MIPS:
          detail.arch.setType(Mips.UnionOpInfo.class);
          detail.arch.read();
          op_info = new Mips.OpInfo((Mips.UnionOpInfo) detail.arch.mips);
          break;
        case CS_ARCH_X86:
          detail.arch.setType(X86.UnionOpInfo.class);
          detail.arch.read();
          op_info = new X86.OpInfo((X86.UnionOpInfo) detail.arch.x86);
          break;
        case CS_ARCH_SPARC:
          detail.arch.setType(Sparc.UnionOpInfo.class);
          detail.arch.read();
          op_info = new Sparc.OpInfo((Sparc.UnionOpInfo) detail.arch.sparc);
          break;
        case CS_ARCH_SYSZ:
          detail.arch.setType(Systemz.UnionOpInfo.class);
          detail.arch.read();
          op_info = new Systemz.OpInfo((Systemz.UnionOpInfo) detail.arch.sysz);
          break;
        case CS_ARCH_PPC:
          detail.arch.setType(Ppc.UnionOpInfo.class);
          detail.arch.read();
          op_info = new Ppc.OpInfo((Ppc.UnionOpInfo) detail.arch.ppc);
          break;
        case CS_ARCH_XCORE:
          detail.arch.setType(Xcore.UnionOpInfo.class);
          detail.arch.read();
          op_info = new Xcore.OpInfo((Xcore.UnionOpInfo) detail.arch.xcore);
          break;
        case CS_ARCH_M680X:
          detail.arch.setType(M680x.UnionOpInfo.class);
          detail.arch.read();
          op_info = new M680x.OpInfo((M680x.UnionOpInfo) detail.arch.m680x);
          break;
        default:
      }

      return op_info;
    }

    public int opCount(int type) {
      return cs.cs_op_count(csh, raw.getPointer(), type);
    }

    public int opIndex(int type, int index) {
      return cs.cs_op_index(csh, raw.getPointer(), type, index);
    }

    public boolean regRead(int reg_id) {
      return cs.cs_reg_read(csh, raw.getPointer(), reg_id) != 0;
    }

    public boolean regWrite(int reg_id) {
      return cs.cs_reg_write(csh, raw.getPointer(), reg_id) != 0;
    }

    public int errno() {
      return cs.cs_errno(csh);
    }

    public String regName(int reg_id) {
      return cs.cs_reg_name(csh, reg_id);
    }

    public String insnName() {
      return cs.cs_insn_name(csh, id);
    }

    public String groupName(int id) {
      return cs.cs_group_name(csh, id);
    }

    public boolean group(int gid) {
      return cs.cs_insn_group(csh, raw.getPointer(), gid) != 0;
    }

    public CsRegsAccess regsAccess() {
      Memory regsReadMemory = new Memory(64*2);
      ByteByReference regsReadCountRef = new ByteByReference();
      Memory regsWriteMemory = new Memory(64*2);
      ByteByReference regsWriteCountRef = new ByteByReference();

      int c = cs.cs_regs_access(csh, raw.getPointer(), regsReadMemory, regsReadCountRef, regsWriteMemory, regsWriteCountRef);
      if (c != CS_ERR_OK) {
        return null;
      }

      byte regsReadCount = regsReadCountRef.getValue();
      byte regsWriteCount = regsWriteCountRef.getValue();

      short[] regsRead = new short[regsReadCount];
      regsReadMemory.read(0, regsRead, 0, regsReadCount);

      short[] regsWrite = new short[regsWriteCount];
      regsWriteMemory.read(0, regsWrite, 0, regsWriteCount);

      return new CsRegsAccess(regsRead, regsWrite);
    }
  }

  public static class CsRegsAccess {
    public short[] regsRead;
    public short[] regsWrite;

    public CsRegsAccess(short[] regsRead, short[] regsWrite) {
      this.regsRead = regsRead;
      this.regsWrite = regsWrite;
    }
  }

  private CsInsn[] fromArrayRaw(_cs_insn[] arr_raw) {
    CsInsn[] arr = new CsInsn[arr_raw.length];

    for (int i = 0; i < arr_raw.length; i++) {
      arr[i] = new CsInsn(arr_raw[i], this.arch, ns.csh, cs, this.diet);
    }

    return arr;
  }

  private interface CS extends Library {
    public int cs_open(int arch, int mode, NativeLongByReference handle);
    public NativeLong cs_disasm(NativeLong handle, byte[] code, NativeLong code_len,
        long addr, NativeLong count, PointerByReference insn);
    public void cs_free(Pointer p, NativeLong count);
    public int cs_close(NativeLongByReference handle);
    public int cs_option(NativeLong handle, int option, NativeLong optionValue);

    public String cs_reg_name(NativeLong csh, int id);
    public int cs_op_count(NativeLong csh, Pointer insn, int type);
    public int cs_op_index(NativeLong csh, Pointer insn, int type, int index);

    public String cs_insn_name(NativeLong csh, int id);
    public String cs_group_name(NativeLong csh, int id);
    public byte cs_insn_group(NativeLong csh, Pointer insn, int id);
    public byte cs_reg_read(NativeLong csh, Pointer insn, int id);
    public byte cs_reg_write(NativeLong csh, Pointer insn, int id);
    public int cs_errno(NativeLong csh);
    public int cs_version(IntByReference major, IntByReference minor);
    public boolean cs_support(int query);
    public String cs_strerror(int code);
    public int cs_regs_access(NativeLong handle, Pointer insn, Pointer regs_read, ByteByReference regs_read_count, Pointer regs_write, ByteByReference regs_write_count);
  }

  // Capstone API version
  public static final int CS_API_MAJOR = 4;
  public static final int CS_API_MINOR = 0;

  // architectures
  public static final int CS_ARCH_ARM = 0;
  public static final int CS_ARCH_ARM64 = 1;
  public static final int CS_ARCH_MIPS = 2;
  public static final int CS_ARCH_X86 = 3;
  public static final int CS_ARCH_PPC = 4;
  public static final int CS_ARCH_SPARC = 5;
  public static final int CS_ARCH_SYSZ = 6;
  public static final int CS_ARCH_XCORE = 7;
  public static final int CS_ARCH_M68K = 8;
  public static final int CS_ARCH_TMS320C64X = 9;
  public static final int CS_ARCH_M680X = 10;
  public static final int CS_ARCH_MAX = 11;
  public static final int CS_ARCH_ALL = 0xFFFF; // query id for cs_support()

  // disasm mode
  public static final int CS_MODE_LITTLE_ENDIAN = 0;  // little-endian mode (default mode)
  public static final int CS_MODE_ARM = 0;	          // 32-bit ARM
  public static final int CS_MODE_16 = 1 << 1;		// 16-bit mode for X86
  public static final int CS_MODE_32 = 1 << 2;		// 32-bit mode for X86
  public static final int CS_MODE_64 = 1 << 3;		// 64-bit mode for X86, PPC
  public static final int CS_MODE_THUMB = 1 << 4;	  // ARM's Thumb mode, including Thumb-2
  public static final int CS_MODE_MCLASS = 1 << 5;	  // ARM's Cortex-M series
  public static final int CS_MODE_V8 = 1 << 6;	      // ARMv8 A32 encodings for ARM
  public static final int CS_MODE_MICRO = 1 << 4;	  // MicroMips mode (Mips arch)
  public static final int CS_MODE_MIPS3 = 1 << 5;     // Mips III ISA
  public static final int CS_MODE_MIPS32R6 = 1 << 6;  // Mips32r6 ISA
  public static final int CS_MODE_MIPS2 = 1 << 7;  // Mips II ISA
  public static final int CS_MODE_BIG_ENDIAN = 1 << 31; // big-endian mode
  public static final int CS_MODE_V9 = 1 << 4;	      // SparcV9 mode (Sparc arch)
  public static final int CS_MODE_MIPS32 = CS_MODE_32; // Mips32 ISA
  public static final int CS_MODE_MIPS64 = CS_MODE_64; // Mips64 ISA
  public static final int CS_MODE_QPX = 1 << 4; // Quad Processing eXtensions mode (PPC)
  public static final int CS_MODE_M680X_6301 = 1 << 1; // M680X Hitachi 6301,6303 mode
  public static final int CS_MODE_M680X_6309 = 1 << 2; // M680X Hitachi 6309 mode
  public static final int CS_MODE_M680X_6800 = 1 << 3; // M680X Motorola 6800,6802 mode
  public static final int CS_MODE_M680X_6801 = 1 << 4; // M680X Motorola 6801,6803 mode
  public static final int CS_MODE_M680X_6805 = 1 << 5; // M680X Motorola 6805 mode
  public static final int CS_MODE_M680X_6808 = 1 << 6; // M680X Motorola 6808 mode
  public static final int CS_MODE_M680X_6809 = 1 << 7; // M680X Motorola 6809 mode
  public static final int CS_MODE_M680X_6811 = 1 << 8; // M680X Motorola/Freescale 68HC11 mode
  public static final int CS_MODE_M680X_CPU12 = 1 << 9; // M680X Motorola/Freescale/NXP CPU12 mode
  public static final int CS_MODE_M680X_HCS08 = 1 << 10; // M680X Freescale HCS08 mode

  // Capstone error
  public static final int CS_ERR_OK = 0;
  public static final int CS_ERR_MEM = 1;	    // Out-Of-Memory error
  public static final int CS_ERR_ARCH = 2;	  // Unsupported architecture
  public static final int CS_ERR_HANDLE = 3;	// Invalid handle
  public static final int CS_ERR_CSH = 4;	    // Invalid csh argument
  public static final int CS_ERR_MODE = 5;	  // Invalid/unsupported mode
  public static final int CS_ERR_OPTION = 6;  // Invalid/unsupported option: cs_option()
  public static final int CS_ERR_DETAIL = 7;  // Invalid/unsupported option: cs_option()
  public static final int CS_ERR_MEMSETUP = 8;
  public static final int CS_ERR_VERSION = 9;  //Unsupported version (bindings)
  public static final int CS_ERR_DIET = 10;  //Information irrelevant in diet engine
  public static final int CS_ERR_SKIPDATA = 11;  //Access irrelevant data for "data" instruction in SKIPDATA mode
  public static final int CS_ERR_X86_ATT = 12;  //X86 AT&T syntax is unsupported (opt-out at compile time)
  public static final int CS_ERR_X86_INTEL = 13;  //X86 Intel syntax is unsupported (opt-out at compile time)

  // Capstone option type
  public static final int CS_OPT_SYNTAX = 1;  // Intel X86 asm syntax (CS_ARCH_X86 arch)
  public static final int CS_OPT_DETAIL = 2;  // Break down instruction structure into details
  public static final int CS_OPT_MODE = 3;  // Change engine's mode at run-time

  // Capstone option value
  public static final int CS_OPT_OFF = 0;  // Turn OFF an option - default option of CS_OPT_DETAIL
  public static final int CS_OPT_SYNTAX_INTEL = 1;  // Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX,  CS_ARCH_X86)
  public static final int CS_OPT_SYNTAX_ATT = 2;    // ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86)
  public static final int CS_OPT_ON = 3;  // Turn ON an option (CS_OPT_DETAIL)
  public static final int CS_OPT_SYNTAX_NOREGNAME = 3; // PPC asm syntax: Prints register name with only number (CS_OPT_SYNTAX)

  // Common instruction operand types - to be consistent across all architectures.
  public static final int CS_OP_INVALID = 0;
  public static final int CS_OP_REG = 1;
  public static final int CS_OP_IMM = 2;
  public static final int CS_OP_MEM = 3;
  public static final int CS_OP_FP  = 4;

  // Common instruction operand access types - to be consistent across all architectures.
  // It is possible to combine access types, for example: CS_AC_READ | CS_AC_WRITE
  public static final int CS_AC_INVALID = 0;
  public static final int CS_AC_READ = 1 << 0;
  public static final int CS_AC_WRITE = 1 << 1;

  // Common instruction groups - to be consistent across all architectures.
  public static final int CS_GRP_INVALID = 0;  // uninitialized/invalid group.
  public static final int CS_GRP_JUMP    = 1;  // all jump instructions (conditional+direct+indirect jumps)
  public static final int CS_GRP_CALL    = 2;  // all call instructions
  public static final int CS_GRP_RET     = 3;  // all return instructions
  public static final int CS_GRP_INT     = 4;  // all interrupt instructions (int+syscall)
  public static final int CS_GRP_IRET    = 5;  // all interrupt return instructions
  public static final int CS_GRP_PRIVILEGE = 6;  // all privileged instructions

  // Query id for cs_support()
  public static final int CS_SUPPORT_DIET = CS_ARCH_ALL+1;	  // diet mode
  public static final int CS_SUPPORT_X86_REDUCE = CS_ARCH_ALL+2;  // X86 reduce mode

  protected class NativeStruct {
      private NativeLong csh;
      private NativeLongByReference handleRef;
  }

  private static final CsInsn[] EMPTY_INSN = new CsInsn[0];

  protected NativeStruct ns; // for memory retention
  private CS cs;
  public int arch;
  public int mode;
  private int syntax;
  private int detail;
  private boolean diet;

  public Capstone(int arch, int mode) {
    cs = (CS)Native.loadLibrary("capstone", CS.class);
    int version = cs.cs_version(null, null);
    if (version != (CS_API_MAJOR << 8) + CS_API_MINOR) {
      throw new RuntimeException("Different API version between core & binding (CS_ERR_VERSION)");
    }

    this.arch = arch;
    this.mode = mode;
    ns = new NativeStruct();
    ns.handleRef = new NativeLongByReference();
    if (cs.cs_open(arch, mode, ns.handleRef) != CS_ERR_OK) {
      throw new RuntimeException("ERROR: Wrong arch or mode");
    }
    ns.csh = ns.handleRef.getValue();
    this.detail = CS_OPT_OFF;
	this.diet = cs.cs_support(CS_SUPPORT_DIET);
  }

  // return combined API version
  public int version() {
    return cs.cs_version(null, null);
  }

  // set Assembly syntax
  public void setSyntax(int syntax) {
    if (cs.cs_option(ns.csh, CS_OPT_SYNTAX, new NativeLong(syntax)) == CS_ERR_OK) {
      this.syntax = syntax;
    } else {
      throw new RuntimeException("ERROR: Failed to set assembly syntax");
    }
  }

  // set detail option at run-time
  public void setDetail(int opt) {
    if (cs.cs_option(ns.csh, CS_OPT_DETAIL, new NativeLong(opt)) == CS_ERR_OK) {
      this.detail = opt;
    } else {
      throw new RuntimeException("ERROR: Failed to set detail option");
    }
  }

  // set mode option at run-time
  public void setMode(int opt) {
    if (cs.cs_option(ns.csh, CS_OPT_MODE, new NativeLong(opt)) == CS_ERR_OK) {
      this.mode = opt;
    } else {
      throw new RuntimeException("ERROR: Failed to set mode option");
    }
  }

  // destructor automatically caled at destroyed time.
  protected void finalize() {
    // FIXME: crashed on Ubuntu 14.04 64bit, OpenJDK java 1.6.0_33
    // cs.cs_close(ns.handleRef);
  }

  // destructor automatically caled at destroyed time.
  public int close() {
    return cs.cs_close(ns.handleRef);
  }

  /**
   * Disassemble instructions from @code assumed to be located at @address,
   * stop when encountering first broken instruction.
   * 
   * @param code The source machine code bytes.
   * @param address The address of the first machine code byte.
   * @return the array of successfully disassembled instructions, empty if no instruction could be disassembled.
   */
  public CsInsn[] disasm(byte[] code, long address) {
    return disasm(code, address, 0);
  }

  /**
   * Disassemble up to @count instructions from @code assumed to be located at @address,
   * stop when encountering first broken instruction.
   * 
   * @param code The source machine code bytes.
   * @param address The address of the first machine code byte.
   * @param count The maximum number of instructions to disassemble, 0 for no maximum.
   * @return the array of successfully disassembled instructions, empty if no instruction could be disassembled.
   */
  public CsInsn[] disasm(byte[] code, long address, long count) {
    PointerByReference insnRef = new PointerByReference();

    NativeLong c = cs.cs_disasm(ns.csh, code, new NativeLong(code.length), address, new NativeLong(count), insnRef);
    
    if (0 == c.intValue()) {
    	return EMPTY_INSN;
    }
    
    Pointer p = insnRef.getValue();
    _cs_insn byref = new _cs_insn(p);

    CsInsn[] allInsn = fromArrayRaw((_cs_insn[]) byref.toArray(c.intValue()));

    // free allocated memory
    // cs.cs_free(p, c);
    // FIXME(danghvu): Can't free because memory is still inside CsInsn

    return allInsn;
  }

  public String strerror(int code) {
    return cs.cs_strerror(code);
  }
}
