// Capstone Java binding // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 package capstone; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLong; 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; } 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 byte[] regs_read = new byte[12]; public byte regs_read_count; // list of all implicit registers being written. public byte[] regs_write = new byte[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; // 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 byte[] regsRead; // list of all implicit registers being written. public byte[] 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); } cs = _cs; arch = _arch; raw = insn; csh = _csh; if (insn.cs_detail != null) { if (!diet) { regsRead = new byte[insn.cs_detail.regs_read_count]; for (int i=0; i