class Crabstone::Disassembler
Constants
- DETAIL
- SKIPDATA
- SYNTAX
Attributes
arch[R]
csh[R]
decomposer[R]
mode[R]
syntax[R]
Public Class Methods
new(arch, mode)
click to toggle source
# File lib/crabstone/disassembler.rb, line 30 def initialize(arch, mode) @arch = arch @mode = mode @p_csh = FFI::MemoryPointer.new(:ulong_long) safe { Binding.cs_open(arch, mode, @p_csh) } @csh = @p_csh.read_ulong_long end
Public Instance Methods
close()
click to toggle source
After you close the engine, don't use it anymore. Can't believe I even have to write this.
@return [void]
# File lib/crabstone/disassembler.rb, line 43 def close safe { Binding.cs_close(@p_csh) } end
decomposer=(new_val)
click to toggle source
@param [Boolean] new_val
# File lib/crabstone/disassembler.rb, line 54 def decomposer=(new_val) Crabstone::Error.raise!(ErrOption) unless DETAIL[new_val] set_raw_option(OPT_DETAIL, DETAIL[new_val]) @decomposer = new_val end
diet?()
click to toggle source
# File lib/crabstone/disassembler.rb, line 64 def diet? DIET_MODE end
disasm(code, offset, count = 0)
click to toggle source
@return [Array<Crabstone::Instruction>]
# File lib/crabstone/disassembler.rb, line 107 def disasm(code, offset, count = 0) return [] if code.empty? insn_ptr = FFI::MemoryPointer.new(:pointer) insn_count = Binding.cs_disasm( @csh, code, code.bytesize, offset, count, insn_ptr ) Crabstone::Error.raise_errno!(errno) if insn_count.zero? convert_disasm_result(insn_ptr, insn_count).tap { Binding.free(insn_ptr.read_pointer) } end
errno()
click to toggle source
# File lib/crabstone/disassembler.rb, line 68 def errno Binding.cs_errno(@csh) end
reg_name(regid)
click to toggle source
# File lib/crabstone/disassembler.rb, line 99 def reg_name(regid) Crabstone::Error.raise!(ErrDiet) if DIET_MODE name = Binding.cs_reg_name(csh, regid) Crabstone::Error.raise!(ErrCsh) unless name name end
set_raw_option(opt, val)
click to toggle source
# File lib/crabstone/disassembler.rb, line 124 def set_raw_option(opt, val) safe { Binding.cs_option(csh, opt, val) } end
skipdata(mnemonic = '.byte') { |code, offset| ... }
click to toggle source
# File lib/crabstone/disassembler.rb, line 72 def skipdata(mnemonic = '.byte') cfg = Binding::SkipdataConfig.new cfg[:mnemonic] = FFI::MemoryPointer.from_string(mnemonic.to_s) if block_given? cfg[:callback] = FFI::Function.new( :size_t, %i[pointer size_t size_t pointer] ) do |code, sz, offset, _| code = code.read_array_of_uchar(sz).pack('c*') begin Integer(yield(code, offset)) rescue StandardError warn "Error in skipdata callback: #{$ERROR_INFO}" # It will go on to crash, but now at least there's more info :) end end end set_raw_option(OPT_SKIPDATA_SETUP, cfg.pointer.address) set_raw_option(OPT_SKIPDATA, SKIPDATA[true]) end
skipdata_off()
click to toggle source
# File lib/crabstone/disassembler.rb, line 95 def skipdata_off set_raw_option(OPT_SKIPDATA, SKIPDATA[false]) end
syntax=(new_stx)
click to toggle source
# File lib/crabstone/disassembler.rb, line 47 def syntax=(new_stx) Crabstone::Error.raise!(ErrOption) unless SYNTAX[new_stx] set_raw_option(OPT_SYNTAX, SYNTAX[new_stx]) @syntax = new_stx end
version()
click to toggle source
# File lib/crabstone/disassembler.rb, line 60 def version Crabstone.cs_version end
Private Instance Methods
convert_disasm_result(insn_ptr, insn_count)
click to toggle source
Convert the insn_ptr from cs_disasm into Ruby instruction objects. @param [FFI::MemoryPointer] insn_ptr @param [Integer] insn_count @return [Array<Crabstone::Instruction>]
# File lib/crabstone/disassembler.rb, line 134 def convert_disasm_result(insn_ptr, insn_count) insn_sz = Binding::Instruction.size Array.new(insn_count) do |i| cs_insn_ptr = Binding.malloc(insn_sz) Binding.memcpy(cs_insn_ptr, insn_ptr.read_pointer + i * insn_sz, insn_sz) Crabstone::Instruction.new(@csh, Binding::Instruction.new(cs_insn_ptr), @arch) end end
safe() { || ... }
click to toggle source
# File lib/crabstone/disassembler.rb, line 143 def safe yield.tap { |res| Crabstone::Error.raise_errno!(res) unless res.zero? } end