2013-11-27 12:28:41 +08:00
// Capstone Java binding
// By Nguyen Anh Quynh & Dang Hoang Vu, 2013
2013-11-28 05:09:07 +08:00
import capstone.Capstone ;
import capstone.Arm ;
2013-12-02 03:32:16 +08:00
import static capstone.Arm_const.* ;
2013-11-27 12:28:41 +08:00
public class TestArm {
static byte [ ] hexString2Byte ( String s ) {
// from http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
int len = s . length ( ) ;
byte [ ] data = new byte [ len / 2 ] ;
for ( int i = 0 ; i < len ; i + = 2 ) {
data [ i / 2 ] = ( byte ) ( ( Character . digit ( s . charAt ( i ) , 16 ) < < 4 )
+ Character . digit ( s . charAt ( i + 1 ) , 16 ) ) ;
}
return data ;
}
2014-09-28 06:53:49 +08:00
static final String ARM_CODE = " EDFFFFEB04e02de500000000e08322e5f102030e0000a0e30230c1e7000053e3000201f10540d0e8 " ;
2013-11-27 12:28:41 +08:00
static final String ARM_CODE2 = " d1e800f0f02404071f3cf2c000004ff00001466c " ;
2014-09-28 06:53:49 +08:00
static final String THUMB_CODE2 = " 4ff00001bde80088d1e800f018bfadbff3ff0b0c86f3008980f3008c4ffa99f6d0ffa201 " ;
static final String THUMB_CODE = " 7047eb4683b0c9681fb130bfaff32084 " ;
2013-11-27 12:28:41 +08:00
public static Capstone cs ;
private static String hex ( int i ) {
return Integer . toString ( i , 16 ) ;
}
private static String hex ( long i ) {
return Long . toString ( i , 16 ) ;
}
2013-12-17 13:25:57 +08:00
public static void print_ins_detail ( Capstone . CsInsn ins ) {
System . out . printf ( " 0x%x: \ t%s \ t%s \ n " , ins . address , ins . mnemonic , ins . opStr ) ;
2013-11-27 12:28:41 +08:00
2013-12-17 13:25:57 +08:00
Arm . OpInfo operands = ( Arm . OpInfo ) ins . operands ;
2013-11-27 12:28:41 +08:00
2013-12-17 13:25:57 +08:00
if ( operands . op . length ! = 0 ) {
System . out . printf ( " \ top_count: %d \ n " , operands . op . length ) ;
for ( int c = 0 ; c < operands . op . length ; c + + ) {
Arm . Operand i = ( Arm . Operand ) operands . op [ c ] ;
2013-11-27 12:28:41 +08:00
String imm = hex ( i . value . imm ) ;
2014-09-28 06:53:49 +08:00
if ( i . type = = ARM_OP_SYSREG )
System . out . printf ( " \ t \ toperands[%d].type: SYSREG = %d \ n " , c , i . value . reg ) ;
2013-12-02 03:32:16 +08:00
if ( i . type = = ARM_OP_REG )
2013-12-17 13:25:57 +08:00
System . out . printf ( " \ t \ toperands[%d].type: REG = %s \ n " , c , ins . regName ( i . value . reg ) ) ;
2013-12-02 03:32:16 +08:00
if ( i . type = = ARM_OP_IMM )
2013-11-28 00:58:31 +08:00
System . out . printf ( " \ t \ toperands[%d].type: IMM = 0x%x \ n " , c , i . value . imm ) ;
2013-12-02 03:32:16 +08:00
if ( i . type = = ARM_OP_PIMM )
2013-11-28 00:58:31 +08:00
System . out . printf ( " \ t \ toperands[%d].type: P-IMM = %d \ n " , c , i . value . imm ) ;
2013-12-02 03:32:16 +08:00
if ( i . type = = ARM_OP_CIMM )
2013-11-28 00:58:31 +08:00
System . out . printf ( " \ t \ toperands[%d].type: C-IMM = %d \ n " , c , i . value . imm ) ;
2014-09-28 06:53:49 +08:00
if ( i . type = = ARM_OP_SETEND )
System . out . printf ( " \ t \ toperands[%d].type: SETEND = %s \ n " , c , i . value . setend = = ARM_SETEND_BE ? " be " : " le " ) ;
2013-12-02 03:32:16 +08:00
if ( i . type = = ARM_OP_FP )
2013-11-27 12:42:30 +08:00
System . out . printf ( " \ t \ toperands[%d].type: FP = %f \ n " , c , i . value . fp ) ;
2013-12-02 03:32:16 +08:00
if ( i . type = = ARM_OP_MEM ) {
2013-11-27 12:28:41 +08:00
System . out . printf ( " \ t \ toperands[%d].type: MEM \ n " , c ) ;
2013-12-17 13:25:57 +08:00
String base = ins . regName ( i . value . mem . base ) ;
String index = ins . regName ( i . value . mem . index ) ;
2013-11-27 12:28:41 +08:00
if ( base ! = null )
System . out . printf ( " \ t \ t \ toperands[%d].mem.base: REG = %s \ n " , c , base ) ;
if ( index ! = null )
System . out . printf ( " \ t \ t \ toperands[%d].mem.index: REG = %s \ n " , c , index ) ;
if ( i . value . mem . scale ! = 1 )
2013-11-28 00:58:31 +08:00
System . out . printf ( " \ t \ t \ toperands[%d].mem.scale: %d \ n " , c , ( i . value . mem . scale ) ) ;
2013-11-27 12:28:41 +08:00
if ( i . value . mem . disp ! = 0 )
2013-11-28 00:58:31 +08:00
System . out . printf ( " \ t \ t \ toperands[%d].mem.disp: 0x%x \ n " , c , ( i . value . mem . disp ) ) ;
2013-11-27 12:28:41 +08:00
}
2014-09-28 06:53:49 +08:00
if ( i . vector_index > 0 )
System . out . printf ( " \ t \ t \ toperands[%d].vector_index = %d \ n " , c , ( i . vector_index ) ) ;
2013-12-02 03:32:16 +08:00
if ( i . shift . type ! = ARM_SFT_INVALID & & i . shift . value > 0 )
2014-09-28 06:53:49 +08:00
System . out . printf ( " \ t \ t \ tShift: %d = %d \ n " , i . shift . type , i . shift . value ) ;
2013-11-27 12:28:41 +08:00
}
2014-09-28 06:53:49 +08:00
}
if ( operands . writeback )
System . out . println ( " \ tWrite-back: True " ) ;
2013-11-28 11:41:17 +08:00
2014-09-28 06:53:49 +08:00
if ( operands . updateFlags )
System . out . println ( " \ tUpdate-flags: True " ) ;
2013-11-28 11:41:17 +08:00
2014-09-28 06:53:49 +08:00
if ( operands . cc ! = ARM_CC_AL & & operands . cc ! = ARM_CC_INVALID )
System . out . printf ( " \ tCode condition: %d \ n " , operands . cc ) ;
if ( operands . cpsMode > 0 )
System . out . printf ( " \ tCPSI-mode: %d \ n " , operands . cpsMode ) ;
if ( operands . cpsFlag > 0 )
System . out . printf ( " \ tCPSI-flag: %d \ n " , operands . cpsFlag ) ;
if ( operands . vectorData > 0 )
System . out . printf ( " \ tVector-data: %d \ n " , operands . vectorData ) ;
if ( operands . vectorSize > 0 )
System . out . printf ( " \ tVector-size: %d \ n " , operands . vectorSize ) ;
if ( operands . usermode )
System . out . printf ( " \ tUser-mode: True \ n " ) ;
2013-11-27 12:28:41 +08:00
}
public static void main ( String argv [ ] ) {
final Test . platform [ ] all_tests = {
2013-11-27 12:42:30 +08:00
new Test . platform ( Capstone . CS_ARCH_ARM , Capstone . CS_MODE_ARM , hexString2Byte ( ARM_CODE ) , " ARM " ) ,
new Test . platform ( Capstone . CS_ARCH_ARM , Capstone . CS_MODE_THUMB , hexString2Byte ( THUMB_CODE ) , " Thumb " ) ,
new Test . platform ( Capstone . CS_ARCH_ARM , Capstone . CS_MODE_THUMB , hexString2Byte ( ARM_CODE2 ) , " Thumb-mixed " ) ,
2014-05-14 15:37:08 +08:00
new Test . platform ( Capstone . CS_ARCH_ARM , Capstone . CS_MODE_THUMB , Capstone . CS_OPT_SYNTAX_NOREGNAME , hexString2Byte ( THUMB_CODE2 ) , " Thumb-2 & register named with numbers " ) ,
2013-11-27 12:28:41 +08:00
} ;
for ( int i = 0 ; i < all_tests . length ; i + + ) {
Test . platform test = all_tests [ i ] ;
2013-11-28 11:41:17 +08:00
System . out . println ( new String ( new char [ 16 ] ) . replace ( " \ 0 " , " * " ) ) ;
2013-11-27 12:28:41 +08:00
System . out . println ( " Platform: " + test . comment ) ;
2013-11-28 11:41:17 +08:00
System . out . println ( " Code: " + Test . stringToHex ( test . code ) ) ;
2013-11-27 12:28:41 +08:00
System . out . println ( " Disasm: " ) ;
cs = new Capstone ( test . arch , test . mode ) ;
2014-01-07 23:47:18 +08:00
cs . setDetail ( Capstone . CS_OPT_ON ) ;
2014-05-14 15:37:08 +08:00
if ( test . syntax ! = 0 )
cs . setSyntax ( test . syntax ) ;
2013-12-17 13:25:57 +08:00
Capstone . CsInsn [ ] all_ins = cs . disasm ( test . code , 0x1000 ) ;
2013-11-27 12:28:41 +08:00
for ( int j = 0 ; j < all_ins . length ; j + + ) {
print_ins_detail ( all_ins [ j ] ) ;
System . out . println ( ) ;
}
2013-11-28 00:58:31 +08:00
System . out . printf ( " 0x%x: \ n \ n " , ( all_ins [ all_ins . length - 1 ] . address + all_ins [ all_ins . length - 1 ] . size ) ) ;
2013-11-27 12:28:41 +08:00
}
}
}