Class: Crabstone::Disassembler

Inherits:
Object
  • Object
show all
Defined in:
lib/crabstone/disassembler.rb

Constant Summary collapse

SYNTAX =
{
  intel: 1,
  att: 2,
  no_regname: 3 # for PPC only
}.freeze
DETAIL =
{
  true => 3, # trololol
  false => 0
}.freeze
SKIPDATA =
{
  true => 3, # trololol
  false => 0
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arch, mode) ⇒ Disassembler

Returns a new instance of Disassembler.



30
31
32
33
34
35
36
37
# 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

Instance Attribute Details

#archObject (readonly)

Returns the value of attribute arch.



28
29
30
# File 'lib/crabstone/disassembler.rb', line 28

def arch
  @arch
end

#cshObject (readonly)

Returns the value of attribute csh.



28
29
30
# File 'lib/crabstone/disassembler.rb', line 28

def csh
  @csh
end

#decomposerObject

Returns the value of attribute decomposer.



28
29
30
# File 'lib/crabstone/disassembler.rb', line 28

def decomposer
  @decomposer
end

#modeObject (readonly)

Returns the value of attribute mode.



28
29
30
# File 'lib/crabstone/disassembler.rb', line 28

def mode
  @mode
end

#syntaxObject

Returns the value of attribute syntax.



28
29
30
# File 'lib/crabstone/disassembler.rb', line 28

def syntax
  @syntax
end

Instance Method Details

#closevoid

This method returns an undefined value.

After you close the engine, don’t use it anymore. Can’t believe I even have to write this.



43
44
45
# File 'lib/crabstone/disassembler.rb', line 43

def close
  safe { Binding.cs_close(@p_csh) }
end

#diet?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/crabstone/disassembler.rb', line 64

def diet?
  DIET_MODE
end

#disasm(code, offset, count = 0) ⇒ Array<Crabstone::Instruction>

Returns:



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/crabstone/disassembler.rb', line 106

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

#errnoObject



68
69
70
# File 'lib/crabstone/disassembler.rb', line 68

def errno
  Binding.cs_errno(@csh)
end

#reg_name(regid) ⇒ Object



98
99
100
101
102
103
# File 'lib/crabstone/disassembler.rb', line 98

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) ⇒ Object



123
124
125
# File 'lib/crabstone/disassembler.rb', line 123

def set_raw_option(opt, val)
  safe { Binding.cs_option(csh, opt, val) }
end

#skipdata(mnemonic = '.byte') ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 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 => e
        raise Crabstone::ErrSkipData, "Error in skipdata callback: #{e.message}"
      end
    end
  end

  set_raw_option(OPT_SKIPDATA_SETUP, cfg.pointer.address)
  set_raw_option(OPT_SKIPDATA, SKIPDATA[true])
end

#skipdata_offObject



94
95
96
# File 'lib/crabstone/disassembler.rb', line 94

def skipdata_off
  set_raw_option(OPT_SKIPDATA, SKIPDATA[false])
end

#versionObject



60
61
62
# File 'lib/crabstone/disassembler.rb', line 60

def version
  Crabstone.cs_version
end