class Crabstone::Instruction
Attributes
csh[R]
raw_insn[R]
Public Class Methods
new(csh, insn, arch)
click to toggle source
# File lib/crabstone/instruction.rb, line 12 def initialize(csh, insn, arch) @arch_module = Arch.module_of(arch) @csh = csh @raw_insn = insn init_detail(insn[:detail]) if detailed? end
Public Instance Methods
bytes()
click to toggle source
# File lib/crabstone/instruction.rb, line 116 def bytes raw_insn[:bytes].first(raw_insn[:size]) end
detail()
click to toggle source
# File lib/crabstone/instruction.rb, line 38 def detail raise_unless_detailed @detail end
detailed?()
click to toggle source
It's more informative to raise if CS_DETAIL is off than just return nil
# File lib/crabstone/instruction.rb, line 34 def detailed? !@raw_insn[:detail].pointer.null? end
group?(group_id)
click to toggle source
# File lib/crabstone/instruction.rb, line 61 def group?(group_id) raise_unless_detailed raise_if_diet Binding.cs_insn_group(csh, raw_insn, group_id) end
group_name(grp)
click to toggle source
# File lib/crabstone/instruction.rb, line 26 def group_name(grp) raise_if_diet name = Binding.cs_group_name(csh, Integer(grp)) Crabstone::Error.raise!(ErrCsh) unless name name end
groups()
click to toggle source
# File lib/crabstone/instruction.rb, line 55 def groups raise_unless_detailed raise_if_diet @groups end
method_missing(meth, *args)
click to toggle source
So an Instruction
should respond to all the methods in Instruction
, and all the methods in the Arch
specific Instruction
class. The methods / members that have special handling for detail mode or diet mode are handled above. The rest is dynamically dispatched below.
Calls superclass method
# File lib/crabstone/instruction.rb, line 124 def method_missing(meth, *args) # Dispatch to toplevel Instruction class ( this file ) return raw_insn[meth] if raw_insn.members.include?(meth) # Nothing else is available without details. unless detailed? raise( NoMethodError, "Either CS_DETAIL is off, or #{self.class} doesn't implement #{meth}" ) end # Dispatch to the architecture specific Instruction ( in arch/ ) return @arch_insn.__send__(meth, *args) if @arch_insn.respond_to?(meth) return @arch_insn[meth] if @arch_insn.members.include?(meth) super end
mnemonic()
click to toggle source
# File lib/crabstone/instruction.rb, line 97 def mnemonic raise_if_diet raw_insn[:mnemonic] end
name()
click to toggle source
# File lib/crabstone/instruction.rb, line 19 def name raise_if_diet name = Binding.cs_insn_name(csh, id) Crabstone::Error.raise!(ErrCsh) unless name name end
op_count(op_type = nil)
click to toggle source
# File lib/crabstone/instruction.rb, line 107 def op_count(op_type = nil) raise_unless_detailed if op_type Binding.cs_op_count(csh, raw_insn, op_type) else operands.size end end
op_str()
click to toggle source
# File lib/crabstone/instruction.rb, line 102 def op_str raise_if_diet raw_insn[:op_str] end
reads_reg?(reg)
click to toggle source
# File lib/crabstone/instruction.rb, line 67 def reads_reg?(reg) raise_unless_detailed raise_if_diet Binding.cs_reg_read(csh, raw_insn, @arch_module.register(reg)) end
regs_access()
click to toggle source
@return [{:regs_read => Array<Integer>, :regs_write => Array<Integer>}]
# File lib/crabstone/instruction.rb, line 80 def regs_access raise_unless_detailed raise_if_diet # XXX: Becare of if `typedef uint16_t cs_regs[64];` changes regs_read = FFI::MemoryPointer.new(:uint16, 64) regs_read_count = FFI::MemoryPointer.new(:uint8) regs_write = FFI::MemoryPointer.new(:uint16, 64) regs_write_count = FFI::MemoryPointer.new(:uint8) err = Binding.cs_regs_access(csh, raw_insn, regs_read, regs_read_count, regs_write, regs_write_count) Crabstone::Error.raise_errno(err) if err.nonzero? { regs_read: regs_read.read_array_of_short(regs_read_count.read_int8), regs_write: regs_write.read_array_of_short(regs_write_count.read_int8) } end
regs_read()
click to toggle source
# File lib/crabstone/instruction.rb, line 43 def regs_read raise_unless_detailed raise_if_diet @regs_read end
regs_write()
click to toggle source
# File lib/crabstone/instruction.rb, line 49 def regs_write raise_unless_detailed raise_if_diet @regs_write end
respond_to_missing?(meth, include_private = true)
click to toggle source
Calls superclass method
# File lib/crabstone/instruction.rb, line 142 def respond_to_missing?(meth, include_private = true) return true if raw_insn.members.include?(meth) return super unless detailed? return true if @arch_insn.respond_to?(meth) return true if @arch_insn.members.include?(meth) super end
writes_reg?(reg)
click to toggle source
# File lib/crabstone/instruction.rb, line 73 def writes_reg?(reg) raise_unless_detailed raise_if_diet Binding.cs_reg_write(csh, raw_insn, @arch_module.register(reg)) end
Private Instance Methods
arch_field()
click to toggle source
Find the field name of Architecture.
# File lib/crabstone/instruction.rb, line 170 def arch_field klass = @arch_module.const_get(:Instruction) obj = Binding::Architecture.new Binding::Architecture.members.find do |sym| obj[sym].instance_of?(klass) end end
init_detail(detail)
click to toggle source
# File lib/crabstone/instruction.rb, line 161 def init_detail(detail) @detail = detail @arch_insn = @detail[:arch][arch_field] @regs_read = @detail[:regs_read].first(@detail[:regs_read_count]) @regs_write = @detail[:regs_write].first(@detail[:regs_write_count]) @groups = @detail[:groups].first(@detail[:groups_count]) end
raise_if_diet()
click to toggle source
# File lib/crabstone/instruction.rb, line 157 def raise_if_diet Crabstone::Error.raise!(ErrDiet) if DIET_MODE end
raise_unless_detailed()
click to toggle source
# File lib/crabstone/instruction.rb, line 153 def raise_unless_detailed Crabstone::Error.raise!(ErrDetail) unless detailed? end