1 // Capstone Java binding 2 // By Nguyen Anh Quynh & Dang Hoang Vu, 2013 3 4 import capstone.Capstone; 5 import capstone.X86; 6 7 import static capstone.X86_const.*; 8 9 public class TestX86 { 10 hexString2Byte(String s)11 static byte[] hexString2Byte(String s) { 12 // from http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java 13 int len = s.length(); 14 byte[] data = new byte[len / 2]; 15 for (int i = 0; i < len; i += 2) { 16 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 17 + Character.digit(s.charAt(i+1), 16)); 18 } 19 return data; 20 } 21 22 static final String X86_CODE64 = "55488b05b8130000"; 23 static final String X86_CODE16 = "8d4c320801d881c6341200000523010000368b849123010000418d8439896700008d8789670000b4c6"; 24 static final String X86_CODE32 = "8d4c320801d881c6341200000523010000368b849123010000418d8439896700008d8789670000b4c6"; 25 26 public static Capstone cs; 27 hex(int i)28 private static String hex(int i) { 29 return Integer.toString(i, 16); 30 } 31 hex(long i)32 private static String hex(long i) { 33 return Long.toString(i, 16); 34 } 35 array2hex(byte[] arr)36 private static String array2hex(byte[] arr) { 37 String ret = ""; 38 for (int i=0 ;i<arr.length; i++) 39 ret += String.format("0x%02x ", arr[i]); 40 return ret; 41 } 42 print_ins_detail(Capstone.CsInsn ins)43 public static void print_ins_detail(Capstone.CsInsn ins) { 44 System.out.printf("0x%x:\t%s\t%s\n", ins.address, ins.mnemonic, ins.opStr); 45 46 X86.OpInfo operands = (X86.OpInfo) ins.operands; 47 48 System.out.printf("\tPrefix: %s\n", array2hex(operands.prefix)); 49 50 System.out.printf("\tOpcode: %s\n", array2hex(operands.opcode)); 51 52 // print REX prefix (non-zero value is relevant for x86_64) 53 System.out.printf("\trex: 0x%x\n", operands.rex); 54 55 // print address size 56 System.out.printf("\taddr_size: %d\n", operands.addrSize); 57 58 // print modRM byte 59 System.out.printf("\tmodrm: 0x%x\n", operands.modrm); 60 61 // print displacement value 62 System.out.printf("\tdisp: 0x%x\n", operands.disp); 63 64 // SIB is not available in 16-bit mode 65 if ( (cs.mode & Capstone.CS_MODE_16) == 0) { 66 // print SIB byte 67 System.out.printf("\tsib: 0x%x\n", operands.sib); 68 if (operands.sib != 0) 69 System.out.printf("\t\tsib_base: %s\n\t\tsib_index: %s\n\t\tsib_scale: %d\n", 70 ins.regName(operands.sibBase), ins.regName(operands.sibIndex), operands.sibScale); 71 } 72 73 if (operands.sseCC != 0) 74 System.out.printf("\tsse_cc: %u\n", operands.sseCC); 75 76 if (operands.avxCC != 0) 77 System.out.printf("\tavx_cc: %u\n", operands.avxCC); 78 79 if (operands.avxSae) 80 System.out.printf("\tavx_sae: TRUE\n"); 81 82 if (operands.avxRm != 0) 83 System.out.printf("\tavx_rm: %u\n", operands.avxRm); 84 85 int count = ins.opCount(X86_OP_IMM); 86 if (count > 0) { 87 System.out.printf("\timm_count: %d\n", count); 88 for (int i=0; i<count; i++) { 89 int index = ins.opIndex(X86_OP_IMM, i + 1); 90 System.out.printf("\t\timms[%d]: 0x%x\n", i+1, (operands.op[index].value.imm)); 91 } 92 } 93 94 if (operands.op.length != 0) { 95 System.out.printf("\top_count: %d\n", operands.op.length); 96 for (int c=0; c<operands.op.length; c++) { 97 X86.Operand i = (X86.Operand) operands.op[c]; 98 String imm = hex(i.value.imm); 99 if (i.type == X86_OP_REG) 100 System.out.printf("\t\toperands[%d].type: REG = %s\n", c, ins.regName(i.value.reg)); 101 if (i.type == X86_OP_IMM) 102 System.out.printf("\t\toperands[%d].type: IMM = 0x%x\n", c, i.value.imm); 103 if (i.type == X86_OP_FP) 104 System.out.printf("\t\toperands[%d].type: FP = %f\n", c, i.value.fp); 105 if (i.type == X86_OP_MEM) { 106 System.out.printf("\t\toperands[%d].type: MEM\n",c); 107 String segment = ins.regName(i.value.mem.segment); 108 String base = ins.regName(i.value.mem.base); 109 String index = ins.regName(i.value.mem.index); 110 if (segment != null) 111 System.out.printf("\t\t\toperands[%d].mem.segment: REG = %s\n", c, segment); 112 if (base != null) 113 System.out.printf("\t\t\toperands[%d].mem.base: REG = %s\n", c, base); 114 if (index != null) 115 System.out.printf("\t\t\toperands[%d].mem.index: REG = %s\n", c, index); 116 if (i.value.mem.scale != 1) 117 System.out.printf("\t\t\toperands[%d].mem.scale: %d\n", c, i.value.mem.scale); 118 if (i.value.mem.disp != 0) 119 System.out.printf("\t\t\toperands[%d].mem.disp: 0x%x\n", c, i.value.mem.disp); 120 } 121 122 // AVX broadcast type 123 if (i.avx_bcast != X86_AVX_BCAST_INVALID) { 124 System.out.printf("\t\toperands[%d].avx_bcast: %d\n", c, i.avx_bcast); 125 } 126 127 // AVX zero opmask {z} 128 if (i.avx_zero_opmask) { 129 System.out.printf("\t\toperands[%d].avx_zero_opmask: TRUE\n", c); 130 } 131 132 System.out.printf("\t\toperands[%d].size: %d\n", c, i.size); 133 } 134 } 135 } 136 main(String argv[])137 public static void main(String argv[]) { 138 139 final Test.platform[] all_tests = { 140 new Test.platform(Capstone.CS_ARCH_X86, Capstone.CS_MODE_16, hexString2Byte(X86_CODE16), "X86 16bit (Intel syntax)"), 141 new Test.platform(Capstone.CS_ARCH_X86, Capstone.CS_MODE_32, Capstone.CS_OPT_SYNTAX_ATT, hexString2Byte(X86_CODE32), "X86 32 (AT&T syntax)"), 142 new Test.platform(Capstone.CS_ARCH_X86, Capstone.CS_MODE_32, hexString2Byte(X86_CODE32), "X86 32 (Intel syntax)"), 143 new Test.platform(Capstone.CS_ARCH_X86, Capstone.CS_MODE_64, hexString2Byte(X86_CODE64), "X86 64 (Intel syntax)"), 144 }; 145 146 for (int i=0; i<all_tests.length; i++) { 147 Test.platform test = all_tests[i]; 148 System.out.println(new String(new char[16]).replace("\0", "*")); 149 System.out.println("Platform: " + test.comment); 150 System.out.println("Code: " + Test.stringToHex(test.code)); 151 System.out.println("Disasm:"); 152 153 cs = new Capstone(test.arch, test.mode); 154 cs.setDetail(Capstone.CS_OPT_ON); 155 if (test.syntax != 0) { 156 cs.setSyntax(test.syntax); 157 } 158 Capstone.CsInsn[] all_ins = cs.disasm(test.code, 0x1000); 159 160 for (int j = 0; j < all_ins.length; j++) { 161 print_ins_detail(all_ins[j]); 162 System.out.println(); 163 } 164 165 System.out.printf("0x%x:\n\n", all_ins[all_ins.length-1].address + all_ins[all_ins.length-1].size); 166 167 // Close when done 168 cs.close(); 169 } 170 } 171 172 } 173