1 // Capstone Java binding 2 // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 4 package capstone; 5 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; 17 18 import java.util.List; 19 import java.util.Arrays; 20 import java.lang.RuntimeException; 21 22 public class Capstone { 23 24 protected static abstract class OpInfo {}; 25 protected static abstract class UnionOpInfo extends Structure {}; 26 27 public static class UnionArch extends Union { 28 public static class ByValue extends UnionArch implements Union.ByValue {}; 29 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; 39 } 40 41 protected static class _cs_insn extends Structure { 42 // instruction ID. 43 public int id; 44 // instruction address. 45 public long address; 46 // instruction size. 47 public short size; 48 // machine bytes of instruction. 49 public byte[] bytes; 50 // instruction mnemonic. NOTE: irrelevant for diet engine. 51 public byte[] mnemonic; 52 // instruction operands. NOTE: irrelevant for diet engine. 53 public byte[] op_str; 54 // detail information of instruction. 55 public _cs_detail.ByReference cs_detail; 56 _cs_insn()57 public _cs_insn() { 58 bytes = new byte[16]; 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); 63 } 64 _cs_insn(Pointer p)65 public _cs_insn(Pointer p) { 66 this(); 67 useMemory(p); 68 read(); 69 } 70 71 @Override getFieldOrder()72 public List getFieldOrder() { 73 return Arrays.asList("id", "address", "size", "bytes", "mnemonic", "op_str", "cs_detail"); 74 } 75 } 76 77 protected static class _cs_detail extends Structure { 78 public static class ByReference extends _cs_detail implements Structure.ByReference {}; 79 80 // list of all implicit registers being read. 81 public short[] regs_read = new short[12]; 82 public byte regs_read_count; 83 // list of all implicit registers being written. 84 public short[] regs_write = new short[20]; 85 public byte regs_write_count; 86 // list of semantic groups this instruction belongs to. 87 public byte[] groups = new byte[8]; 88 public byte groups_count; 89 90 public UnionArch arch; 91 92 @Override getFieldOrder()93 public List getFieldOrder() { 94 return Arrays.asList("regs_read", "regs_read_count", "regs_write", "regs_write_count", "groups", "groups_count", "arch"); 95 } 96 } 97 98 public static class CsInsn { 99 private NativeLong csh; 100 private CS cs; 101 private _cs_insn raw; 102 private int arch; 103 104 // instruction ID. 105 public int id; 106 // instruction address. 107 public long address; 108 // instruction size. 109 public short size; 110 // Machine bytes of this instruction, with number of bytes indicated by size above 111 public byte[] bytes; 112 // instruction mnemonic. NOTE: irrelevant for diet engine. 113 public String mnemonic; 114 // instruction operands. NOTE: irrelevant for diet engine. 115 public String opStr; 116 // list of all implicit registers being read. 117 public short[] regsRead; 118 // list of all implicit registers being written. 119 public short[] regsWrite; 120 // list of semantic groups this instruction belongs to. 121 public byte[] groups; 122 public OpInfo operands; 123 CsInsn(_cs_insn insn, int _arch, NativeLong _csh, CS _cs, boolean diet)124 public CsInsn (_cs_insn insn, int _arch, NativeLong _csh, CS _cs, boolean diet) { 125 id = insn.id; 126 address = insn.address; 127 size = insn.size; 128 129 if (!diet) { 130 int lm = 0; 131 while (insn.mnemonic[lm++] != 0); 132 int lo = 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); 137 } 138 139 cs = _cs; 140 arch = _arch; 141 raw = insn; 142 csh = _csh; 143 144 if (insn.cs_detail != null) { 145 if (!diet) { 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]; 153 for (int i=0; i<groups.length; i++) 154 groups[i] = insn.cs_detail.groups[i]; 155 } 156 157 operands = getOptInfo(insn.cs_detail); 158 } 159 } 160 getOptInfo(_cs_detail detail)161 private OpInfo getOptInfo(_cs_detail detail) { 162 OpInfo op_info = null; 163 164 switch (this.arch) { 165 case CS_ARCH_ARM: 166 detail.arch.setType(Arm.UnionOpInfo.class); 167 detail.arch.read(); 168 op_info = new Arm.OpInfo((Arm.UnionOpInfo) detail.arch.arm); 169 break; 170 case CS_ARCH_ARM64: 171 detail.arch.setType(Arm64.UnionOpInfo.class); 172 detail.arch.read(); 173 op_info = new Arm64.OpInfo((Arm64.UnionOpInfo) detail.arch.arm64); 174 break; 175 case CS_ARCH_MIPS: 176 detail.arch.setType(Mips.UnionOpInfo.class); 177 detail.arch.read(); 178 op_info = new Mips.OpInfo((Mips.UnionOpInfo) detail.arch.mips); 179 break; 180 case CS_ARCH_X86: 181 detail.arch.setType(X86.UnionOpInfo.class); 182 detail.arch.read(); 183 op_info = new X86.OpInfo((X86.UnionOpInfo) detail.arch.x86); 184 break; 185 case CS_ARCH_SPARC: 186 detail.arch.setType(Sparc.UnionOpInfo.class); 187 detail.arch.read(); 188 op_info = new Sparc.OpInfo((Sparc.UnionOpInfo) detail.arch.sparc); 189 break; 190 case CS_ARCH_SYSZ: 191 detail.arch.setType(Systemz.UnionOpInfo.class); 192 detail.arch.read(); 193 op_info = new Systemz.OpInfo((Systemz.UnionOpInfo) detail.arch.sysz); 194 break; 195 case CS_ARCH_PPC: 196 detail.arch.setType(Ppc.UnionOpInfo.class); 197 detail.arch.read(); 198 op_info = new Ppc.OpInfo((Ppc.UnionOpInfo) detail.arch.ppc); 199 break; 200 case CS_ARCH_XCORE: 201 detail.arch.setType(Xcore.UnionOpInfo.class); 202 detail.arch.read(); 203 op_info = new Xcore.OpInfo((Xcore.UnionOpInfo) detail.arch.xcore); 204 break; 205 case CS_ARCH_M680X: 206 detail.arch.setType(M680x.UnionOpInfo.class); 207 detail.arch.read(); 208 op_info = new M680x.OpInfo((M680x.UnionOpInfo) detail.arch.m680x); 209 break; 210 default: 211 } 212 213 return op_info; 214 } 215 opCount(int type)216 public int opCount(int type) { 217 return cs.cs_op_count(csh, raw.getPointer(), type); 218 } 219 opIndex(int type, int index)220 public int opIndex(int type, int index) { 221 return cs.cs_op_index(csh, raw.getPointer(), type, index); 222 } 223 regRead(int reg_id)224 public boolean regRead(int reg_id) { 225 return cs.cs_reg_read(csh, raw.getPointer(), reg_id) != 0; 226 } 227 regWrite(int reg_id)228 public boolean regWrite(int reg_id) { 229 return cs.cs_reg_write(csh, raw.getPointer(), reg_id) != 0; 230 } 231 errno()232 public int errno() { 233 return cs.cs_errno(csh); 234 } 235 regName(int reg_id)236 public String regName(int reg_id) { 237 return cs.cs_reg_name(csh, reg_id); 238 } 239 insnName()240 public String insnName() { 241 return cs.cs_insn_name(csh, id); 242 } 243 groupName(int id)244 public String groupName(int id) { 245 return cs.cs_group_name(csh, id); 246 } 247 group(int gid)248 public boolean group(int gid) { 249 return cs.cs_insn_group(csh, raw.getPointer(), gid) != 0; 250 } 251 regsAccess()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(); 257 258 int c = cs.cs_regs_access(csh, raw.getPointer(), regsReadMemory, regsReadCountRef, regsWriteMemory, regsWriteCountRef); 259 if (c != CS_ERR_OK) { 260 return null; 261 } 262 263 byte regsReadCount = regsReadCountRef.getValue(); 264 byte regsWriteCount = regsWriteCountRef.getValue(); 265 266 short[] regsRead = new short[regsReadCount]; 267 regsReadMemory.read(0, regsRead, 0, regsReadCount); 268 269 short[] regsWrite = new short[regsWriteCount]; 270 regsWriteMemory.read(0, regsWrite, 0, regsWriteCount); 271 272 return new CsRegsAccess(regsRead, regsWrite); 273 } 274 } 275 276 public static class CsRegsAccess { 277 public short[] regsRead; 278 public short[] regsWrite; 279 CsRegsAccess(short[] regsRead, short[] regsWrite)280 public CsRegsAccess(short[] regsRead, short[] regsWrite) { 281 this.regsRead = regsRead; 282 this.regsWrite = regsWrite; 283 } 284 } 285 fromArrayRaw(_cs_insn[] arr_raw)286 private CsInsn[] fromArrayRaw(_cs_insn[] arr_raw) { 287 CsInsn[] arr = new CsInsn[arr_raw.length]; 288 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); 291 } 292 293 return arr; 294 } 295 296 private interface CS extends Library { cs_open(int arch, int mode, NativeLongByReference handle)297 public int cs_open(int arch, int mode, NativeLongByReference handle); cs_disasm(NativeLong handle, byte[] code, NativeLong code_len, long addr, NativeLong count, PointerByReference insn)298 public NativeLong cs_disasm(NativeLong handle, byte[] code, NativeLong code_len, 299 long addr, NativeLong count, PointerByReference insn); cs_free(Pointer p, NativeLong count)300 public void cs_free(Pointer p, NativeLong count); cs_close(NativeLongByReference handle)301 public int cs_close(NativeLongByReference handle); cs_option(NativeLong handle, int option, NativeLong optionValue)302 public int cs_option(NativeLong handle, int option, NativeLong optionValue); 303 cs_reg_name(NativeLong csh, int id)304 public String cs_reg_name(NativeLong csh, int id); cs_op_count(NativeLong csh, Pointer insn, int type)305 public int cs_op_count(NativeLong csh, Pointer insn, int type); cs_op_index(NativeLong csh, Pointer insn, int type, int index)306 public int cs_op_index(NativeLong csh, Pointer insn, int type, int index); 307 cs_insn_name(NativeLong csh, int id)308 public String cs_insn_name(NativeLong csh, int id); cs_group_name(NativeLong csh, int id)309 public String cs_group_name(NativeLong csh, int id); cs_insn_group(NativeLong csh, Pointer insn, int id)310 public byte cs_insn_group(NativeLong csh, Pointer insn, int id); cs_reg_read(NativeLong csh, Pointer insn, int id)311 public byte cs_reg_read(NativeLong csh, Pointer insn, int id); cs_reg_write(NativeLong csh, Pointer insn, int id)312 public byte cs_reg_write(NativeLong csh, Pointer insn, int id); cs_errno(NativeLong csh)313 public int cs_errno(NativeLong csh); cs_version(IntByReference major, IntByReference minor)314 public int cs_version(IntByReference major, IntByReference minor); cs_support(int query)315 public boolean cs_support(int query); cs_strerror(int code)316 public String cs_strerror(int code); cs_regs_access(NativeLong handle, Pointer insn, Pointer regs_read, ByteByReference regs_read_count, Pointer regs_write, ByteByReference regs_write_count)317 public int cs_regs_access(NativeLong handle, Pointer insn, Pointer regs_read, ByteByReference regs_read_count, Pointer regs_write, ByteByReference regs_write_count); 318 } 319 320 // Capstone API version 321 public static final int CS_API_MAJOR = 4; 322 public static final int CS_API_MINOR = 0; 323 324 // architectures 325 public static final int CS_ARCH_ARM = 0; 326 public static final int CS_ARCH_ARM64 = 1; 327 public static final int CS_ARCH_MIPS = 2; 328 public static final int CS_ARCH_X86 = 3; 329 public static final int CS_ARCH_PPC = 4; 330 public static final int CS_ARCH_SPARC = 5; 331 public static final int CS_ARCH_SYSZ = 6; 332 public static final int CS_ARCH_XCORE = 7; 333 public static final int CS_ARCH_M68K = 8; 334 public static final int CS_ARCH_TMS320C64X = 9; 335 public static final int CS_ARCH_M680X = 10; 336 public static final int CS_ARCH_MAX = 11; 337 public static final int CS_ARCH_ALL = 0xFFFF; // query id for cs_support() 338 339 // disasm mode 340 public static final int CS_MODE_LITTLE_ENDIAN = 0; // little-endian mode (default mode) 341 public static final int CS_MODE_ARM = 0; // 32-bit ARM 342 public static final int CS_MODE_16 = 1 << 1; // 16-bit mode for X86 343 public static final int CS_MODE_32 = 1 << 2; // 32-bit mode for X86 344 public static final int CS_MODE_64 = 1 << 3; // 64-bit mode for X86, PPC 345 public static final int CS_MODE_THUMB = 1 << 4; // ARM's Thumb mode, including Thumb-2 346 public static final int CS_MODE_MCLASS = 1 << 5; // ARM's Cortex-M series 347 public static final int CS_MODE_V8 = 1 << 6; // ARMv8 A32 encodings for ARM 348 public static final int CS_MODE_MICRO = 1 << 4; // MicroMips mode (Mips arch) 349 public static final int CS_MODE_MIPS3 = 1 << 5; // Mips III ISA 350 public static final int CS_MODE_MIPS32R6 = 1 << 6; // Mips32r6 ISA 351 public static final int CS_MODE_MIPS2 = 1 << 7; // Mips II ISA 352 public static final int CS_MODE_BIG_ENDIAN = 1 << 31; // big-endian mode 353 public static final int CS_MODE_V9 = 1 << 4; // SparcV9 mode (Sparc arch) 354 public static final int CS_MODE_MIPS32 = CS_MODE_32; // Mips32 ISA 355 public static final int CS_MODE_MIPS64 = CS_MODE_64; // Mips64 ISA 356 public static final int CS_MODE_QPX = 1 << 4; // Quad Processing eXtensions mode (PPC) 357 public static final int CS_MODE_M680X_6301 = 1 << 1; // M680X Hitachi 6301,6303 mode 358 public static final int CS_MODE_M680X_6309 = 1 << 2; // M680X Hitachi 6309 mode 359 public static final int CS_MODE_M680X_6800 = 1 << 3; // M680X Motorola 6800,6802 mode 360 public static final int CS_MODE_M680X_6801 = 1 << 4; // M680X Motorola 6801,6803 mode 361 public static final int CS_MODE_M680X_6805 = 1 << 5; // M680X Motorola 6805 mode 362 public static final int CS_MODE_M680X_6808 = 1 << 6; // M680X Motorola 6808 mode 363 public static final int CS_MODE_M680X_6809 = 1 << 7; // M680X Motorola 6809 mode 364 public static final int CS_MODE_M680X_6811 = 1 << 8; // M680X Motorola/Freescale 68HC11 mode 365 public static final int CS_MODE_M680X_CPU12 = 1 << 9; // M680X Motorola/Freescale/NXP CPU12 mode 366 public static final int CS_MODE_M680X_HCS08 = 1 << 10; // M680X Freescale HCS08 mode 367 368 // Capstone error 369 public static final int CS_ERR_OK = 0; 370 public static final int CS_ERR_MEM = 1; // Out-Of-Memory error 371 public static final int CS_ERR_ARCH = 2; // Unsupported architecture 372 public static final int CS_ERR_HANDLE = 3; // Invalid handle 373 public static final int CS_ERR_CSH = 4; // Invalid csh argument 374 public static final int CS_ERR_MODE = 5; // Invalid/unsupported mode 375 public static final int CS_ERR_OPTION = 6; // Invalid/unsupported option: cs_option() 376 public static final int CS_ERR_DETAIL = 7; // Invalid/unsupported option: cs_option() 377 public static final int CS_ERR_MEMSETUP = 8; 378 public static final int CS_ERR_VERSION = 9; //Unsupported version (bindings) 379 public static final int CS_ERR_DIET = 10; //Information irrelevant in diet engine 380 public static final int CS_ERR_SKIPDATA = 11; //Access irrelevant data for "data" instruction in SKIPDATA mode 381 public static final int CS_ERR_X86_ATT = 12; //X86 AT&T syntax is unsupported (opt-out at compile time) 382 public static final int CS_ERR_X86_INTEL = 13; //X86 Intel syntax is unsupported (opt-out at compile time) 383 384 // Capstone option type 385 public static final int CS_OPT_SYNTAX = 1; // Intel X86 asm syntax (CS_ARCH_X86 arch) 386 public static final int CS_OPT_DETAIL = 2; // Break down instruction structure into details 387 public static final int CS_OPT_MODE = 3; // Change engine's mode at run-time 388 389 // Capstone option value 390 public static final int CS_OPT_OFF = 0; // Turn OFF an option - default option of CS_OPT_DETAIL 391 public static final int CS_OPT_SYNTAX_INTEL = 1; // Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX, CS_ARCH_X86) 392 public static final int CS_OPT_SYNTAX_ATT = 2; // ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86) 393 public static final int CS_OPT_ON = 3; // Turn ON an option (CS_OPT_DETAIL) 394 public static final int CS_OPT_SYNTAX_NOREGNAME = 3; // PPC asm syntax: Prints register name with only number (CS_OPT_SYNTAX) 395 396 // Common instruction operand types - to be consistent across all architectures. 397 public static final int CS_OP_INVALID = 0; 398 public static final int CS_OP_REG = 1; 399 public static final int CS_OP_IMM = 2; 400 public static final int CS_OP_MEM = 3; 401 public static final int CS_OP_FP = 4; 402 403 // Common instruction operand access types - to be consistent across all architectures. 404 // It is possible to combine access types, for example: CS_AC_READ | CS_AC_WRITE 405 public static final int CS_AC_INVALID = 0; 406 public static final int CS_AC_READ = 1 << 0; 407 public static final int CS_AC_WRITE = 1 << 1; 408 409 // Common instruction groups - to be consistent across all architectures. 410 public static final int CS_GRP_INVALID = 0; // uninitialized/invalid group. 411 public static final int CS_GRP_JUMP = 1; // all jump instructions (conditional+direct+indirect jumps) 412 public static final int CS_GRP_CALL = 2; // all call instructions 413 public static final int CS_GRP_RET = 3; // all return instructions 414 public static final int CS_GRP_INT = 4; // all interrupt instructions (int+syscall) 415 public static final int CS_GRP_IRET = 5; // all interrupt return instructions 416 public static final int CS_GRP_PRIVILEGE = 6; // all privileged instructions 417 418 // Query id for cs_support() 419 public static final int CS_SUPPORT_DIET = CS_ARCH_ALL+1; // diet mode 420 public static final int CS_SUPPORT_X86_REDUCE = CS_ARCH_ALL+2; // X86 reduce mode 421 422 protected class NativeStruct { 423 private NativeLong csh; 424 private NativeLongByReference handleRef; 425 } 426 427 private static final CsInsn[] EMPTY_INSN = new CsInsn[0]; 428 429 protected NativeStruct ns; // for memory retention 430 private CS cs; 431 public int arch; 432 public int mode; 433 private int syntax; 434 private int detail; 435 private boolean diet; 436 Capstone(int arch, int mode)437 public Capstone(int arch, int mode) { 438 cs = (CS)Native.loadLibrary("capstone", CS.class); 439 int version = cs.cs_version(null, null); 440 if (version != (CS_API_MAJOR << 8) + CS_API_MINOR) { 441 throw new RuntimeException("Different API version between core & binding (CS_ERR_VERSION)"); 442 } 443 444 this.arch = arch; 445 this.mode = mode; 446 ns = new NativeStruct(); 447 ns.handleRef = new NativeLongByReference(); 448 if (cs.cs_open(arch, mode, ns.handleRef) != CS_ERR_OK) { 449 throw new RuntimeException("ERROR: Wrong arch or mode"); 450 } 451 ns.csh = ns.handleRef.getValue(); 452 this.detail = CS_OPT_OFF; 453 this.diet = cs.cs_support(CS_SUPPORT_DIET); 454 } 455 456 // return combined API version version()457 public int version() { 458 return cs.cs_version(null, null); 459 } 460 461 // set Assembly syntax setSyntax(int syntax)462 public void setSyntax(int syntax) { 463 if (cs.cs_option(ns.csh, CS_OPT_SYNTAX, new NativeLong(syntax)) == CS_ERR_OK) { 464 this.syntax = syntax; 465 } else { 466 throw new RuntimeException("ERROR: Failed to set assembly syntax"); 467 } 468 } 469 470 // set detail option at run-time setDetail(int opt)471 public void setDetail(int opt) { 472 if (cs.cs_option(ns.csh, CS_OPT_DETAIL, new NativeLong(opt)) == CS_ERR_OK) { 473 this.detail = opt; 474 } else { 475 throw new RuntimeException("ERROR: Failed to set detail option"); 476 } 477 } 478 479 // set mode option at run-time setMode(int opt)480 public void setMode(int opt) { 481 if (cs.cs_option(ns.csh, CS_OPT_MODE, new NativeLong(opt)) == CS_ERR_OK) { 482 this.mode = opt; 483 } else { 484 throw new RuntimeException("ERROR: Failed to set mode option"); 485 } 486 } 487 488 // destructor automatically caled at destroyed time. finalize()489 protected void finalize() { 490 // FIXME: crashed on Ubuntu 14.04 64bit, OpenJDK java 1.6.0_33 491 // cs.cs_close(ns.handleRef); 492 } 493 494 // destructor automatically caled at destroyed time. close()495 public int close() { 496 return cs.cs_close(ns.handleRef); 497 } 498 499 /** 500 * Disassemble instructions from @code assumed to be located at @address, 501 * stop when encountering first broken instruction. 502 * 503 * @param code The source machine code bytes. 504 * @param address The address of the first machine code byte. 505 * @return the array of successfully disassembled instructions, empty if no instruction could be disassembled. 506 */ disasm(byte[] code, long address)507 public CsInsn[] disasm(byte[] code, long address) { 508 return disasm(code, address, 0); 509 } 510 511 /** 512 * Disassemble up to @count instructions from @code assumed to be located at @address, 513 * stop when encountering first broken instruction. 514 * 515 * @param code The source machine code bytes. 516 * @param address The address of the first machine code byte. 517 * @param count The maximum number of instructions to disassemble, 0 for no maximum. 518 * @return the array of successfully disassembled instructions, empty if no instruction could be disassembled. 519 */ disasm(byte[] code, long address, long count)520 public CsInsn[] disasm(byte[] code, long address, long count) { 521 PointerByReference insnRef = new PointerByReference(); 522 523 NativeLong c = cs.cs_disasm(ns.csh, code, new NativeLong(code.length), address, new NativeLong(count), insnRef); 524 525 if (0 == c.intValue()) { 526 return EMPTY_INSN; 527 } 528 529 Pointer p = insnRef.getValue(); 530 _cs_insn byref = new _cs_insn(p); 531 532 CsInsn[] allInsn = fromArrayRaw((_cs_insn[]) byref.toArray(c.intValue())); 533 534 // free allocated memory 535 // cs.cs_free(p, c); 536 // FIXME(danghvu): Can't free because memory is still inside CsInsn 537 538 return allInsn; 539 } 540 strerror(int code)541 public String strerror(int code) { 542 return cs.cs_strerror(code); 543 } 544 } 545