@@ -17,6 +17,17 @@ use super::*;
17
17
18
18
const X86_CODE : & [ u8 ] = b"\x55 \x48 \x8b \x05 \xb8 \x13 \x00 \x00 " ;
19
19
const ARM_CODE : & [ u8 ] = b"\x55 \x48 \x8b \x05 \xb8 \x13 \x00 \x00 " ;
20
+ const CBPF_CODE : & [ u8 ] = b"\x94 \x09 \x00 \x00 \x37 \x13 \x03 \x00 \
21
+ \x87 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
22
+ \x07 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
23
+ \x16 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
24
+ \x80 \x00 \x00 \x00 \x00 \x00 \x00 \x00 ";
25
+ const EBPF_CODE : & [ u8 ] = b"\x97 \x09 \x00 \x00 \x37 \x13 \x03 \x00 \
26
+ \xdc \x02 \x00 \x00 \x20 \x00 \x00 \x00 \
27
+ \x30 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
28
+ \xdb \x3a \x00 \x01 \x00 \x00 \x00 \x00 \
29
+ \x84 \x02 \x00 \x00 \x00 \x00 \x00 \x00 \
30
+ \x6d \x33 \x17 \x02 \x00 \x00 \x00 \x00 ";
20
31
21
32
// Aliases for group types
22
33
const JUMP : cs_group_type:: Type = cs_group_type:: CS_GRP_JUMP ;
@@ -3244,3 +3255,185 @@ fn test_owned_insn() {
3244
3255
assert_eq ! ( format!( "{:?}" , insn) , format!( "{:?}" , owned) ) ;
3245
3256
}
3246
3257
}
3258
+
3259
+ /// Print register names
3260
+ fn reg_names ( cs : & Capstone , regs : & [ RegId ] ) -> String {
3261
+ let names: Vec < String > = regs. iter ( ) . map ( |& x| cs. reg_name ( x) . unwrap ( ) ) . collect ( ) ;
3262
+ names. join ( ", " )
3263
+ }
3264
+
3265
+ /// Print instruction group names
3266
+ fn group_names ( cs : & Capstone , regs : & [ InsnGroupId ] ) -> String {
3267
+ let names: Vec < String > = regs. iter ( ) . map ( |& x| cs. group_name ( x) . unwrap ( ) ) . collect ( ) ;
3268
+ names. join ( ", " )
3269
+ }
3270
+
3271
+ #[ test]
3272
+ fn test_cbpf ( ) {
3273
+ let cs = Capstone :: new ( )
3274
+ . bpf ( )
3275
+ . mode ( bpf:: ArchMode :: Cbpf )
3276
+ . endian ( Endian :: Little )
3277
+ . detail ( true )
3278
+ . build ( )
3279
+ . unwrap ( ) ;
3280
+ let insns = cs. disasm_all ( CBPF_CODE , 0x1000 ) ;
3281
+ match insns {
3282
+ Ok ( ins) => {
3283
+ for i in ins. as_ref ( ) {
3284
+ println ! ( ) ;
3285
+ eprintln ! ( "{}" , i) ;
3286
+
3287
+ let detail: InsnDetail = cs. insn_detail ( & i) . expect ( "Failed to get insn detail" ) ;
3288
+ let arch_detail: ArchDetail = detail. arch_detail ( ) ;
3289
+ let ops = arch_detail. operands ( ) ;
3290
+
3291
+ let output: & [ ( & str , String ) ] = & [
3292
+ ( "insn id:" , format ! ( "{:?}" , i. id( ) . 0 ) ) ,
3293
+ ( "bytes:" , format ! ( "{:?}" , i. bytes( ) ) ) ,
3294
+ ( "read regs:" , reg_names ( & cs, detail. regs_read ( ) ) ) ,
3295
+ ( "write regs:" , reg_names ( & cs, detail. regs_write ( ) ) ) ,
3296
+ ( "insn groups:" , group_names ( & cs, detail. groups ( ) ) ) ,
3297
+ ] ;
3298
+
3299
+ for & ( ref name, ref message) in output. iter ( ) {
3300
+ eprintln ! ( "{:4}{:12} {}" , "" , name, message) ;
3301
+ }
3302
+
3303
+ println ! ( "{:4}operands: {}" , "" , ops. len( ) ) ;
3304
+ for op in ops {
3305
+ eprintln ! ( "{:8}{:?}" , "" , op) ;
3306
+ }
3307
+ }
3308
+ }
3309
+
3310
+ Err ( e) => {
3311
+ eprintln ! ( "{:?}" , e) ;
3312
+ assert ! ( false ) ;
3313
+ }
3314
+ }
3315
+ }
3316
+
3317
+ #[ test]
3318
+ fn test_ebpf ( ) {
3319
+ let cs = Capstone :: new ( )
3320
+ . bpf ( )
3321
+ . mode ( bpf:: ArchMode :: Ebpf )
3322
+ . endian ( Endian :: Little )
3323
+ . detail ( true )
3324
+ . build ( )
3325
+ . unwrap ( ) ;
3326
+ let insns = cs. disasm_all ( EBPF_CODE , 0x1000 ) ;
3327
+ match insns {
3328
+ Ok ( ins) => {
3329
+ for i in ins. as_ref ( ) {
3330
+ println ! ( ) ;
3331
+ eprintln ! ( "{}" , i) ;
3332
+
3333
+ let detail: InsnDetail = cs. insn_detail ( & i) . expect ( "Failed to get insn detail" ) ;
3334
+ let arch_detail: ArchDetail = detail. arch_detail ( ) ;
3335
+ let ops = arch_detail. operands ( ) ;
3336
+
3337
+ let output: & [ ( & str , String ) ] = & [
3338
+ ( "insn id:" , format ! ( "{:?}" , i. id( ) . 0 ) ) ,
3339
+ ( "bytes:" , format ! ( "{:?}" , i. bytes( ) ) ) ,
3340
+ ( "read regs:" , reg_names ( & cs, detail. regs_read ( ) ) ) ,
3341
+ ( "write regs:" , reg_names ( & cs, detail. regs_write ( ) ) ) ,
3342
+ ( "insn groups:" , group_names ( & cs, detail. groups ( ) ) ) ,
3343
+ ] ;
3344
+
3345
+ for & ( ref name, ref message) in output. iter ( ) {
3346
+ eprintln ! ( "{:4}{:12} {}" , "" , name, message) ;
3347
+ }
3348
+
3349
+ println ! ( "{:4}operands: {}" , "" , ops. len( ) ) ;
3350
+ for op in ops {
3351
+ eprintln ! ( "{:8}{:?}" , "" , op) ;
3352
+ }
3353
+ }
3354
+ }
3355
+
3356
+ Err ( e) => {
3357
+ eprintln ! ( "{:?}" , e) ;
3358
+ assert ! ( false ) ;
3359
+ }
3360
+ }
3361
+ }
3362
+
3363
+ #[ test]
3364
+ fn test_arch_bpf_detail ( ) {
3365
+ use crate :: arch:: bpf:: BpfOperand :: * ;
3366
+ use crate :: arch:: bpf:: BpfReg :: * ;
3367
+ use crate :: arch:: bpf:: * ;
3368
+ use capstone_sys:: * ;
3369
+
3370
+ test_arch_mode_endian_insns_detail (
3371
+ & mut Capstone :: new ( )
3372
+ . bpf ( )
3373
+ . mode ( bpf:: ArchMode :: Ebpf )
3374
+ . endian ( Endian :: Little )
3375
+ . detail ( true )
3376
+ . build ( )
3377
+ . unwrap ( ) ,
3378
+ Arch :: BPF ,
3379
+ Mode :: Ebpf ,
3380
+ None ,
3381
+ & [ ] ,
3382
+ & [
3383
+ // r1 = 0x1
3384
+ DII :: new (
3385
+ "mov64" ,
3386
+ b"\xb7 \x01 \x00 \x00 \x01 \x00 \x00 \x00 " ,
3387
+ & [ Reg ( RegId ( BPF_REG_R1 as RegIdInt ) ) , Imm ( 1 ) ] ,
3388
+ ) ,
3389
+ // r0 = *(u32 *)(r10 - 0xc)
3390
+ DII :: new (
3391
+ "ldxw" ,
3392
+ b"\x61 \xa0 \xf4 \xff \x00 \x00 \x00 \x00 " ,
3393
+ & [
3394
+ Reg ( RegId ( BPF_REG_R0 as RegIdInt ) ) ,
3395
+ Mem ( BpfOpMem ( bpf_op_mem {
3396
+ base : BPF_REG_R10 ,
3397
+ disp : 0xfff4 ,
3398
+ } ) ) ,
3399
+ ] ,
3400
+ ) ,
3401
+ // *(u32 *)(r10 - 0xc) = r1
3402
+ DII :: new (
3403
+ "stxw" ,
3404
+ b"\x63 \x1a \xf4 \xff \x00 \x00 \x00 \x00 " ,
3405
+ & [
3406
+ Mem ( BpfOpMem ( bpf_op_mem {
3407
+ base : BPF_REG_R10 ,
3408
+ disp : 0xfff4 ,
3409
+ } ) ) ,
3410
+ Reg ( RegId ( BPF_REG_R1 as RegIdInt ) ) ,
3411
+ ] ,
3412
+ ) ,
3413
+ // exit
3414
+ DII :: new ( "exit" , b"\x95 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " , & [ ] ) ,
3415
+ ] ,
3416
+ ) ;
3417
+
3418
+ test_arch_mode_endian_insns_detail (
3419
+ & mut Capstone :: new ( )
3420
+ . bpf ( )
3421
+ . mode ( bpf:: ArchMode :: Cbpf )
3422
+ . endian ( Endian :: Little )
3423
+ . detail ( true )
3424
+ . build ( )
3425
+ . unwrap ( ) ,
3426
+ Arch :: BPF ,
3427
+ Mode :: Cbpf ,
3428
+ None ,
3429
+ & [ ] ,
3430
+ & [
3431
+ DII :: new ( "txa" , b"\x87 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " , & [ ] ) ,
3432
+ DII :: new (
3433
+ "ret" ,
3434
+ b"\x16 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ,
3435
+ & [ Reg ( RegId ( BPF_REG_A as RegIdInt ) ) ] ,
3436
+ ) ,
3437
+ ] ,
3438
+ ) ;
3439
+ }
0 commit comments