capstone/bindings/java/CS.java

212 lines
6.1 KiB
Java

// Capstone Java binding
// By Nguyen Anh Quynh & Dang Hoang Vu, 2013
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.Union;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;
import java.util.List;
import java.util.Arrays;
import java.lang.RuntimeException;
class Capstone {
public int arch;
public int mode;
public static abstract class OpInfo {
}
public static class PrivateOpInfo extends Union {
public X86.UnionOpInfo x86;
public Arm64.UnionOpInfo arm64;
public Arm.UnionOpInfo arm;
public Mips.UnionOpInfo mips;
}
public static class _cs_insn extends Structure implements Structure.ByReference {
public int id;
public long address;
public short size;
public byte[] mnemonic = new byte[32];
public byte[] operands = new byte[96];
public int[] regs_read = new int[32];
public int[] regs_write = new int[32];
public int[] groups = new int[8];
public PrivateOpInfo _op_info;
public _cs_insn(Pointer p) { super(p); }
@Override
public List getFieldOrder() {
return Arrays.asList("id", "address", "size", "mnemonic", "operands", "regs_read", "regs_write", "groups", "_op_info");
}
}
public static class cs_insn {
OpInfo op_info;
Pointer ptr_origin;
long csh;
CS cs;
int id;
long address;
short size;
String mnemonic;
String operands;
int[] regs_read;
int[] regs_write;
int[] groups;
public cs_insn (_cs_insn struct, Pointer _ptr_origin, long _csh, CS _cs, OpInfo _op_info) {
id = struct.id;
address = struct.address;
size = struct.size;
mnemonic = new String(struct.mnemonic).replace("\u0000","");
operands = new String(struct.operands).replace("\u0000","");
regs_read = struct.regs_read;
regs_write = struct.regs_write;
groups = struct.groups;
ptr_origin = _ptr_origin;
op_info = _op_info;
csh = _csh;
cs = _cs;
}
public int op_count(int type) {
return cs.cs_op_count(csh, ptr_origin, type);
}
public int op_index(int type, int index) {
return cs.cs_op_index(csh, ptr_origin, type, index);
}
}
private cs_insn fromPointer(Pointer pointer)
{
_cs_insn insn = new _cs_insn(pointer);
OpInfo op_info = null;
switch (this.arch) {
case CS_ARCH_ARM:
insn._op_info.setType(Arm.UnionOpInfo.class);
insn.read();
op_info = new Arm.OpInfo(insn._op_info.arm);
break;
case CS_ARCH_ARM64:
insn._op_info.setType(Arm64.UnionOpInfo.class);
insn.read();
op_info = new Arm64.OpInfo(insn._op_info.arm64);
break;
case CS_ARCH_MIPS:
insn._op_info.setType(Mips.UnionOpInfo.class);
insn.read();
op_info = new Mips.OpInfo(insn._op_info.mips);
break;
case CS_ARCH_X86:
insn._op_info.setType(X86.UnionOpInfo.class);
insn.read();
op_info = new X86.OpInfo(insn._op_info.x86);
break;
default:
}
return new cs_insn(insn, pointer, csh, cs, op_info);
}
private cs_insn[] fromArrayPointer(Pointer pointer, int numberResults)
{
cs_insn[] arr = new cs_insn[numberResults];
int offset = 0;
for (int i = 0; i < numberResults; i++) {
arr[i] = fromPointer(pointer.share(offset));
offset += 1728; // sizeof(cs_insn);
}
return arr;
}
private interface CS extends Library {
public int cs_open(int arch, int mode, LongByReference handle);
public long cs_disasm_dyn(long handle, byte[] code, long code_len,
long addr, long count, PointerByReference insn);
public void cs_free(Pointer p);
public int cs_close(long handle);
public String cs_reg_name(long csh, int id);
public int cs_op_count(long csh, Pointer insn, int type);
public int cs_op_index(long csh, Pointer insn, int type, int index);
}
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_MODE_LITTLE_ENDIAN = 0; // default mode
public static final int CS_MODE_SYNTAX_INTEL = 0; // default X86 asm syntax (applicable for CS_ARCH_INTEL only)
public static final int CS_MODE_ARM = 0; // 32-bit ARM
public static final int CS_MODE_16 = 1 << 1;
public static final int CS_MODE_32 = 1 << 2;
public static final int CS_MODE_64 = 1 << 3;
public static final int CS_MODE_THUMB = 1 << 4; // ARM's Thumb mode, including Thumb-2
public static final int CS_MODE_SYNTAX_ATT = 1 << 30; // X86 ATT asm syntax (applicable for CS_ARCH_INTEL only)
public static final int CS_MODE_BIG_ENDIAN = 1 << 31;
// 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
private long csh;
private PointerByReference insnRef;
private CS cs;
Capstone(int arch, int mode)
{
this.arch = arch;
this.mode = mode;
cs = (CS)Native.loadLibrary("capstone", CS.class);
LongByReference handleref = new LongByReference();
if (cs.cs_open(arch, mode, handleref) != CS_ERR_OK) {
throw new RuntimeException("ERROR: Wrong arch or mode");
}
csh = handleref.getValue();
}
public String reg_name(int reg) {
return cs.cs_reg_name(csh, reg);
}
protected void finalize()
{
cs.cs_close(csh);
}
cs_insn[] disasm(byte[] code, long address)
{
return disasm(code, address, 0);
}
cs_insn[] disasm(byte[] code, long address, long count)
{
insnRef = new PointerByReference();
long c = cs.cs_disasm_dyn(csh, code, code.length, address, count, insnRef);
Pointer p = insnRef.getValue();
cs_insn[] all_insn = fromArrayPointer(p, (int)c);
return all_insn;
}
}