Module: PWN::FFI::Capstone

Extended by:
Library
Defined in:
lib/pwn/ffi/capstone.rb

Overview

Thin libcapstone disassembler.

Defined Under Namespace

Classes: Insn

Constant Summary collapse

CS_ARCH_ARM =
0
CS_ARCH_ARM64 =
1
CS_ARCH_X86 =
3
CS_MODE_LITTLE_ENDIAN =
0
CS_MODE_32 =
4
CS_MODE_64 =
8

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.load_errorObject (readonly)

Returns the value of attribute load_error.



39
40
41
# File 'lib/pwn/ffi/capstone.rb', line 39

def load_error
  @load_error
end

Class Method Details

.authorsObject



93
94
95
# File 'lib/pwn/ffi/capstone.rb', line 93

public_class_method def self.authors
  "AUTHOR(S):\n  0day Inc. <[email protected]>\n"
end

.available?(opts = {}) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
52
# File 'lib/pwn/ffi/capstone.rb', line 49

public_class_method def self.available?(opts = {})
  opts[:mod]
  load_error.nil?
end

.disassemble(opts = {}) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/pwn/ffi/capstone.rb', line 54

public_class_method def self.disassemble(opts = {})
  raise 'ERROR: libcapstone not available' unless available?(mod: self)

  raw = opts[:bytes] || opts[:opcodes]
  raise 'ERROR: bytes is required' if raw.to_s.empty?

  bytes = raw.to_s.b
  arch, mode = arch_mode(arch: opts[:arch], endian: opts[:endian])
  handle = PubFFI::MemoryPointer.new(:size_t)
  raise 'ERROR: cs_open failed' unless cs_open(arch, mode, handle).zero?

  buf = PubFFI::MemoryPointer.from_string(bytes)
  insn_ptr = PubFFI::MemoryPointer.new(:pointer)
  count = cs_disasm(handle.read_ulong, buf, bytes.bytesize, (opts[:address] || 0).to_i, 0, insn_ptr)
  insns = []
  base = insn_ptr.read_pointer
  count.times do |i|
    insn = Insn.new(base + (i * Insn.size))
    insns << { address: insn[:address], mnemonic: insn[:mnemonic].to_s, op_str: insn[:op_str].to_s, size: insn[:size] }
  end
  cs_free(base, count) unless base.null?
  cs_close(handle)
  { engine: 'capstone', insns: insns, count: count }
end

.helpObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/pwn/ffi/capstone.rb', line 97

public_class_method def self.help
  puts "USAGE:
    # True when libcapstone is loadable.
    #{self}.available?(
      mod: 'optional - ignored; present so (opts = {}) reads opts['
    )

    # Disassemble bytes with Capstone.
    #{self}.disassemble(
      bytes: 'required - raw machine-code bytes',
      opcodes: 'optional - alias for bytes',
      arch: 'optional - x86_64|x86|arm|aarch64',
      endian: 'optional - :little or :big byte order',
      address: 'optional - start address'
    )

    # Print the AUTHOR(S) string for this module.
    #{self}.authors
  "
  constants.sort
end