Class: FFI::UDis86::UD

Inherits:
Struct
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ffi/udis86/ud.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.create(options = {}) {|ud| ... } ⇒ UD

Creates a new disassembler object.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options.

Options Hash (options):

  • :mode (Integer) — default: 32

    The mode of disassembly, can either 16, 32 or 64.

  • :syntax (Integer) — default: :intel

    The assembly syntax the disassembler will emit, can be either :att or :intel.

  • :buffer (String)

    A buffer to disassemble.

  • :vendor (Symbol)

    Sets the vendor of whose instructions to choose from. Can be either :amd or :intel.

  • :pc (Integer)

    Initial value of the Program Counter (PC).

Yields:

  • (ud)

    If a block is given, it will be used as an input callback to return the next byte to disassemble. When the block returns -1, the disassembler will stop processing input.

Yield Parameters:

  • ud (UD)

    The disassembler.

Returns:

  • (UD)

    The newly created disassembler.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ffi/udis86/ud.rb', line 89

def self.create(options={},&block)
  ud = self.new
  ud.init

  ud.mode = (options[:mode] || 32)

  if options[:buffer]
    ud.input_buffer = options[:buffer]
  end

  ud.syntax = (options[:syntax] || :intel)

  if options[:vendor]
    ud.vendor = options[:vendor]
  end

  if options[:pc]
    ud.pc = options[:pc]
  end

  ud.input_callback(&block) if block

  return ud
end

.open(path, options = {}) {|ud| ... } ⇒ Object

Opens a file and disassembles it.

Parameters:

  • path (String)

    The path to the file.

  • options (Hash) (defaults to: {})

    Additional options for the disassembler.

Options Hash (options):

  • :mode (Integer) — default: 32

    The mode of disassembly, can either 16, 32 or 64.

  • :syntax (Integer) — default: :intel

    The assembly syntax the disassembler will emit, can be either :att or :intel.

  • :buffer (String)

    A buffer to disassemble.

  • :vendor (Symbol)

    Sets the vendor of whose instructions to choose from. Can be either :amd or :intel.

  • :pc (Integer)

    Initial value of the Program Counter (PC).

Yields:

  • (ud)

    If a block is given, it will be passed the newly created UD object, configured to disassembler the file.

Yield Parameters:

  • ud (UD)

    The newly created disassembler.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/ffi/udis86/ud.rb', line 147

def self.open(path,options={})
  File.open(path,'rb') do |file|
    ud = self.create(options) do |ud|
      if (b = file.getc)
        b.ord
      else
        -1
      end
    end

    yield ud if block_given?
  end

  return nil
end

Instance Method Details

#address_prefixInteger

The address-size prefix (67h) of the last disassembled instruction.

Returns:

  • (Integer)

    The address-size prefix.



409
410
411
# File 'lib/ffi/udis86/ud.rb', line 409

def address_prefix
  self[:pfx_adr]
end

#disassemble {|ud| ... } ⇒ UD Also known as: disas, each

Reads each byte, disassembling each instruction.

Yields:

  • (ud)

    If a block is given, it will be passed the disassembler after each instruction has been disassembled.

Yield Parameters:

  • ud (UD)

    The disassembler.

Returns:

  • (UD)

    The disassembler.



543
544
545
546
547
548
549
# File 'lib/ffi/udis86/ud.rb', line 543

def disassemble
  until UDis86.ud_disassemble(self) == 0
    yield self if block_given?
  end

  return self
end

#initUD

Initializes the disassembler.

Returns:

  • (UD)

    The initialized disassembler.



169
170
171
172
# File 'lib/ffi/udis86/ud.rb', line 169

def init
  UDis86.ud_init(self)
  return self
end

#input_bufferString

Returns the input buffer used by the disassembler.

Returns:

  • (String)

    The current contents of the input buffer.



180
181
182
183
184
185
186
# File 'lib/ffi/udis86/ud.rb', line 180

def input_buffer
  if @input_buffer
    @input_buffer.get_bytes(0,@input_buffer.total)
  else
    ''
  end
end

#input_buffer=(data) ⇒ String

Sets the contents of the input buffer for the disassembler.

Parameters:

  • data (Array<Integer>, String)

    The new contents to use for the input buffer.

Returns:

  • (String)

    The new contents of the input buffer.

Raises:

  • (RuntimeError)

    The given input buffer was neither a String or an Array of bytes.



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/ffi/udis86/ud.rb', line 200

def input_buffer=(data)
  data = data.to_s

  @input_buffer = FFI::MemoryPointer.new(data.length)

  if data.kind_of?(Array)
    @input_buffer.put_array_of_uint8(0,data)
  elsif data.kind_of?(String)
    @input_buffer.put_bytes(0,data)
  else
    raise(RuntimeError,"input buffer must be either a String or an Array of bytes",caller)
  end

  UDis86.ud_set_input_buffer(self,@input_buffer,@input_buffer.total)
  return data
end

#input_callback {|ud| ... } ⇒ Object

Sets the input callback for the disassembler.

Yields:

  • (ud)

    If a block is given, it will be used to get the next byte of input to disassemble. When the block returns -1, the disassembler will stop processing input.

Yield Parameters:

  • The (UD)

    disassembler.



228
229
230
231
232
233
234
235
236
# File 'lib/ffi/udis86/ud.rb', line 228

def input_callback(&block)
  if block
    @input_callback = Proc.new { |ptr| block.call(self) }

    UDis86.ud_set_input_hook(self,@input_callback)
  end

  return @input_callback
end

#insn_lengthInteger

Returns the number of bytes that were disassembled.

Returns:

  • (Integer)

    The number of bytes disassembled.



504
505
506
# File 'lib/ffi/udis86/ud.rb', line 504

def insn_length
  UDis86.ud_insn_len(self)
end

#insn_offsetInteger

Returns the starting offset of the disassembled instruction relative to the initial value of the Program Counter (PC).

Returns:

  • (Integer)

    The offset of the instruction.



515
516
517
# File 'lib/ffi/udis86/ud.rb', line 515

def insn_offset
  UDis86.ud_insn_off(self)
end

#insn_ptrFFI::Pointer

Returns the pointer to the buffer holding the disassembled instruction bytes.

Returns:

  • (FFI::Pointer)

    The pointer to the instruction buffer.



526
527
528
# File 'lib/ffi/udis86/ud.rb', line 526

def insn_ptr
  UDis86.ud_insn_ptr(self)
end

#lock_prefixInteger

The lock prefix of the last disassembled instruction.

Returns:

  • (Integer)

    The lock prefix.



419
420
421
# File 'lib/ffi/udis86/ud.rb', line 419

def lock_prefix
  self[:pfx_lock]
end

#mnemonicSymbol

The mnemonic string of the last disassembled instruction.

Returns:

  • (Symbol)

    The mnemonic string.



369
370
371
# File 'lib/ffi/udis86/ud.rb', line 369

def mnemonic
  UDis86.ud_lookup_mnemonic(self[:mnemonic]).to_sym
end

#mnemonic_codeSymbol

The mnemonic code of the last disassembled instruction.

Returns:

  • (Symbol)

    The mnemonic code.



359
360
361
# File 'lib/ffi/udis86/ud.rb', line 359

def mnemonic_code
  self[:mnemonic]
end

#modeInteger

Returns the mode the disassembler is running in.

Returns:

  • (Integer)

    Returns either 16, 32 or 64.



244
245
246
# File 'lib/ffi/udis86/ud.rb', line 244

def mode
  self[:dis_mode]
end

#mode=(new_mode) ⇒ Integer

Sets the mode the disassembler will run in.

Parameters:

  • new_mode (Integer)

    The mode the disassembler will run in. Can be either 16, 32 or 64.

Returns:

  • (Integer)

    The new mode of the disassembler.



257
258
259
260
261
262
263
264
# File 'lib/ffi/udis86/ud.rb', line 257

def mode=(new_mode)
  unless MODES.include?(new_mode)
    raise(RuntimeError,"invalid disassembly mode #{new_mode}",caller)
  end

  UDis86.ud_set_mode(self,new_mode)
  return new_mode
end

#next_insnUD

Disassembles the next instruction in the input stream.

Returns:

  • (UD)

    The disassembler.



494
495
496
# File 'lib/ffi/udis86/ud.rb', line 494

def next_insn
  UDis86.ud_disassemble(self)
end

#operand_prefixInteger

The operand-size prefix (66h) of the last disassembled instruction.

Returns:

  • (Integer)

    The operand-size prefix.



399
400
401
# File 'lib/ffi/udis86/ud.rb', line 399

def operand_prefix
  self[:pfx_opr]
end

#operandsArray<Operand>

Returns the operands for the last disassembled instruction.

Returns:

  • (Array<Operand>)

    The operands of the instruction.



482
483
484
485
486
# File 'lib/ffi/udis86/ud.rb', line 482

def operands
  self[:operand].entries.select do |operand|
    OPERAND_TYPES.include?(operand.type)
  end
end

#pcInteger

Returns the current value of the Program Counter (PC).

Returns:

  • (Integer)

    The value of the PC.



320
321
322
# File 'lib/ffi/udis86/ud.rb', line 320

def pc
  self[:pc]
end

#pc=(new_pc) ⇒ Integer

Sets the value of the Program Counter (PC).

Parameters:

  • new_pc (Integer)

    The new value to use for the PC.

Returns:

  • (Integer)

    The new value of the PC.



333
334
335
336
# File 'lib/ffi/udis86/ud.rb', line 333

def pc=(new_pc)
  UDis86.ud_set_pc(self,new_pc)
  return new_pc
end

#rep_prefixInteger

The rep prefix of the last disassembled instruction.

Returns:

  • (Integer)

    The rep prefix.



429
430
431
# File 'lib/ffi/udis86/ud.rb', line 429

def rep_prefix
  self[:pfx_rep]
end

#repe_prefixInteger

The repe prefix of the last disassembled instruction.

Returns:

  • (Integer)

    The repe prefix.



439
440
441
# File 'lib/ffi/udis86/ud.rb', line 439

def repe_prefix
  self[:pfx_repe]
end

#repne_prefixInteger

The repne prefix of the last disassembled instruction.

Returns:

  • (Integer)

    The repne prefix.



449
450
451
# File 'lib/ffi/udis86/ud.rb', line 449

def repne_prefix
  self[:pfx_repne]
end

#rex_prefixInteger

The 64-bit mode REX prefix of the last disassembled instruction.

Returns:

  • (Integer)

    The 64-bit REX prefix.



379
380
381
# File 'lib/ffi/udis86/ud.rb', line 379

def rex_prefix
  self[:pfx_rex]
end

#segment_prefixInteger

The segment register prefix of the last disassembled instruction.

Returns:

  • (Integer)

    The segment register prefix.



389
390
391
# File 'lib/ffi/udis86/ud.rb', line 389

def segment_prefix
  self[:pfx_seg]
end

#skip(n) ⇒ UD

Causes the disassembler to skip a certain number of bytes in the input stream.

Parameters:

  • n (Integer)

    The number of bytes to skip.

Returns:

  • (UD)

    The disassembler.



348
349
350
351
# File 'lib/ffi/udis86/ud.rb', line 348

def skip(n)
  UDis86.ud_input_skip(self,n)
  return self
end

#syntax=(new_syntax) ⇒ Symbol

Sets the assembly syntax that the disassembler will emit.

Parameters:

  • new_syntax (Symbol, String)

    The new assembler syntax the disassembler will emit. Can be either :att or :intel.

Returns:

  • (Symbol)

    The new assembly syntax being used.



276
277
278
279
280
281
282
283
284
285
286
# File 'lib/ffi/udis86/ud.rb', line 276

def syntax=(new_syntax)
  new_syntax = new_syntax.to_s.downcase.to_sym
  func_name = UDis86::SYNTAX[new_syntax]

  unless func_name
    raise(ArgumentError,"unknown syntax name #{new_syntax}",caller)
  end

  UDis86.ud_set_syntax(self,UDis86.method(func_name))
  return new_syntax
end

#to_asmString Also known as: to_s

Returns the assembly syntax for the last disassembled instruction.

Returns:

  • (String)

    The assembly syntax for the instruction.



459
460
461
# File 'lib/ffi/udis86/ud.rb', line 459

def to_asm
  UDis86.ud_insn_asm(self)
end

#to_hexString

Returns the hexadecimal representation of the disassembled instruction.

Returns:

  • (String)

    The hexadecimal form of the disassembled instruction.



470
471
472
# File 'lib/ffi/udis86/ud.rb', line 470

def to_hex
  UDis86.ud_insn_hex(self)
end

#vendorSymbol

The vendor of whose instructions are to be chosen from during disassembly.

Returns:

  • (Symbol)

    The vendor name, may be either :amd or :intel.



295
296
297
# File 'lib/ffi/udis86/ud.rb', line 295

def vendor
  VENDORS[self[:vendor]]
end

#vendor=(new_vendor) ⇒ Symbol

Sets the vendor, of whose instructions are to be chosen from during disassembly.

Parameters:

  • new_vendor (Symbol)

    The new vendor to use, can be either :amd or :intel.

Returns:

  • (Symbol)

    The new vendor to use.



309
310
311
312
# File 'lib/ffi/udis86/ud.rb', line 309

def vendor=(new_vendor)
  UDis86.ud_set_vendor(self,VENDORS.index(new_vendor))
  return new_vendor
end