6 import com.sun.jna.Library;
7 import com.sun.jna.Memory;
8 import com.sun.jna.Native;
9 import com.sun.jna.NativeLong;
10 import com.sun.jna.ptr.ByteByReference;
11 import com.sun.jna.ptr.NativeLongByReference;
12 import com.sun.jna.Structure;
13 import com.sun.jna.Union;
14 import com.sun.jna.Pointer;
15 import com.sun.jna.ptr.PointerByReference;
16 import com.sun.jna.ptr.IntByReference;
18 import java.util.List;
19 import java.util.Arrays;
22 public class Capstone {
24 protected static abstract class OpInfo {};
25 protected static abstract class UnionOpInfo
extends Structure {};
27 public static class UnionArch
extends Union {
28 public static class ByValue
extends UnionArch implements Union.ByValue {};
30 public Arm.UnionOpInfo
arm;
31 public Arm64.UnionOpInfo
arm64;
32 public X86.UnionOpInfo
x86;
33 public Mips.UnionOpInfo
mips;
34 public Ppc.UnionOpInfo
ppc;
35 public Sparc.UnionOpInfo
sparc;
36 public Systemz.UnionOpInfo sysz;
37 public Xcore.UnionOpInfo
xcore;
38 public M680x.UnionOpInfo m680x;
41 protected static class _cs_insn
extends Structure {
51 public byte[] mnemonic;
55 public _cs_detail.ByReference cs_detail;
59 mnemonic =
new byte[32];
60 op_str =
new byte[160];
61 java.util.Arrays.fill(mnemonic, (
byte) 0);
62 java.util.Arrays.fill(op_str, (
byte) 0);
72 public List getFieldOrder() {
73 return Arrays.asList(
"id",
"address",
"size",
"bytes",
"mnemonic",
"op_str",
"cs_detail");
77 protected static class _cs_detail
extends Structure {
78 public static class ByReference
extends _cs_detail implements Structure.ByReference {};
81 public short[] regs_read =
new short[16];
82 public byte regs_read_count;
84 public short[] regs_write =
new short[20];
85 public byte regs_write_count;
87 public byte[]
groups =
new byte[8];
88 public byte groups_count;
90 public UnionArch
arch;
93 public List getFieldOrder() {
94 return Arrays.asList(
"regs_read",
"regs_read_count",
"regs_write",
"regs_write_count",
"groups",
"groups_count",
"arch");
98 public static class CsInsn {
101 private _cs_insn raw;
113 public String mnemonic;
117 public short[] regsRead;
119 public short[] regsWrite;
124 public CsInsn (_cs_insn insn,
int _arch,
Pointer _csh, CS
_cs,
boolean diet) {
126 address = insn.address;
131 while (insn.mnemonic[lm++] != 0);
133 while (insn.op_str[lo++] != 0);
134 mnemonic =
new String(insn.mnemonic, 0, lm-1);
135 opStr =
new String(insn.op_str, 0, lo-1);
136 bytes = Arrays.copyOf(insn.bytes, insn.size);
144 if (insn.cs_detail !=
null) {
146 regsRead =
new short[insn.cs_detail.regs_read_count];
147 for (
int i=0;
i<regsRead.length;
i++)
148 regsRead[i] = insn.cs_detail.regs_read[i];
149 regsWrite =
new short[insn.cs_detail.regs_write_count];
150 for (
int i=0;
i<regsWrite.length;
i++)
151 regsWrite[i] = insn.cs_detail.regs_write[i];
152 groups =
new byte[insn.cs_detail.groups_count];
154 groups[i] = insn.cs_detail.groups[i];
157 operands = getOptInfo(insn.cs_detail);
166 detail.arch.setType(Arm.UnionOpInfo.class);
168 op_info =
new Arm.OpInfo((Arm.UnionOpInfo)
detail.arch.arm);
171 detail.arch.setType(Arm64.UnionOpInfo.class);
173 op_info =
new Arm64.OpInfo((Arm64.UnionOpInfo)
detail.arch.arm64);
176 detail.arch.setType(Mips.UnionOpInfo.class);
178 op_info =
new Mips.OpInfo((Mips.UnionOpInfo)
detail.arch.mips);
181 detail.arch.setType(X86.UnionOpInfo.class);
183 op_info =
new X86.OpInfo((X86.UnionOpInfo)
detail.arch.x86);
186 detail.arch.setType(Sparc.UnionOpInfo.class);
188 op_info =
new Sparc.OpInfo((Sparc.UnionOpInfo)
detail.arch.sparc);
191 detail.arch.setType(Systemz.UnionOpInfo.class);
193 op_info =
new Systemz.OpInfo((Systemz.UnionOpInfo)
detail.arch.sysz);
196 detail.arch.setType(Ppc.UnionOpInfo.class);
198 op_info =
new Ppc.OpInfo((Ppc.UnionOpInfo)
detail.arch.ppc);
201 detail.arch.setType(Xcore.UnionOpInfo.class);
203 op_info =
new Xcore.OpInfo((Xcore.UnionOpInfo)
detail.arch.xcore);
206 detail.arch.setType(M680x.UnionOpInfo.class);
208 op_info =
new M680x.OpInfo((M680x.UnionOpInfo)
detail.arch.m680x);
216 public int opCount(
int type) {
217 return cs.cs_op_count(
csh, raw.getPointer(),
type);
220 public int opIndex(
int type,
int index) {
224 public boolean regRead(
int reg_id) {
225 return cs.cs_reg_read(
csh, raw.getPointer(), reg_id) != 0;
228 public boolean regWrite(
int reg_id) {
229 return cs.cs_reg_write(
csh, raw.getPointer(), reg_id) != 0;
233 return cs.cs_errno(
csh);
236 public String regName(
int reg_id) {
237 return cs.cs_reg_name(
csh, reg_id);
240 public String insnName() {
241 return cs.cs_insn_name(
csh,
id);
244 public String groupName(
int id) {
245 return cs.cs_group_name(
csh,
id);
248 public boolean group(
int gid) {
249 return cs.cs_insn_group(
csh, raw.getPointer(), gid) != 0;
252 public CsRegsAccess regsAccess() {
253 Memory regsReadMemory =
new Memory(64*2);
254 ByteByReference regsReadCountRef =
new ByteByReference();
255 Memory regsWriteMemory =
new Memory(64*2);
256 ByteByReference regsWriteCountRef =
new ByteByReference();
258 int c =
cs.cs_regs_access(
csh, raw.getPointer(), regsReadMemory, regsReadCountRef, regsWriteMemory, regsWriteCountRef);
263 byte regsReadCount = regsReadCountRef.getValue();
264 byte regsWriteCount = regsWriteCountRef.getValue();
266 short[] regsRead =
new short[regsReadCount];
267 regsReadMemory.read(0, regsRead, 0, regsReadCount);
269 short[] regsWrite =
new short[regsWriteCount];
270 regsWriteMemory.read(0, regsWrite, 0, regsWriteCount);
272 return new CsRegsAccess(regsRead, regsWrite);
276 public static class CsRegsAccess {
277 public short[] regsRead;
278 public short[] regsWrite;
280 public CsRegsAccess(
short[] regsRead,
short[] regsWrite) {
281 this.regsRead = regsRead;
282 this.regsWrite = regsWrite;
286 private CsInsn[] fromArrayRaw(_cs_insn[] arr_raw) {
287 CsInsn[] arr =
new CsInsn[arr_raw.length];
289 for (
int i = 0;
i < arr_raw.length;
i++) {
290 arr[
i] =
new CsInsn(arr_raw[i], this.arch,
ns.csh,
cs,
this.diet);
296 private interface CS
extends Library {
299 long addr, NativeLong
count, PointerByReference insn);
314 public int cs_version(IntByReference major, IntByReference minor);
401 public static final int CS_OP_FP = 4;
422 protected class NativeStruct {
424 private PointerByReference handleRef;
427 private static final CsInsn[] EMPTY_INSN =
new CsInsn[0];
429 protected NativeStruct
ns;
435 private boolean diet;
437 public Capstone(
int arch,
int mode) {
438 cs = (CS)Native.loadLibrary(
"capstone", CS.class);
439 int coreVersion =
cs.cs_version(
null,
null);
441 if (coreVersion != bindingVersion) {
442 throw new RuntimeException(
"Different API version between core " + coreVersion +
443 " & binding " + bindingVersion +
" (CS_ERR_VERSION)");
448 ns =
new NativeStruct();
449 ns.handleRef =
new PointerByReference();
451 throw new RuntimeException(
"ERROR: Wrong arch or mode");
453 ns.csh =
ns.handleRef.getValue();
460 return cs.cs_version(
null,
null);
464 public void setSyntax(
int syntax) {
468 throw new RuntimeException(
"ERROR: Failed to set assembly syntax");
473 public void setDetail(
int opt) {
477 throw new RuntimeException(
"ERROR: Failed to set detail option");
482 public void setMode(
int opt) {
486 throw new RuntimeException(
"ERROR: Failed to set mode option");
491 protected void finalize() {
498 return cs.cs_close(
ns.handleRef);
509 public CsInsn[] disasm(
byte[]
code,
long address) {
510 return disasm(
code, address, 0);
522 public CsInsn[] disasm(
byte[]
code,
long address,
long count) {
523 PointerByReference insnRef =
new PointerByReference();
525 NativeLong
c =
cs.cs_disasm(
ns.csh,
code,
new NativeLong(
code.length), address,
new NativeLong(
count), insnRef);
527 if (0 ==
c.intValue()) {
532 _cs_insn byref =
new _cs_insn(p);
534 CsInsn[] allInsn = fromArrayRaw((_cs_insn[]) byref.toArray(
c.intValue()));
543 public String strerror(
int code) {
544 return cs.cs_strerror(
code);