diff --git a/bindings/java/Arm.java b/bindings/java/Arm.java index 0b23288c0f..c8276a4f4c 100644 --- a/bindings/java/Arm.java +++ b/bindings/java/Arm.java @@ -63,32 +63,22 @@ public List getFieldOrder() { } } - public static class OpValue extends Union implements Union.ByReference { + public static class OpValue extends Union { public int reg; public long imm; public double fp; public MemType mem; - public OpValue(Pointer p) { - super(p); - read(); - } - @Override public List getFieldOrder() { return Arrays.asList("reg", "imm", "fp", "mem"); } } - public static class OpShift extends Structure implements Structure.ByReference { + public static class OpShift extends Structure { public int type; public int value; - public OpShift(Pointer p) { - super(p); - read(); - } - @Override public List getFieldOrder() { return Arrays.asList("type","value"); @@ -100,38 +90,53 @@ public static class Operand extends Structure { public int type; public OpValue value; + public void read() { + super.read(); + if (type == ARM_OP_MEM) + value.setType(MemType.class); + if (type == ARM_OP_FP) + value.setType(Double.TYPE); + if (type == ARM_OP_PIMM || type == ARM_OP_IMM || type == ARM_OP_CIMM) + value.setType(Long.TYPE); + if (type == ARM_OP_REG) + value.setType(Integer.TYPE); + readField("value"); + } + @Override public List getFieldOrder() { return Arrays.asList("shift", "type", "value"); } } - public static class OpInfo extends Capstone.OpInfo { + public static class UnionOpInfo extends Structure { + public int cc; + public byte _update_flags; + public byte _writeback; + public byte op_count; - public Operand [] op; + public Operand [] op = new Operand[32]; - public OpInfo(Pointer p) { - cc = p.getInt(0); - update_flags = (boolean) (p.getByte(4) > 0); - writeback = (boolean) (p.getByte(5) > 0); - int op_count = p.getShort(6); - if (op_count == 0) { - op = null; - return; - } + @Override + public List getFieldOrder() { + return Arrays.asList("cc", "_update_flags", "_writeback", "op_count", "op"); + } + } + + public static class OpInfo extends Capstone.OpInfo { + public int cc; + public boolean update_flags; + public boolean writeback; + public Operand [] op = null; - op = new Operand[op_count]; - for (int i=0; i 0); + writeback = (op_info._writeback > 0); + if (op_info.op_count == 0) return; + op = new Operand[op_info.op_count]; + for (int i=0; i 0); - writeback = (boolean) (p.getByte(5) > 0); - int op_count = p.getShort(6); - if (op_count == 0) { - op = null; - return; - } + public Operand [] op = new Operand[32]; + public void read() { + readField("cc"); + readField("_update_flags"); + readField("_writeback"); + readField("op_count"); op = new Operand[op_count]; - for (int i=0; i 0); + writeback = (op_info._writeback > 0); + if (op_info.op_count == 0) return; + op = op_info.op; } } diff --git a/bindings/java/CS.java b/bindings/java/CS.java index 9bcc8f7428..53981aa665 100644 --- a/bindings/java/CS.java +++ b/bindings/java/CS.java @@ -18,92 +18,109 @@ class Capstone { public int arch; public int mode; - public static class OpInfo { - public int cc; - public boolean update_flags; - public boolean writeback; + public static abstract class OpInfo { } - public class cs_insn { - /* - == total size: 1728 - @id: 0 - @address: 8 - @size: 16 - @mnemonic: 18 - @operands: 50 - @regs_read: 148 - @regs_write: 276 - @groups: 404 - @arch: 440 - */ + 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 String mnemonic; - public String operands; - public int[] regs_read; - public int[] regs_write; - public int[] groups; + 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 OpInfo 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"); + } + } - Pointer ptr_cs_ins; - long handleval; + 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(handleval, ptr_cs_ins, type); + return cs.cs_op_count(csh, ptr_origin, type); } public int op_index(int type, int index) { - return cs.cs_op_index(handleval, ptr_cs_ins, type, index); + return cs.cs_op_index(csh, ptr_origin, type, index); } - } - private cs_insn fromPointer(Pointer pointer) { - cs_insn insn = new cs_insn(); - - insn.id = pointer.getInt(0); - - insn.address = pointer.getLong(8); - - insn.size = pointer.getShort(16); - - insn.mnemonic = pointer.getString(18); - - insn.operands = pointer.getString(50); - - insn.regs_read = pointer.getIntArray(148, 32); - - insn.regs_write = pointer.getIntArray(276, 32); - - insn.groups = pointer.getIntArray(404, 8); + 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 = new Arm.OpInfo(pointer.share(440)); + 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 = new Arm64.OpInfo(pointer.share(440)); + 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 = new Mips.OpInfo(pointer.share(440)); + 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 = new X86.OpInfo(pointer.share(440)); + insn._op_info.setType(X86.UnionOpInfo.class); + insn.read(); + op_info = new X86.OpInfo(insn._op_info.x86); break; default: - insn.op_info = null; } - - insn.ptr_cs_ins = pointer; - insn.handleval = handle.getValue(); - - return insn; + return new cs_insn(insn, pointer, csh, cs, op_info); } - private cs_insn[] fromArrayPointer(Pointer pointer, int numberResults) { + private cs_insn[] fromArrayPointer(Pointer pointer, int numberResults) + { cs_insn[] arr = new cs_insn[numberResults]; int offset = 0; @@ -120,7 +137,7 @@ private interface CS extends Library { 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 boolean cs_close(long handle); + 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); @@ -150,7 +167,7 @@ public long cs_disasm_dyn(long handle, byte[] code, long code_len, public static final int CS_ERR_MODE = 5; // Invalid/unsupported mode - private LongByReference handle; + private long csh; private PointerByReference insnRef; private CS cs; @@ -159,28 +176,32 @@ public long cs_disasm_dyn(long handle, byte[] code, long code_len, this.arch = arch; this.mode = mode; cs = (CS)Native.loadLibrary("capstone", CS.class); - handle = new LongByReference(); - if (cs.cs_open(arch, mode, handle) != CS_ERR_OK) { + 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(handle.getValue(), reg); + return cs.cs_reg_name(csh, reg); } - protected void finalize() { - cs.cs_close(handle.getValue()); + protected void finalize() + { + cs.cs_close(csh); } - cs_insn[] disasm(byte[] code, long address) { + cs_insn[] disasm(byte[] code, long address) + { return disasm(code, address, 0); } - cs_insn[] disasm(byte[] code, long address, long count) { + cs_insn[] disasm(byte[] code, long address, long count) + { insnRef = new PointerByReference(); - long c = cs.cs_disasm_dyn(handle.getValue(), code, code.length, address, count, insnRef); + 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); diff --git a/bindings/java/Mips.java b/bindings/java/Mips.java index fe33cce8aa..517dbe628e 100644 --- a/bindings/java/Mips.java +++ b/bindings/java/Mips.java @@ -27,16 +27,11 @@ public List getFieldOrder() { } } - public static class OpValue extends Union implements Union.ByReference { + public static class OpValue extends Union { public int reg; public long imm; public MemType mem; - public OpValue(Pointer p) { - super(p); - read(); - } - @Override public List getFieldOrder() { return Arrays.asList("reg", "imm", "mem"); @@ -47,34 +42,50 @@ public static class Operand extends Structure { public int type; public OpValue value; + public void read() { + super.read(); + if (type == MIPS_OP_MEM) + value.setType(MemType.class); + if (type == MIPS_OP_IMM) + value.setType(Long.TYPE); + if (type == MIPS_OP_REG) + value.setType(Integer.TYPE); + if (type == MIPS_OP_INVALID) + return; + readField("value"); + } @Override public List getFieldOrder() { return Arrays.asList("type", "value"); } } + public static class UnionOpInfo extends Structure { + public short op_count; + public Operand [] op = new Operand[8]; + + public void read() { + readField("op_count"); + op = new Operand[op_count]; + readField("op"); + } + + @Override + public List getFieldOrder() { + return Arrays.asList("op_count", "op"); + } + } + public static class OpInfo extends Capstone.OpInfo { public Operand [] op; - public OpInfo(Pointer p) { - int op_count = p.getShort(0); - if (op_count == 0) { + public OpInfo(UnionOpInfo e) { + if (e.op_count == 0) { op = null; return; } - - op = new Operand[op_count]; - for (int i=0; i 0) { diff --git a/bindings/java/X86.java b/bindings/java/X86.java index 8c4d388d76..2120474275 100644 --- a/bindings/java/X86.java +++ b/bindings/java/X86.java @@ -30,17 +30,12 @@ public List getFieldOrder() { } } - public static class OpValue extends Union implements Union.ByReference { + public static class OpValue extends Union { public int reg; public long imm; public double fp; public MemType mem; - public OpValue(Pointer p) { - super(p); - read(); - } - @Override public List getFieldOrder() { return Arrays.asList("reg", "imm", "fp", "mem"); @@ -51,16 +46,31 @@ public static class Operand extends Structure { public int type; public OpValue value; + public void read() { + super.read(); + if (type == X86_OP_MEM) + value.setType(MemType.class); + if (type == X86_OP_FP) + value.setType(Double.TYPE); + if (type == X86_OP_IMM) + value.setType(Long.TYPE); + if (type == X86_OP_REG) + value.setType(Integer.TYPE); + if (type == X86_OP_INVALID) + return; + readField("value"); + } + @Override public List getFieldOrder() { - return Arrays.asList("shift", "type", "value"); + return Arrays.asList("type", "value"); } } - public static class X86extra extends Structure implements Structure.ByReference { - public byte [] prefix; + public static class UnionOpInfo extends Structure { + public byte [] prefix = new byte[5]; public int segment; - public byte [] opcode; + public byte [] opcode = new byte[3]; public byte op_size; public byte addr_size; public byte disp_size; @@ -72,38 +82,18 @@ public static class X86extra extends Structure implements Structure.ByReference public byte sib_scale; public int sib_base; - public X86extra(Pointer p) { - super (p); - prefix = new byte[5]; - opcode = new byte[3]; - read(); - } + public int op_count; + + public Operand [] op = new Operand[8]; @Override public List getFieldOrder() { - return Arrays.asList("prefix", "segment", "opcode", "op_size", "addr_size", "disp_size", "imm_size", "modrm", "sib", "disp", "sib_index", "sib_scale", "sib_base"); + return Arrays.asList("prefix", "segment", "opcode", "op_size", "addr_size", "disp_size", + "imm_size", "modrm", "sib", "disp", "sib_index", "sib_scale", "sib_base", "op_count", "op"); } - /* 15 + 4*8 - ('prefix', ctypes.c_uint8 * 5), - ('segment', ctypes.c_uint), - ('opcode', ctypes.c_uint8 * 3), - ('op_size', ctypes.c_uint8), - ('addr_size', ctypes.c_uint8), - ('disp_size', ctypes.c_uint8), - ('imm_size', ctypes.c_uint8), - ('modrm', ctypes.c_uint8), - ('sib', ctypes.c_uint8), - ('disp', ctypes.c_int32), - ('sib_index', ctypes.c_uint), - ('sib_scale', ctypes.c_int8), - ('sib_base', ctypes.c_uint), - */ } public static class OpInfo extends Capstone.OpInfo { - public X86extra e; - public Operand [] op; - public byte [] prefix; public int segment; public byte [] opcode; @@ -118,10 +108,9 @@ public static class OpInfo extends Capstone.OpInfo { public byte sib_scale; public int sib_base; + Operand[] op; - private void copyextra() { - // FIXME: we need to manually copy like this since we want to use JNA constructor - // still better than having a fixed offset + public OpInfo(UnionOpInfo e) { prefix = e.prefix; segment = e.segment; opcode = e.opcode; @@ -135,29 +124,13 @@ private void copyextra() { sib_index = e.sib_index; sib_scale = e.sib_scale; sib_base = e.sib_base; - } - - public OpInfo(Pointer p) { - e = new X86extra(p); - copyextra(); - - int op_count = p.getByte(e.size()); - if (op_count == 0) { + if (e.op_count == 0) { op = null; return; } - - op = new Operand[op_count]; - for (int i=0; i