Merge pull request #55 from danghvu/master
Update Java binding for new API
This commit is contained in:
commit
c4792c21ba
|
@ -4,9 +4,7 @@
|
||||||
package capstone;
|
package capstone;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
import com.sun.jna.Pointer;
|
|
||||||
import com.sun.jna.Union;
|
import com.sun.jna.Union;
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -88,17 +86,6 @@ public class Arm {
|
||||||
op = new Operand[20];
|
op = new Operand[20];
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnionOpInfo(Pointer p){
|
|
||||||
op = new Operand[20];
|
|
||||||
useMemory(p);
|
|
||||||
read();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getSize() {
|
|
||||||
UnionOpInfo x = new UnionOpInfo();
|
|
||||||
return x.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void read() {
|
public void read() {
|
||||||
readField("cc");
|
readField("cc");
|
||||||
readField("_update_flags");
|
readField("_update_flags");
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
package capstone;
|
package capstone;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
import com.sun.jna.Pointer;
|
|
||||||
import com.sun.jna.Union;
|
import com.sun.jna.Union;
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -87,16 +85,6 @@ public class Arm64 {
|
||||||
op = new Operand[8];
|
op = new Operand[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnionOpInfo(Pointer p) {
|
|
||||||
op = new Operand[8];
|
|
||||||
useMemory(p);
|
|
||||||
read();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getSize() {
|
|
||||||
return (new UnionOpInfo()).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void read() {
|
public void read() {
|
||||||
readField("cc");
|
readField("cc");
|
||||||
readField("_update_flags");
|
readField("_update_flags");
|
||||||
|
|
|
@ -16,23 +16,19 @@ import com.sun.jna.ptr.IntByReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.lang.RuntimeException;
|
import java.lang.RuntimeException;
|
||||||
import java.lang.Math;
|
|
||||||
|
|
||||||
public class Capstone {
|
public class Capstone {
|
||||||
|
|
||||||
public int arch;
|
protected static abstract class OpInfo {};
|
||||||
public int mode;
|
protected static abstract class UnionOpInfo extends Structure {};
|
||||||
private int syntax;
|
|
||||||
private int detail;
|
|
||||||
|
|
||||||
protected static abstract class OpInfo {}
|
public static class UnionArch extends Union {
|
||||||
protected static abstract class UnionOpInfo extends Structure {}
|
public static class ByValue extends UnionArch implements Union.ByValue {};
|
||||||
|
|
||||||
protected static int max(int a, int b, int c, int d) {
|
public Arm.UnionOpInfo arm;
|
||||||
if (a<b) a = b;
|
public Arm64.UnionOpInfo arm64;
|
||||||
if (c<d) c = d;
|
public X86.UnionOpInfo x86;
|
||||||
if (a<c) a = c;
|
public Mips.UnionOpInfo mips;
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class _cs_insn extends Structure {
|
protected static class _cs_insn extends Structure {
|
||||||
|
@ -42,39 +38,49 @@ public class Capstone {
|
||||||
public byte[] bytes;
|
public byte[] bytes;
|
||||||
public byte[] mnemonic;
|
public byte[] mnemonic;
|
||||||
public byte[] operands;
|
public byte[] operands;
|
||||||
public byte[] regs_read;
|
public _cs_detail.ByReference cs_detail;
|
||||||
public byte regs_read_count;
|
|
||||||
public byte[] regs_write;
|
|
||||||
public byte regs_write_count;
|
|
||||||
public byte[] groups;
|
|
||||||
public byte groups_count;
|
|
||||||
|
|
||||||
public _cs_insn(Pointer p) {
|
public _cs_insn() {
|
||||||
bytes = new byte[16];
|
bytes = new byte[16];
|
||||||
mnemonic = new byte[32];
|
mnemonic = new byte[32];
|
||||||
operands = new byte[96];
|
operands = new byte[96];
|
||||||
regs_read = new byte[12];
|
}
|
||||||
regs_write = new byte[20];
|
|
||||||
groups = new byte[8];
|
public _cs_insn(Pointer p) {
|
||||||
|
this();
|
||||||
useMemory(p);
|
useMemory(p);
|
||||||
read();
|
read();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List getFieldOrder() {
|
public List getFieldOrder() {
|
||||||
return Arrays.asList("id", "address", "size", "bytes", "mnemonic", "operands",
|
return Arrays.asList("id", "address", "size", "bytes", "mnemonic", "operands", "cs_detail");
|
||||||
"regs_read", "regs_read_count",
|
}
|
||||||
"regs_write", "regs_write_count",
|
}
|
||||||
"groups", "groups_count");
|
|
||||||
|
protected static class _cs_detail extends Structure {
|
||||||
|
public static class ByReference extends _cs_detail implements Structure.ByReference {};
|
||||||
|
|
||||||
|
public byte[] regs_read = new byte[12];
|
||||||
|
public byte regs_read_count;
|
||||||
|
public byte[] regs_write = new byte[20];
|
||||||
|
public byte regs_write_count;
|
||||||
|
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 {
|
public static class CsInsn {
|
||||||
public OpInfo operands;
|
|
||||||
private Pointer ptr_origin;
|
|
||||||
private NativeLong csh;
|
private NativeLong csh;
|
||||||
private CS cs;
|
private CS cs;
|
||||||
private static int _size = -1;
|
private _cs_insn raw;
|
||||||
|
private int arch;
|
||||||
|
|
||||||
public int id;
|
public int id;
|
||||||
public long address;
|
public long address;
|
||||||
|
@ -84,54 +90,79 @@ public class Capstone {
|
||||||
public byte[] regsRead;
|
public byte[] regsRead;
|
||||||
public byte[] regsWrite;
|
public byte[] regsWrite;
|
||||||
public byte[] groups;
|
public byte[] groups;
|
||||||
|
public OpInfo operands;
|
||||||
|
|
||||||
public CsInsn (_cs_insn struct, Pointer _ptr_origin, NativeLong _csh, CS _cs, OpInfo _op_info) {
|
public CsInsn (_cs_insn insn, int _arch, NativeLong _csh, CS _cs) {
|
||||||
id = struct.id;
|
id = insn.id;
|
||||||
address = struct.address;
|
address = insn.address;
|
||||||
size = struct.size;
|
size = insn.size;
|
||||||
mnemonic = new String(struct.mnemonic).replace("\u0000","");
|
mnemonic = new String(insn.mnemonic).replace("\u0000","");
|
||||||
opStr = new String(struct.operands).replace("\u0000","");
|
opStr = new String(insn.operands).replace("\u0000","");
|
||||||
|
|
||||||
regsRead = new byte[struct.regs_read_count];
|
arch = _arch;
|
||||||
for (int i=0; i<regsRead.length; i++)
|
raw = insn;
|
||||||
regsRead[i] = struct.regs_read[i];
|
|
||||||
regsWrite = new byte[struct.regs_write_count];
|
|
||||||
for (int i=0; i<regsWrite.length; i++)
|
|
||||||
regsWrite[i] = struct.regs_write[i];
|
|
||||||
groups = new byte[struct.groups_count];
|
|
||||||
for (int i=0; i<groups.length; i++)
|
|
||||||
groups[i] = struct.groups[i];
|
|
||||||
operands = _op_info;
|
|
||||||
|
|
||||||
ptr_origin = _ptr_origin;
|
|
||||||
csh = _csh;
|
csh = _csh;
|
||||||
cs = _cs;
|
cs = _cs;
|
||||||
|
|
||||||
// cache the size so we do not need to recompute the offset everytime
|
if (insn.cs_detail != null) {
|
||||||
if (_size == -1)
|
regsRead = new byte[insn.cs_detail.regs_read_count];
|
||||||
_size = struct.size() + Arm.UnionOpInfo.getSize();
|
for (int i=0; i<regsRead.length; i++)
|
||||||
// Arm is the max, so we optimized it here, a more generic way is as follows:
|
regsRead[i] = insn.cs_detail.regs_read[i];
|
||||||
// = max( Arm.UnionOpInfo.getSize(), Arm64.UnionOpInfo.getSize(), Mips.UnionOpInfo.getSize(), X86.UnionOpInfo.getSize() );
|
regsWrite = new byte[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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int size() {
|
private OpInfo getOptInfo(_cs_detail detail) {
|
||||||
return _size;
|
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;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return op_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int opCount(int type) {
|
public int opCount(int type) {
|
||||||
return cs.cs_op_count(csh, ptr_origin, type);
|
return cs.cs_op_count(csh, raw.getPointer(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int opIndex(int type, int index) {
|
public int opIndex(int type, int index) {
|
||||||
return cs.cs_op_index(csh, ptr_origin, type, index);
|
return cs.cs_op_index(csh, raw.getPointer(), type, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean regRead(int reg_id) {
|
public boolean regRead(int reg_id) {
|
||||||
return cs.cs_reg_read(csh, ptr_origin, reg_id) != 0;
|
return cs.cs_reg_read(csh, raw.getPointer(), reg_id) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean regWrite(int reg_id) {
|
public boolean regWrite(int reg_id) {
|
||||||
return cs.cs_reg_write(csh, ptr_origin, reg_id) != 0;
|
return cs.cs_reg_write(csh, raw.getPointer(), reg_id) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int errno() {
|
public int errno() {
|
||||||
|
@ -147,47 +178,16 @@ public class Capstone {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean group(int gid) {
|
public boolean group(int gid) {
|
||||||
return cs.cs_insn_group(csh, ptr_origin, gid) != 0;
|
return cs.cs_insn_group(csh, raw.getPointer(), gid) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CsInsn fromPointer(Pointer pointer)
|
private CsInsn[] fromArrayRaw(_cs_insn[] arr_raw) {
|
||||||
{
|
CsInsn[] arr = new CsInsn[arr_raw.length];
|
||||||
_cs_insn insn = new _cs_insn(pointer);
|
|
||||||
OpInfo op_info = null;
|
|
||||||
UnionOpInfo _op_info = null;
|
|
||||||
|
|
||||||
switch (this.arch) {
|
for (int i = 0; i < arr_raw.length; i++) {
|
||||||
case CS_ARCH_ARM:
|
arr[i] = new CsInsn(arr_raw[i], this.arch, ns.csh, cs);
|
||||||
_op_info = new Arm.UnionOpInfo(pointer.share(insn.size()));
|
|
||||||
op_info = new Arm.OpInfo((Arm.UnionOpInfo) _op_info);
|
|
||||||
break;
|
|
||||||
case CS_ARCH_ARM64:
|
|
||||||
_op_info = new Arm64.UnionOpInfo(pointer.share(insn.size()));
|
|
||||||
op_info = new Arm64.OpInfo((Arm64.UnionOpInfo) _op_info);
|
|
||||||
break;
|
|
||||||
case CS_ARCH_MIPS:
|
|
||||||
_op_info = new Mips.UnionOpInfo(pointer.share(insn.size()));
|
|
||||||
op_info = new Mips.OpInfo((Mips.UnionOpInfo) _op_info);
|
|
||||||
break;
|
|
||||||
case CS_ARCH_X86:
|
|
||||||
_op_info = new X86.UnionOpInfo(pointer.share(insn.size()));
|
|
||||||
op_info = new X86.OpInfo((X86.UnionOpInfo) _op_info);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
return new CsInsn(insn, pointer, ns.csh, cs, op_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CsInsn[] fromArrayPointer(Pointer pointer, int numberResults)
|
|
||||||
{
|
|
||||||
CsInsn[] arr = new CsInsn[numberResults];
|
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < numberResults; i++) {
|
|
||||||
arr[i] = fromPointer(pointer.share(offset));
|
|
||||||
offset += arr[i].size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
|
@ -195,7 +195,7 @@ public class Capstone {
|
||||||
|
|
||||||
private interface CS extends Library {
|
private interface CS extends Library {
|
||||||
public int cs_open(int arch, int mode, NativeLongByReference handle);
|
public int cs_open(int arch, int mode, NativeLongByReference handle);
|
||||||
public NativeLong cs_disasm_dyn(NativeLong handle, byte[] code, NativeLong code_len,
|
public NativeLong cs_disasm_ex(NativeLong handle, byte[] code, NativeLong code_len,
|
||||||
long addr, NativeLong count, PointerByReference insn);
|
long addr, NativeLong count, PointerByReference insn);
|
||||||
public void cs_free(Pointer p);
|
public void cs_free(Pointer p);
|
||||||
public int cs_close(NativeLong handle);
|
public int cs_close(NativeLong handle);
|
||||||
|
@ -258,9 +258,12 @@ public class Capstone {
|
||||||
|
|
||||||
protected NativeStruct ns; // for memory retention
|
protected NativeStruct ns; // for memory retention
|
||||||
private CS cs;
|
private CS cs;
|
||||||
|
public int arch;
|
||||||
|
public int mode;
|
||||||
|
private int syntax;
|
||||||
|
private int detail;
|
||||||
|
|
||||||
public Capstone(int arch, int mode)
|
public Capstone(int arch, int mode) {
|
||||||
{
|
|
||||||
this.arch = arch;
|
this.arch = arch;
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
ns = new NativeStruct();
|
ns = new NativeStruct();
|
||||||
|
@ -311,9 +314,12 @@ public class Capstone {
|
||||||
public CsInsn[] disasm(byte[] code, long address, long count) {
|
public CsInsn[] disasm(byte[] code, long address, long count) {
|
||||||
PointerByReference insnRef = new PointerByReference();
|
PointerByReference insnRef = new PointerByReference();
|
||||||
|
|
||||||
NativeLong c = cs.cs_disasm_dyn(ns.csh, code, new NativeLong(code.length), address, new NativeLong(count), insnRef);
|
NativeLong c = cs.cs_disasm_ex(ns.csh, code, new NativeLong(code.length), address, new NativeLong(count), insnRef);
|
||||||
|
|
||||||
CsInsn[] allInsn = fromArrayPointer(insnRef.getValue(), c.intValue());
|
Pointer p = insnRef.getValue();
|
||||||
|
_cs_insn byref = new _cs_insn(p);
|
||||||
|
|
||||||
|
CsInsn[] allInsn = fromArrayRaw((_cs_insn[]) byref.toArray(c.intValue()));
|
||||||
return allInsn;
|
return allInsn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
package capstone;
|
package capstone;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
import com.sun.jna.Pointer;
|
|
||||||
import com.sun.jna.Union;
|
import com.sun.jna.Union;
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -66,16 +64,6 @@ public class Mips {
|
||||||
op = new Operand[8];
|
op = new Operand[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnionOpInfo(Pointer p) {
|
|
||||||
op = new Operand[8];
|
|
||||||
useMemory(p);
|
|
||||||
read();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getSize() {
|
|
||||||
return (new UnionOpInfo()).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void read() {
|
public void read() {
|
||||||
readField("op_count");
|
readField("op_count");
|
||||||
op = new Operand[op_count];
|
op = new Operand[op_count];
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
package capstone;
|
package capstone;
|
||||||
|
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
import com.sun.jna.Pointer;
|
|
||||||
import com.sun.jna.Union;
|
import com.sun.jna.Union;
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -89,18 +87,6 @@ public class X86 {
|
||||||
prefix = new byte[5];
|
prefix = new byte[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnionOpInfo(Pointer p) {
|
|
||||||
op = new Operand[8];
|
|
||||||
opcode = new byte[3];
|
|
||||||
prefix = new byte[5];
|
|
||||||
useMemory(p);
|
|
||||||
read();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getSize() {
|
|
||||||
return (new UnionOpInfo()).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List getFieldOrder() {
|
public List getFieldOrder() {
|
||||||
return Arrays.asList("prefix", "segment", "opcode", "op_size", "addr_size", "disp_size",
|
return Arrays.asList("prefix", "segment", "opcode", "op_size", "addr_size", "disp_size",
|
||||||
|
|
Loading…
Reference in New Issue