crabstone 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES.md +61 -0
- data/LICENSE +25 -0
- data/MANIFEST +312 -0
- data/README.md +103 -0
- data/Rakefile +27 -0
- data/bin/genconst +66 -0
- data/bin/genreg +99 -0
- data/crabstone.gemspec +27 -0
- data/examples/hello_world.rb +43 -0
- data/lib/arch/arm.rb +128 -0
- data/lib/arch/arm64.rb +167 -0
- data/lib/arch/arm64_const.rb +1055 -0
- data/lib/arch/arm64_registers.rb +295 -0
- data/lib/arch/arm_const.rb +777 -0
- data/lib/arch/arm_registers.rb +149 -0
- data/lib/arch/mips.rb +78 -0
- data/lib/arch/mips_const.rb +850 -0
- data/lib/arch/mips_registers.rb +208 -0
- data/lib/arch/ppc.rb +90 -0
- data/lib/arch/ppc_const.rb +1181 -0
- data/lib/arch/ppc_registers.rb +209 -0
- data/lib/arch/sparc.rb +79 -0
- data/lib/arch/sparc_const.rb +461 -0
- data/lib/arch/sparc_registers.rb +121 -0
- data/lib/arch/systemz.rb +79 -0
- data/lib/arch/sysz_const.rb +779 -0
- data/lib/arch/sysz_registers.rb +66 -0
- data/lib/arch/x86.rb +107 -0
- data/lib/arch/x86_const.rb +1698 -0
- data/lib/arch/x86_registers.rb +265 -0
- data/lib/arch/xcore.rb +78 -0
- data/lib/arch/xcore_const.rb +185 -0
- data/lib/arch/xcore_registers.rb +57 -0
- data/lib/crabstone.rb +564 -0
- data/test/MC/AArch64/basic-a64-instructions.s.cs +2014 -0
- data/test/MC/AArch64/gicv3-regs.s.cs +111 -0
- data/test/MC/AArch64/neon-2velem.s.cs +113 -0
- data/test/MC/AArch64/neon-3vdiff.s.cs +143 -0
- data/test/MC/AArch64/neon-aba-abd.s.cs +28 -0
- data/test/MC/AArch64/neon-across.s.cs +40 -0
- data/test/MC/AArch64/neon-add-pairwise.s.cs +11 -0
- data/test/MC/AArch64/neon-add-sub-instructions.s.cs +21 -0
- data/test/MC/AArch64/neon-bitwise-instructions.s.cs +17 -0
- data/test/MC/AArch64/neon-compare-instructions.s.cs +136 -0
- data/test/MC/AArch64/neon-crypto.s.cs +15 -0
- data/test/MC/AArch64/neon-extract.s.cs +3 -0
- data/test/MC/AArch64/neon-facge-facgt.s.cs +13 -0
- data/test/MC/AArch64/neon-frsqrt-frecp.s.cs +7 -0
- data/test/MC/AArch64/neon-halving-add-sub.s.cs +25 -0
- data/test/MC/AArch64/neon-max-min-pairwise.s.cs +37 -0
- data/test/MC/AArch64/neon-max-min.s.cs +37 -0
- data/test/MC/AArch64/neon-mla-mls-instructions.s.cs +19 -0
- data/test/MC/AArch64/neon-mov.s.cs +74 -0
- data/test/MC/AArch64/neon-mul-div-instructions.s.cs +24 -0
- data/test/MC/AArch64/neon-perm.s.cs +43 -0
- data/test/MC/AArch64/neon-rounding-halving-add.s.cs +13 -0
- data/test/MC/AArch64/neon-rounding-shift.s.cs +15 -0
- data/test/MC/AArch64/neon-saturating-add-sub.s.cs +29 -0
- data/test/MC/AArch64/neon-saturating-rounding-shift.s.cs +15 -0
- data/test/MC/AArch64/neon-saturating-shift.s.cs +15 -0
- data/test/MC/AArch64/neon-scalar-abs.s.cs +8 -0
- data/test/MC/AArch64/neon-scalar-add-sub.s.cs +3 -0
- data/test/MC/AArch64/neon-scalar-by-elem-mla.s.cs +13 -0
- data/test/MC/AArch64/neon-scalar-by-elem-mul.s.cs +13 -0
- data/test/MC/AArch64/neon-scalar-by-elem-saturating-mla.s.cs +15 -0
- data/test/MC/AArch64/neon-scalar-by-elem-saturating-mul.s.cs +18 -0
- data/test/MC/AArch64/neon-scalar-compare.s.cs +12 -0
- data/test/MC/AArch64/neon-scalar-cvt.s.cs +34 -0
- data/test/MC/AArch64/neon-scalar-dup.s.cs +23 -0
- data/test/MC/AArch64/neon-scalar-extract-narrow.s.cs +10 -0
- data/test/MC/AArch64/neon-scalar-fp-compare.s.cs +21 -0
- data/test/MC/AArch64/neon-scalar-mul.s.cs +13 -0
- data/test/MC/AArch64/neon-scalar-neg.s.cs +6 -0
- data/test/MC/AArch64/neon-scalar-recip.s.cs +11 -0
- data/test/MC/AArch64/neon-scalar-reduce-pairwise.s.cs +3 -0
- data/test/MC/AArch64/neon-scalar-rounding-shift.s.cs +3 -0
- data/test/MC/AArch64/neon-scalar-saturating-add-sub.s.cs +25 -0
- data/test/MC/AArch64/neon-scalar-saturating-rounding-shift.s.cs +9 -0
- data/test/MC/AArch64/neon-scalar-saturating-shift.s.cs +9 -0
- data/test/MC/AArch64/neon-scalar-shift-imm.s.cs +42 -0
- data/test/MC/AArch64/neon-scalar-shift.s.cs +3 -0
- data/test/MC/AArch64/neon-shift-left-long.s.cs +13 -0
- data/test/MC/AArch64/neon-shift.s.cs +22 -0
- data/test/MC/AArch64/neon-simd-copy.s.cs +42 -0
- data/test/MC/AArch64/neon-simd-ldst-multi-elem.s.cs +197 -0
- data/test/MC/AArch64/neon-simd-ldst-one-elem.s.cs +129 -0
- data/test/MC/AArch64/neon-simd-misc.s.cs +213 -0
- data/test/MC/AArch64/neon-simd-post-ldst-multi-elem.s.cs +107 -0
- data/test/MC/AArch64/neon-simd-shift.s.cs +151 -0
- data/test/MC/AArch64/neon-tbl.s.cs +21 -0
- data/test/MC/AArch64/trace-regs.s.cs +383 -0
- data/test/MC/ARM/arm-aliases.s.cs +7 -0
- data/test/MC/ARM/arm-arithmetic-aliases.s.cs +50 -0
- data/test/MC/ARM/arm-it-block.s.cs +2 -0
- data/test/MC/ARM/arm-memory-instructions.s.cs +138 -0
- data/test/MC/ARM/arm-shift-encoding.s.cs +50 -0
- data/test/MC/ARM/arm-thumb-trustzone.s.cs +3 -0
- data/test/MC/ARM/arm-trustzone.s.cs +3 -0
- data/test/MC/ARM/arm_addrmode2.s.cs +15 -0
- data/test/MC/ARM/arm_addrmode3.s.cs +9 -0
- data/test/MC/ARM/arm_instructions.s.cs +25 -0
- data/test/MC/ARM/basic-arm-instructions-v8.s.cs +10 -0
- data/test/MC/ARM/basic-arm-instructions.s.cs +997 -0
- data/test/MC/ARM/basic-thumb-instructions.s.cs +130 -0
- data/test/MC/ARM/basic-thumb2-instructions-v8.s.cs +1 -0
- data/test/MC/ARM/basic-thumb2-instructions.s.cs +1242 -0
- data/test/MC/ARM/crc32-thumb.s.cs +7 -0
- data/test/MC/ARM/crc32.s.cs +7 -0
- data/test/MC/ARM/dot-req.s.cs +3 -0
- data/test/MC/ARM/fp-armv8.s.cs +52 -0
- data/test/MC/ARM/idiv-thumb.s.cs +3 -0
- data/test/MC/ARM/idiv.s.cs +3 -0
- data/test/MC/ARM/load-store-acquire-release-v8-thumb.s.cs +15 -0
- data/test/MC/ARM/load-store-acquire-release-v8.s.cs +15 -0
- data/test/MC/ARM/mode-switch.s.cs +7 -0
- data/test/MC/ARM/neon-abs-encoding.s.cs +15 -0
- data/test/MC/ARM/neon-absdiff-encoding.s.cs +39 -0
- data/test/MC/ARM/neon-add-encoding.s.cs +119 -0
- data/test/MC/ARM/neon-bitcount-encoding.s.cs +15 -0
- data/test/MC/ARM/neon-bitwise-encoding.s.cs +126 -0
- data/test/MC/ARM/neon-cmp-encoding.s.cs +88 -0
- data/test/MC/ARM/neon-convert-encoding.s.cs +27 -0
- data/test/MC/ARM/neon-crypto.s.cs +16 -0
- data/test/MC/ARM/neon-dup-encoding.s.cs +13 -0
- data/test/MC/ARM/neon-minmax-encoding.s.cs +57 -0
- data/test/MC/ARM/neon-mov-encoding.s.cs +76 -0
- data/test/MC/ARM/neon-mul-accum-encoding.s.cs +39 -0
- data/test/MC/ARM/neon-mul-encoding.s.cs +72 -0
- data/test/MC/ARM/neon-neg-encoding.s.cs +15 -0
- data/test/MC/ARM/neon-pairwise-encoding.s.cs +47 -0
- data/test/MC/ARM/neon-reciprocal-encoding.s.cs +13 -0
- data/test/MC/ARM/neon-reverse-encoding.s.cs +13 -0
- data/test/MC/ARM/neon-satshift-encoding.s.cs +75 -0
- data/test/MC/ARM/neon-shift-encoding.s.cs +238 -0
- data/test/MC/ARM/neon-shiftaccum-encoding.s.cs +97 -0
- data/test/MC/ARM/neon-shuffle-encoding.s.cs +59 -0
- data/test/MC/ARM/neon-sub-encoding.s.cs +82 -0
- data/test/MC/ARM/neon-table-encoding.s.cs +9 -0
- data/test/MC/ARM/neon-v8.s.cs +38 -0
- data/test/MC/ARM/neon-vld-encoding.s.cs +213 -0
- data/test/MC/ARM/neon-vst-encoding.s.cs +120 -0
- data/test/MC/ARM/neon-vswp.s.cs +3 -0
- data/test/MC/ARM/neont2-abs-encoding.s.cs +15 -0
- data/test/MC/ARM/neont2-absdiff-encoding.s.cs +39 -0
- data/test/MC/ARM/neont2-add-encoding.s.cs +65 -0
- data/test/MC/ARM/neont2-bitcount-encoding.s.cs +15 -0
- data/test/MC/ARM/neont2-bitwise-encoding.s.cs +15 -0
- data/test/MC/ARM/neont2-cmp-encoding.s.cs +17 -0
- data/test/MC/ARM/neont2-convert-encoding.s.cs +19 -0
- data/test/MC/ARM/neont2-dup-encoding.s.cs +19 -0
- data/test/MC/ARM/neont2-minmax-encoding.s.cs +57 -0
- data/test/MC/ARM/neont2-mov-encoding.s.cs +58 -0
- data/test/MC/ARM/neont2-mul-accum-encoding.s.cs +41 -0
- data/test/MC/ARM/neont2-mul-encoding.s.cs +31 -0
- data/test/MC/ARM/neont2-neg-encoding.s.cs +15 -0
- data/test/MC/ARM/neont2-pairwise-encoding.s.cs +43 -0
- data/test/MC/ARM/neont2-reciprocal-encoding.s.cs +13 -0
- data/test/MC/ARM/neont2-reverse-encoding.s.cs +13 -0
- data/test/MC/ARM/neont2-satshift-encoding.s.cs +75 -0
- data/test/MC/ARM/neont2-shift-encoding.s.cs +80 -0
- data/test/MC/ARM/neont2-shiftaccum-encoding.s.cs +97 -0
- data/test/MC/ARM/neont2-shuffle-encoding.s.cs +23 -0
- data/test/MC/ARM/neont2-sub-encoding.s.cs +23 -0
- data/test/MC/ARM/neont2-table-encoding.s.cs +9 -0
- data/test/MC/ARM/neont2-vld-encoding.s.cs +51 -0
- data/test/MC/ARM/neont2-vst-encoding.s.cs +48 -0
- data/test/MC/ARM/simple-fp-encoding.s.cs +157 -0
- data/test/MC/ARM/thumb-fp-armv8.s.cs +51 -0
- data/test/MC/ARM/thumb-hints.s.cs +12 -0
- data/test/MC/ARM/thumb-neon-crypto.s.cs +16 -0
- data/test/MC/ARM/thumb-neon-v8.s.cs +38 -0
- data/test/MC/ARM/thumb-shift-encoding.s.cs +19 -0
- data/test/MC/ARM/thumb.s.cs +19 -0
- data/test/MC/ARM/thumb2-b.w-encodingT4.s.cs +2 -0
- data/test/MC/ARM/thumb2-branches.s.cs +85 -0
- data/test/MC/ARM/thumb2-mclass.s.cs +41 -0
- data/test/MC/ARM/thumb2-narrow-dp.ll.cs +379 -0
- data/test/MC/ARM/thumb2-pldw.s.cs +2 -0
- data/test/MC/ARM/vfp4-thumb.s.cs +13 -0
- data/test/MC/ARM/vfp4.s.cs +13 -0
- data/test/MC/ARM/vpush-vpop-thumb.s.cs +9 -0
- data/test/MC/ARM/vpush-vpop.s.cs +9 -0
- data/test/MC/Mips/hilo-addressing.s.cs +4 -0
- data/test/MC/Mips/micromips-alu-instructions-EB.s.cs +33 -0
- data/test/MC/Mips/micromips-alu-instructions.s.cs +33 -0
- data/test/MC/Mips/micromips-branch-instructions-EB.s.cs +11 -0
- data/test/MC/Mips/micromips-branch-instructions.s.cs +11 -0
- data/test/MC/Mips/micromips-expansions.s.cs +20 -0
- data/test/MC/Mips/micromips-jump-instructions-EB.s.cs +5 -0
- data/test/MC/Mips/micromips-jump-instructions.s.cs +6 -0
- data/test/MC/Mips/micromips-loadstore-instructions-EB.s.cs +9 -0
- data/test/MC/Mips/micromips-loadstore-instructions.s.cs +9 -0
- data/test/MC/Mips/micromips-loadstore-unaligned-EB.s.cs +5 -0
- data/test/MC/Mips/micromips-loadstore-unaligned.s.cs +5 -0
- data/test/MC/Mips/micromips-movcond-instructions-EB.s.cs +5 -0
- data/test/MC/Mips/micromips-movcond-instructions.s.cs +5 -0
- data/test/MC/Mips/micromips-multiply-instructions-EB.s.cs +5 -0
- data/test/MC/Mips/micromips-multiply-instructions.s.cs +5 -0
- data/test/MC/Mips/micromips-shift-instructions-EB.s.cs +9 -0
- data/test/MC/Mips/micromips-shift-instructions.s.cs +9 -0
- data/test/MC/Mips/micromips-trap-instructions-EB.s.cs +13 -0
- data/test/MC/Mips/micromips-trap-instructions.s.cs +13 -0
- data/test/MC/Mips/mips-alu-instructions.s.cs +53 -0
- data/test/MC/Mips/mips-control-instructions-64.s.cs +33 -0
- data/test/MC/Mips/mips-control-instructions.s.cs +33 -0
- data/test/MC/Mips/mips-coprocessor-encodings.s.cs +17 -0
- data/test/MC/Mips/mips-dsp-instructions.s.cs +43 -0
- data/test/MC/Mips/mips-expansions.s.cs +20 -0
- data/test/MC/Mips/mips-fpu-instructions.s.cs +93 -0
- data/test/MC/Mips/mips-jump-instructions.s.cs +1 -0
- data/test/MC/Mips/mips-memory-instructions.s.cs +17 -0
- data/test/MC/Mips/mips-register-names.s.cs +33 -0
- data/test/MC/Mips/mips64-alu-instructions.s.cs +47 -0
- data/test/MC/Mips/mips64-instructions.s.cs +3 -0
- data/test/MC/Mips/mips64-register-names.s.cs +33 -0
- data/test/MC/Mips/mips_directives.s.cs +12 -0
- data/test/MC/Mips/nabi-regs.s.cs +12 -0
- data/test/MC/Mips/set-at-directive.s.cs +6 -0
- data/test/MC/Mips/test_2r.s.cs +16 -0
- data/test/MC/Mips/test_2rf.s.cs +33 -0
- data/test/MC/Mips/test_3r.s.cs +243 -0
- data/test/MC/Mips/test_3rf.s.cs +83 -0
- data/test/MC/Mips/test_bit.s.cs +49 -0
- data/test/MC/Mips/test_cbranch.s.cs +11 -0
- data/test/MC/Mips/test_ctrlregs.s.cs +33 -0
- data/test/MC/Mips/test_elm.s.cs +16 -0
- data/test/MC/Mips/test_elm_insert.s.cs +4 -0
- data/test/MC/Mips/test_elm_insve.s.cs +5 -0
- data/test/MC/Mips/test_i10.s.cs +5 -0
- data/test/MC/Mips/test_i5.s.cs +45 -0
- data/test/MC/Mips/test_i8.s.cs +11 -0
- data/test/MC/Mips/test_lsa.s.cs +5 -0
- data/test/MC/Mips/test_mi10.s.cs +24 -0
- data/test/MC/Mips/test_vec.s.cs +8 -0
- data/test/MC/PowerPC/ppc64-encoding-bookII.s.cs +25 -0
- data/test/MC/PowerPC/ppc64-encoding-bookIII.s.cs +35 -0
- data/test/MC/PowerPC/ppc64-encoding-ext.s.cs +535 -0
- data/test/MC/PowerPC/ppc64-encoding-fp.s.cs +110 -0
- data/test/MC/PowerPC/ppc64-encoding-vmx.s.cs +170 -0
- data/test/MC/PowerPC/ppc64-encoding.s.cs +202 -0
- data/test/MC/PowerPC/ppc64-operands.s.cs +32 -0
- data/test/MC/README +6 -0
- data/test/MC/Sparc/sparc-alu-instructions.s.cs +47 -0
- data/test/MC/Sparc/sparc-atomic-instructions.s.cs +7 -0
- data/test/MC/Sparc/sparc-ctrl-instructions.s.cs +11 -0
- data/test/MC/Sparc/sparc-fp-instructions.s.cs +59 -0
- data/test/MC/Sparc/sparc-mem-instructions.s.cs +25 -0
- data/test/MC/Sparc/sparc-vis.s.cs +2 -0
- data/test/MC/Sparc/sparc64-alu-instructions.s.cs +13 -0
- data/test/MC/Sparc/sparc64-ctrl-instructions.s.cs +102 -0
- data/test/MC/Sparc/sparcv8-instructions.s.cs +7 -0
- data/test/MC/Sparc/sparcv9-instructions.s.cs +1 -0
- data/test/MC/SystemZ/insn-good-z196.s.cs +589 -0
- data/test/MC/SystemZ/insn-good.s.cs +2265 -0
- data/test/MC/SystemZ/regs-good.s.cs +45 -0
- data/test/MC/X86/3DNow.s.cs +29 -0
- data/test/MC/X86/address-size.s.cs +5 -0
- data/test/MC/X86/avx512-encodings.s.cs +12 -0
- data/test/MC/X86/intel-syntax-encoding.s.cs +30 -0
- data/test/MC/X86/x86-32-avx.s.cs +833 -0
- data/test/MC/X86/x86-32-fma3.s.cs +169 -0
- data/test/MC/X86/x86-32-ms-inline-asm.s.cs +27 -0
- data/test/MC/X86/x86_64-avx-clmul-encoding.s.cs +11 -0
- data/test/MC/X86/x86_64-avx-encoding.s.cs +1058 -0
- data/test/MC/X86/x86_64-bmi-encoding.s.cs +51 -0
- data/test/MC/X86/x86_64-encoding.s.cs +59 -0
- data/test/MC/X86/x86_64-fma3-encoding.s.cs +169 -0
- data/test/MC/X86/x86_64-fma4-encoding.s.cs +98 -0
- data/test/MC/X86/x86_64-hle-encoding.s.cs +3 -0
- data/test/MC/X86/x86_64-imm-widths.s.cs +27 -0
- data/test/MC/X86/x86_64-rand-encoding.s.cs +13 -0
- data/test/MC/X86/x86_64-rtm-encoding.s.cs +4 -0
- data/test/MC/X86/x86_64-sse4a.s.cs +1 -0
- data/test/MC/X86/x86_64-tbm-encoding.s.cs +40 -0
- data/test/MC/X86/x86_64-xop-encoding.s.cs +152 -0
- data/test/README +6 -0
- data/test/test.rb +205 -0
- data/test/test.rb.SPEC +235 -0
- data/test/test_arm.rb +202 -0
- data/test/test_arm.rb.SPEC +275 -0
- data/test/test_arm64.rb +150 -0
- data/test/test_arm64.rb.SPEC +116 -0
- data/test/test_detail.rb +228 -0
- data/test/test_detail.rb.SPEC +322 -0
- data/test/test_exhaustive.rb +80 -0
- data/test/test_mips.rb +118 -0
- data/test/test_mips.rb.SPEC +91 -0
- data/test/test_ppc.rb +137 -0
- data/test/test_ppc.rb.SPEC +84 -0
- data/test/test_sanity.rb +83 -0
- data/test/test_skipdata.rb +111 -0
- data/test/test_skipdata.rb.SPEC +58 -0
- data/test/test_sparc.rb +113 -0
- data/test/test_sparc.rb.SPEC +116 -0
- data/test/test_sysz.rb +111 -0
- data/test/test_sysz.rb.SPEC +61 -0
- data/test/test_x86.rb +189 -0
- data/test/test_x86.rb.SPEC +579 -0
- data/test/test_xcore.rb +100 -0
- data/test/test_xcore.rb.SPEC +75 -0
- metadata +393 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# Library by Nguyen Anh Quynh
|
2
|
+
# Original binding by Nguyen Anh Quynh and Tan Sheng Di
|
3
|
+
# Additional binding work by Ben Nagy
|
4
|
+
# (c) 2013 COSEINC. All Rights Reserved.
|
5
|
+
|
6
|
+
# THIS FILE WAS AUTO-GENERATED -- DO NOT EDIT!
|
7
|
+
# Command: ./genreg /Users/ben/src/capstone/bindings/python/capstone/
|
8
|
+
# 2015-05-02T13:24:08+12:00
|
9
|
+
|
10
|
+
module Crabstone
|
11
|
+
module XCore
|
12
|
+
REG_LOOKUP = {
|
13
|
+
'INVALID' => 0,
|
14
|
+
'CP' => 1,
|
15
|
+
'DP' => 2,
|
16
|
+
'LR' => 3,
|
17
|
+
'SP' => 4,
|
18
|
+
'R0' => 5,
|
19
|
+
'R1' => 6,
|
20
|
+
'R2' => 7,
|
21
|
+
'R3' => 8,
|
22
|
+
'R4' => 9,
|
23
|
+
'R5' => 10,
|
24
|
+
'R6' => 11,
|
25
|
+
'R7' => 12,
|
26
|
+
'R8' => 13,
|
27
|
+
'R9' => 14,
|
28
|
+
'R10' => 15,
|
29
|
+
'R11' => 16,
|
30
|
+
'PC' => 17,
|
31
|
+
'SCP' => 18,
|
32
|
+
'SSR' => 19,
|
33
|
+
'ET' => 20,
|
34
|
+
'ED' => 21,
|
35
|
+
'SED' => 22,
|
36
|
+
'KEP' => 23,
|
37
|
+
'KSP' => 24,
|
38
|
+
'ID' => 25
|
39
|
+
}
|
40
|
+
|
41
|
+
ID_LOOKUP = REG_LOOKUP.invert
|
42
|
+
|
43
|
+
# alias registers
|
44
|
+
|
45
|
+
SYM_LOOKUP = Hash[REG_LOOKUP.map {|k,v| [k.downcase.to_sym,v]}]
|
46
|
+
|
47
|
+
def self.register reg
|
48
|
+
return reg if ID_LOOKUP[reg]
|
49
|
+
return SYM_LOOKUP[reg] if SYM_LOOKUP[reg]
|
50
|
+
if reg.respond_to? :upcase
|
51
|
+
return REG_LOOKUP[reg.upcase] || REG_LOOKUP['INVALID']
|
52
|
+
end
|
53
|
+
REG_LOOKUP['INVALID']
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/crabstone.rb
ADDED
@@ -0,0 +1,564 @@
|
|
1
|
+
# Library by Nguyen Anh Quynh
|
2
|
+
# Original binding by Nguyen Anh Quynh and Tan Sheng Di
|
3
|
+
# Additional binding work by Ben Nagy
|
4
|
+
# (c) 2013 COSEINC. All Rights Reserved.
|
5
|
+
|
6
|
+
require 'ffi'
|
7
|
+
|
8
|
+
require_relative 'arch/x86'
|
9
|
+
require_relative 'arch/x86_registers'
|
10
|
+
require_relative 'arch/arm'
|
11
|
+
require_relative 'arch/arm_registers'
|
12
|
+
require_relative 'arch/arm64'
|
13
|
+
require_relative 'arch/arm64_registers'
|
14
|
+
require_relative 'arch/mips'
|
15
|
+
require_relative 'arch/mips_registers'
|
16
|
+
require_relative 'arch/ppc'
|
17
|
+
require_relative 'arch/ppc_registers'
|
18
|
+
require_relative 'arch/sparc'
|
19
|
+
require_relative 'arch/sparc_registers'
|
20
|
+
require_relative 'arch/systemz'
|
21
|
+
require_relative 'arch/sysz_registers'
|
22
|
+
require_relative 'arch/xcore'
|
23
|
+
require_relative 'arch/xcore_registers'
|
24
|
+
|
25
|
+
module Crabstone
|
26
|
+
|
27
|
+
VERSION = '3.0.3'
|
28
|
+
|
29
|
+
# API version
|
30
|
+
BINDING_MAJ = 3
|
31
|
+
BINDING_MIN = 0
|
32
|
+
|
33
|
+
# architectures
|
34
|
+
ARCH_ARM = 0
|
35
|
+
ARCH_ARM64 = 1
|
36
|
+
ARCH_MIPS = 2
|
37
|
+
ARCH_X86 = 3
|
38
|
+
ARCH_PPC = 4
|
39
|
+
ARCH_SPARC = 5
|
40
|
+
ARCH_SYSZ = 6
|
41
|
+
ARCH_XCORE = 7
|
42
|
+
ARCH_MAX = 8
|
43
|
+
ARCH_ALL = 0xFFFF
|
44
|
+
|
45
|
+
# disasm mode
|
46
|
+
MODE_LITTLE_ENDIAN = 0 # little-endian mode (default mode)
|
47
|
+
MODE_ARM = 0 # 32-bit ARM
|
48
|
+
MODE_16 = 1 << 1 # 16-bit mode (X86)
|
49
|
+
MODE_32 = 1 << 2 # 32-bit mode (X86)
|
50
|
+
MODE_64 = 1 << 3 # 64-bit mode (X86, PPC)
|
51
|
+
MODE_THUMB = 1 << 4 # ARM's Thumb mode, including Thumb-2
|
52
|
+
MODE_MCLASS = 1 << 5 # ARM's Cortex-M series
|
53
|
+
MODE_V8 = 1 << 6 # ARMv8 A32 encodings for ARM
|
54
|
+
MODE_MICRO = 1 << 4 # MicroMips mode (MIPS)
|
55
|
+
MODE_MIPS3 = 1 << 5 # Mips III ISA
|
56
|
+
MODE_MIPS32R6 = 1 << 6 # Mips32r6 ISA
|
57
|
+
MODE_MIPSGP64 = 1 << 7 # General Purpose Registers are 64-bit wide (MIPS)
|
58
|
+
MODE_V9 = 1 << 4 # SparcV9 mode (Sparc)
|
59
|
+
MODE_BIG_ENDIAN = 1 << 31 # big-endian mode
|
60
|
+
MODE_MIPS32 = MODE_32 # Mips32 ISA (Mips)
|
61
|
+
MODE_MIPS64 = MODE_64 # Mips64 ISA (Mips)
|
62
|
+
|
63
|
+
|
64
|
+
# Capstone option type
|
65
|
+
OPT_SYNTAX = 1 # Intel X86 asm syntax (ARCH_X86 arch)
|
66
|
+
OPT_DETAIL = 2 # Break down instruction structure into details
|
67
|
+
OPT_MODE = 3 # Change engine's mode at run-time
|
68
|
+
OPT_MEM = 4 # Change engine's mode at run-time
|
69
|
+
OPT_SKIPDATA = 5 # Skip data when disassembling
|
70
|
+
OPT_SKIPDATA_SETUP = 6 # Setup user-defined function for SKIPDATA option
|
71
|
+
|
72
|
+
# Capstone option value
|
73
|
+
OPT_OFF = 0 # Turn OFF an option - default option of OPT_DETAIL
|
74
|
+
OPT_ON = 3 # Turn ON an option (OPT_DETAIL)
|
75
|
+
|
76
|
+
# Common instruction operand types - to be consistent across all architectures.
|
77
|
+
OP_INVALID = 0
|
78
|
+
OP_REG = 1
|
79
|
+
OP_IMM = 2
|
80
|
+
OP_MEM = 3
|
81
|
+
OP_FP = 4
|
82
|
+
|
83
|
+
# Common instruction groups - to be consistent across all architectures.
|
84
|
+
GRP_INVALID = 0 # uninitialized/invalid group.
|
85
|
+
GRP_JUMP = 1 # all jump instructions (conditional+direct+indirect jumps)
|
86
|
+
GRP_CALL = 2 # all call instructions
|
87
|
+
GRP_RET = 3 # all return instructions
|
88
|
+
GRP_INT = 4 # all interrupt instructions (int+syscall)
|
89
|
+
GRP_IRET = 5 # all interrupt return instructions
|
90
|
+
|
91
|
+
# Capstone syntax value
|
92
|
+
OPT_SYNTAX_DEFAULT = 0 # Default assembly syntax of all platforms (OPT_SYNTAX)
|
93
|
+
OPT_SYNTAX_INTEL = 1 # Intel X86 asm syntax - default syntax on X86 (OPT_SYNTAX, ARCH_X86)
|
94
|
+
OPT_SYNTAX_ATT = 2 # ATT asm syntax (OPT_SYNTAX, ARCH_X86)
|
95
|
+
OPT_SYNTAX_NOREGNAME = 3 # Asm syntax prints register name with only number - (OPT_SYNTAX, ARCH_PPC, ARCH_ARM)
|
96
|
+
|
97
|
+
# query id for cs_support()
|
98
|
+
SUPPORT_DIET = ARCH_ALL + 1
|
99
|
+
SUPPORT_X86_REDUCE = ARCH_ALL + 2
|
100
|
+
|
101
|
+
SYNTAX = {
|
102
|
+
:intel => 1,
|
103
|
+
:att => 2,
|
104
|
+
:no_regname => 3 # for PPC only
|
105
|
+
}
|
106
|
+
|
107
|
+
DETAIL = {
|
108
|
+
true => 3, #trololol
|
109
|
+
false => 0
|
110
|
+
}
|
111
|
+
|
112
|
+
SKIPDATA = {
|
113
|
+
true => 3, #trololol
|
114
|
+
false => 0
|
115
|
+
}
|
116
|
+
|
117
|
+
class ErrArch < StandardError; end
|
118
|
+
class ErrCsh < StandardError; end
|
119
|
+
class ErrHandle < StandardError; end
|
120
|
+
class ErrMem < StandardError; end
|
121
|
+
class ErrMode < StandardError; end
|
122
|
+
class ErrOK < StandardError; end
|
123
|
+
class ErrOption < StandardError; end
|
124
|
+
class ErrDetail < StandardError; end
|
125
|
+
class ErrMemSetup < StandardError; end
|
126
|
+
class ErrVersion < StandardError; end
|
127
|
+
class ErrDiet < StandardError; end
|
128
|
+
class ErrSkipData < StandardError; end
|
129
|
+
class ErrX86ATT < StandardError; end
|
130
|
+
class ErrX86Intel < StandardError; end
|
131
|
+
|
132
|
+
ERRNO = {
|
133
|
+
0 => ErrOK,
|
134
|
+
1 => ErrMem,
|
135
|
+
2 => ErrArch,
|
136
|
+
3 => ErrHandle,
|
137
|
+
4 => ErrCsh,
|
138
|
+
5 => ErrMode,
|
139
|
+
6 => ErrOption,
|
140
|
+
7 => ErrDetail,
|
141
|
+
8 => ErrMemSetup,
|
142
|
+
9 => ErrVersion,
|
143
|
+
10 => ErrDiet,
|
144
|
+
11 => ErrSkipData,
|
145
|
+
12 => ErrX86ATT,
|
146
|
+
13 => ErrX86Intel,
|
147
|
+
}
|
148
|
+
|
149
|
+
ERRNO_KLASS = ERRNO.invert
|
150
|
+
|
151
|
+
def self.raise_errno errno
|
152
|
+
err_klass = ERRNO[errno]
|
153
|
+
raise RuntimeError, "Internal Error: Tried to raise unknown errno" unless err_klass
|
154
|
+
err_str = Binding.cs_strerror(errno)
|
155
|
+
raise err_klass, err_str
|
156
|
+
end
|
157
|
+
|
158
|
+
module Binding
|
159
|
+
|
160
|
+
extend FFI::Library
|
161
|
+
ffi_lib ['capstone', 'libcapstone.so.3']
|
162
|
+
|
163
|
+
# This is because JRuby FFI on x64 Windows thinks size_t is 32 bit
|
164
|
+
case FFI::Platform::ADDRESS_SIZE
|
165
|
+
when 64
|
166
|
+
typedef :ulong_long, :size_t
|
167
|
+
when 32
|
168
|
+
typedef :ulong, :size_t
|
169
|
+
else
|
170
|
+
fail "Unsupported native address size"
|
171
|
+
end
|
172
|
+
|
173
|
+
typedef :size_t, :csh
|
174
|
+
typedef :size_t, :cs_opt_value
|
175
|
+
typedef :uint, :cs_opt_type
|
176
|
+
typedef :uint, :cs_err
|
177
|
+
typedef :uint, :cs_arch
|
178
|
+
typedef :uint, :cs_mode
|
179
|
+
|
180
|
+
class Architecture < FFI::Union
|
181
|
+
layout(
|
182
|
+
:arm, ARM::Instruction,
|
183
|
+
:arm64, ARM64::Instruction,
|
184
|
+
:mips, MIPS::Instruction,
|
185
|
+
:x86, X86::Instruction,
|
186
|
+
:ppc, PPC::Instruction,
|
187
|
+
:sparc, Sparc::Instruction,
|
188
|
+
:sysz, SysZ::Instruction,
|
189
|
+
:xcore, XCore::Instruction
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
class Detail < FFI::Struct
|
194
|
+
layout(
|
195
|
+
:regs_read, [:uint8, 12],
|
196
|
+
:regs_read_count, :uint8,
|
197
|
+
:regs_write, [:uint8, 20],
|
198
|
+
:regs_write_count, :uint8,
|
199
|
+
:groups, [:uint8, 8],
|
200
|
+
:groups_count, :uint8,
|
201
|
+
:arch, Architecture
|
202
|
+
)
|
203
|
+
end
|
204
|
+
|
205
|
+
class Instruction < FFI::ManagedStruct
|
206
|
+
layout(
|
207
|
+
:id, :uint,
|
208
|
+
:address, :ulong_long,
|
209
|
+
:size, :uint16,
|
210
|
+
:bytes, [:uchar, 16],
|
211
|
+
:mnemonic, [:char, 32],
|
212
|
+
:op_str, [:char, 160],
|
213
|
+
:detail, Detail.by_ref
|
214
|
+
)
|
215
|
+
|
216
|
+
def self.release(ptr)
|
217
|
+
detail_ptr = ptr.+(Instruction.offset_of(:detail)).read_ptr
|
218
|
+
Binding.free(detail_ptr)
|
219
|
+
Binding.free(ptr)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
callback :skipdata_cb, [:pointer, :size_t, :size_t, :pointer], :size_t
|
224
|
+
|
225
|
+
class SkipdataConfig < FFI::Struct
|
226
|
+
layout(
|
227
|
+
:mnemonic, :pointer,
|
228
|
+
:callback, :skipdata_cb,
|
229
|
+
:unused, :pointer
|
230
|
+
)
|
231
|
+
end
|
232
|
+
|
233
|
+
attach_function(
|
234
|
+
:cs_disasm,
|
235
|
+
[:csh, :pointer, :size_t, :ulong_long, :size_t, :pointer],
|
236
|
+
:size_t
|
237
|
+
)
|
238
|
+
attach_function :cs_close, [:pointer], :cs_err
|
239
|
+
attach_function :cs_errno, [:csh], :cs_err
|
240
|
+
attach_function :cs_group_name, [:csh, :uint], :string
|
241
|
+
attach_function :cs_insn_group, [:csh, Instruction, :uint], :bool
|
242
|
+
attach_function :cs_insn_name, [:csh, :uint], :string
|
243
|
+
attach_function :cs_op_count, [:csh, Instruction, :uint], :cs_err
|
244
|
+
attach_function :cs_open, [:cs_arch, :cs_mode, :pointer], :cs_err
|
245
|
+
attach_function :cs_option, [:csh, :cs_opt_type, :cs_opt_value], :cs_err
|
246
|
+
attach_function :cs_reg_name, [:csh, :uint], :string
|
247
|
+
attach_function :cs_reg_read, [:csh, Instruction, :uint], :bool
|
248
|
+
attach_function :cs_reg_write, [:csh, Instruction, :uint], :bool
|
249
|
+
attach_function :cs_strerror, [:cs_err], :string
|
250
|
+
attach_function :cs_support, [:cs_arch], :bool
|
251
|
+
attach_function :cs_version, [:pointer, :pointer], :uint
|
252
|
+
attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
|
253
|
+
attach_function :malloc, [:size_t], :pointer
|
254
|
+
attach_function :free, [:pointer], :void
|
255
|
+
|
256
|
+
end # Binding
|
257
|
+
|
258
|
+
# This is a C engine build option, so we can set it here, not when we
|
259
|
+
# instantiate a new Disassembler.
|
260
|
+
DIET_MODE = Binding.cs_support SUPPORT_DIET
|
261
|
+
# Diet mode means:
|
262
|
+
# - No op_str or mnemonic in Instruction
|
263
|
+
# - No regs_read, regs_write or groups ( even with detail on )
|
264
|
+
# - No reg_name or insn_name id2str convenience functions
|
265
|
+
# - detail mode CAN still be on - so the arch insn operands MAY be available
|
266
|
+
|
267
|
+
class Instruction
|
268
|
+
|
269
|
+
attr_reader :arch, :csh, :raw_insn
|
270
|
+
|
271
|
+
ARCHS = {
|
272
|
+
arm: ARCH_ARM,
|
273
|
+
arm64: ARCH_ARM64,
|
274
|
+
x86: ARCH_X86,
|
275
|
+
mips: ARCH_MIPS,
|
276
|
+
ppc: ARCH_PPC,
|
277
|
+
sparc: ARCH_SPARC,
|
278
|
+
sysz: ARCH_SYSZ,
|
279
|
+
xcore: ARCH_XCORE
|
280
|
+
}.invert
|
281
|
+
|
282
|
+
ARCH_CLASSES = {
|
283
|
+
ARCH_ARM => ARM,
|
284
|
+
ARCH_ARM64 => ARM64,
|
285
|
+
ARCH_X86 => X86,
|
286
|
+
ARCH_MIPS => MIPS,
|
287
|
+
ARCH_PPC => PPC,
|
288
|
+
ARCH_SPARC => Sparc,
|
289
|
+
ARCH_SYSZ => SysZ,
|
290
|
+
ARCH_XCORE => XCore
|
291
|
+
}
|
292
|
+
|
293
|
+
def initialize csh, insn, arch
|
294
|
+
@arch = arch
|
295
|
+
@csh = csh
|
296
|
+
@raw_insn = insn
|
297
|
+
if detailed?
|
298
|
+
@detail = insn[:detail]
|
299
|
+
@arch_insn = @detail[:arch][ARCHS[arch]]
|
300
|
+
@regs_read = @detail[:regs_read].first( @detail[:regs_read_count] )
|
301
|
+
@regs_write = @detail[:regs_write].first( @detail[:regs_write_count] )
|
302
|
+
@groups = @detail[:groups].first( @detail[:groups_count] )
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def name
|
307
|
+
raise_if_diet
|
308
|
+
name = Binding.cs_insn_name(csh, id)
|
309
|
+
Crabstone.raise_errno( ERRNO_KLASS[ErrCsh] ) unless name
|
310
|
+
name
|
311
|
+
end
|
312
|
+
|
313
|
+
def group_name grp
|
314
|
+
raise_if_diet
|
315
|
+
name = Binding.cs_group_name(csh, Integer(grp))
|
316
|
+
Crabstone.raise_errno( ERRNO_KLASS[ErrCsh] ) unless name
|
317
|
+
name
|
318
|
+
end
|
319
|
+
|
320
|
+
# It's more informative to raise if CS_DETAIL is off than just return nil
|
321
|
+
def detailed?
|
322
|
+
not @raw_insn[:detail].pointer.null?
|
323
|
+
end
|
324
|
+
|
325
|
+
def detail
|
326
|
+
raise_unless_detailed
|
327
|
+
@detail
|
328
|
+
end
|
329
|
+
|
330
|
+
def regs_read
|
331
|
+
raise_unless_detailed
|
332
|
+
raise_if_diet
|
333
|
+
@regs_read
|
334
|
+
end
|
335
|
+
|
336
|
+
def regs_write
|
337
|
+
raise_unless_detailed
|
338
|
+
raise_if_diet
|
339
|
+
@regs_write
|
340
|
+
end
|
341
|
+
|
342
|
+
def groups
|
343
|
+
raise_unless_detailed
|
344
|
+
raise_if_diet
|
345
|
+
@groups
|
346
|
+
end
|
347
|
+
|
348
|
+
def group? groupid
|
349
|
+
raise_unless_detailed
|
350
|
+
raise_if_diet
|
351
|
+
Binding.cs_insn_group csh, raw_insn, groupid
|
352
|
+
end
|
353
|
+
|
354
|
+
def reads_reg? reg
|
355
|
+
raise_unless_detailed
|
356
|
+
raise_if_diet
|
357
|
+
Binding.cs_reg_read csh, raw_insn, ARCH_CLASSES[arch].register( reg )
|
358
|
+
end
|
359
|
+
|
360
|
+
def writes_reg? reg
|
361
|
+
raise_unless_detailed
|
362
|
+
raise_if_diet
|
363
|
+
Binding.cs_reg_write csh, raw_insn, ARCH_CLASSES[arch].register( reg )
|
364
|
+
end
|
365
|
+
|
366
|
+
def mnemonic
|
367
|
+
raise_if_diet
|
368
|
+
raw_insn[:mnemonic]
|
369
|
+
end
|
370
|
+
|
371
|
+
def op_str
|
372
|
+
raise_if_diet
|
373
|
+
raw_insn[:op_str]
|
374
|
+
end
|
375
|
+
|
376
|
+
def op_count op_type=nil
|
377
|
+
raise_unless_detailed
|
378
|
+
if op_type
|
379
|
+
Binding.cs_op_count csh, raw_insn, op_type
|
380
|
+
else
|
381
|
+
self.operands.size
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
def bytes
|
386
|
+
raw_insn[:bytes].first raw_insn[:size]
|
387
|
+
end
|
388
|
+
|
389
|
+
# So an Instruction should respond to all the methods in Instruction, and
|
390
|
+
# all the methods in the Arch specific Instruction class. The methods /
|
391
|
+
# members that have special handling for detail mode or diet mode are
|
392
|
+
# handled above. The rest is dynamically dispatched below.
|
393
|
+
def method_missing meth, *args
|
394
|
+
if raw_insn.members.include? meth
|
395
|
+
# Dispatch to toplevel Instruction class ( this file )
|
396
|
+
raw_insn[meth]
|
397
|
+
else
|
398
|
+
# Nothing else is available without details.
|
399
|
+
if not detailed?
|
400
|
+
raise(
|
401
|
+
NoMethodError,
|
402
|
+
"Either CS_DETAIL is off, or #{self.class} doesn't implement #{meth}"
|
403
|
+
)
|
404
|
+
end
|
405
|
+
# Dispatch to the architecture specific Instruction ( in arch/ )
|
406
|
+
if @arch_insn.respond_to? meth
|
407
|
+
@arch_insn.send meth, *args
|
408
|
+
elsif @arch_insn.members.include? meth
|
409
|
+
@arch_insn[meth]
|
410
|
+
else
|
411
|
+
raise NoMethodError, "Unknown method #{meth} for #{self.class}"
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
private
|
417
|
+
|
418
|
+
def raise_unless_detailed
|
419
|
+
Crabstone.raise_errno( Crabstone::ERRNO_KLASS[ErrDetail] ) unless detailed?
|
420
|
+
end
|
421
|
+
|
422
|
+
def raise_if_diet
|
423
|
+
Crabstone.raise_errno( Crabstone::ERRNO_KLASS[ErrDiet] ) if DIET_MODE
|
424
|
+
end
|
425
|
+
|
426
|
+
end
|
427
|
+
|
428
|
+
|
429
|
+
class Disassembler
|
430
|
+
|
431
|
+
attr_reader :arch, :mode, :csh, :syntax, :decomposer
|
432
|
+
|
433
|
+
def initialize arch, mode
|
434
|
+
|
435
|
+
maj, min = version
|
436
|
+
if maj != BINDING_MAJ || min != BINDING_MIN
|
437
|
+
raise "FATAL: Binding for #{BINDING_MAJ}.#{BINDING_MIN}, found #{maj}.#{min}"
|
438
|
+
end
|
439
|
+
|
440
|
+
@arch = arch
|
441
|
+
@mode = mode
|
442
|
+
p_size_t = FFI::MemoryPointer.new :ulong_long
|
443
|
+
@p_csh = FFI::MemoryPointer.new p_size_t
|
444
|
+
if ( res = Binding.cs_open( arch, mode, @p_csh )).nonzero?
|
445
|
+
Crabstone.raise_errno res
|
446
|
+
end
|
447
|
+
|
448
|
+
@csh = @p_csh.read_ulong_long
|
449
|
+
|
450
|
+
end
|
451
|
+
|
452
|
+
# After you close the engine, don't use it anymore. Can't believe I even
|
453
|
+
# have to write this.
|
454
|
+
def close
|
455
|
+
if ( res = Binding.cs_close(@p_csh) ).nonzero?
|
456
|
+
Crabstone.raise_errno res
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def syntax= new_stx
|
461
|
+
Crabstone.raise_errno( Crabstone::ERRNO_KLASS[ErrOption] ) unless SYNTAX[new_stx]
|
462
|
+
res = Binding.cs_option(csh, OPT_SYNTAX, SYNTAX[new_stx])
|
463
|
+
Crabstone.raise_errno res if res.nonzero?
|
464
|
+
@syntax = new_stx
|
465
|
+
end
|
466
|
+
|
467
|
+
def decomposer= new_val
|
468
|
+
res = Binding.cs_option(csh, OPT_DETAIL, DETAIL[!!(new_val)])
|
469
|
+
Crabstone.raise_errno res if res.nonzero?
|
470
|
+
@decomposer = !!(new_val)
|
471
|
+
end
|
472
|
+
|
473
|
+
def version
|
474
|
+
maj = FFI::MemoryPointer.new(:int)
|
475
|
+
min = FFI::MemoryPointer.new(:int)
|
476
|
+
Binding.cs_version maj, min
|
477
|
+
[ maj.read_int, min.read_int ]
|
478
|
+
end
|
479
|
+
|
480
|
+
def diet?
|
481
|
+
DIET_MODE
|
482
|
+
end
|
483
|
+
|
484
|
+
def errno
|
485
|
+
Binding.cs_errno(csh)
|
486
|
+
end
|
487
|
+
|
488
|
+
def skipdata mnemonic='.byte'
|
489
|
+
|
490
|
+
cfg = Binding::SkipdataConfig.new
|
491
|
+
cfg[:mnemonic] = FFI::MemoryPointer.from_string String(mnemonic)
|
492
|
+
|
493
|
+
if block_given?
|
494
|
+
|
495
|
+
real_cb = FFI::Function.new(
|
496
|
+
:size_t,
|
497
|
+
[:pointer, :size_t, :size_t, :pointer]
|
498
|
+
) {|code, sz, offset, _|
|
499
|
+
|
500
|
+
code = code.read_array_of_uchar(sz).pack('c*')
|
501
|
+
begin
|
502
|
+
res = yield code, offset
|
503
|
+
Integer(res)
|
504
|
+
rescue
|
505
|
+
warn "Error in skipdata callback: #{$!}"
|
506
|
+
# It will go on to crash, but now at least there's more info :)
|
507
|
+
end
|
508
|
+
}
|
509
|
+
|
510
|
+
cfg[:callback] = real_cb
|
511
|
+
|
512
|
+
end
|
513
|
+
|
514
|
+
res = Binding.cs_option(csh, OPT_SKIPDATA_SETUP, cfg.pointer.address)
|
515
|
+
Crabstone.raise_errno res if res.nonzero?
|
516
|
+
res = Binding.cs_option(csh, OPT_SKIPDATA, SKIPDATA[true])
|
517
|
+
Crabstone.raise_errno res if res.nonzero?
|
518
|
+
end
|
519
|
+
|
520
|
+
def skipdata_off
|
521
|
+
res = Binding.cs_option(csh, OPT_SKIPDATA, SKIPDATA[false])
|
522
|
+
Crabstone.raise_errno res if res.nonzero?
|
523
|
+
end
|
524
|
+
|
525
|
+
def reg_name regid
|
526
|
+
Crabstone.raise_errno( Crabstone::ERRNO_KLASS[ErrDiet] ) if DIET_MODE
|
527
|
+
name = Binding.cs_reg_name(csh, regid)
|
528
|
+
Crabstone.raise_errno( Crabstone::ERRNO_KLASS[ErrCsh] ) unless name
|
529
|
+
name
|
530
|
+
end
|
531
|
+
|
532
|
+
def disasm code, offset, count = 0
|
533
|
+
return [] if code.empty?
|
534
|
+
|
535
|
+
insn_ptr = FFI::MemoryPointer.new :pointer
|
536
|
+
insn_count = Binding.cs_disasm(
|
537
|
+
@csh,
|
538
|
+
code,
|
539
|
+
code.bytesize,
|
540
|
+
offset,
|
541
|
+
count,
|
542
|
+
insn_ptr
|
543
|
+
)
|
544
|
+
Crabstone.raise_errno(errno) if insn_count.zero?
|
545
|
+
|
546
|
+
insns = (0...insn_count * Binding::Instruction.size).step(Binding::Instruction.size).map do |off|
|
547
|
+
cs_insn_ptr = Binding.malloc Binding::Instruction.size
|
548
|
+
cs_insn = Binding::Instruction.new cs_insn_ptr
|
549
|
+
Binding.memcpy(cs_insn_ptr, insn_ptr.read_pointer + off, Binding::Instruction.size)
|
550
|
+
Instruction.new @csh, cs_insn, @arch
|
551
|
+
end
|
552
|
+
|
553
|
+
Binding.free(insn_ptr.read_pointer)
|
554
|
+
|
555
|
+
insns
|
556
|
+
end
|
557
|
+
|
558
|
+
def set_raw_option opt, val
|
559
|
+
res = Binding.cs_option csh, opt, val
|
560
|
+
Crabstone.raise_errno res if res.nonzero?
|
561
|
+
end
|
562
|
+
|
563
|
+
end
|
564
|
+
end
|