Class: Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Util

Inherits:
Object
  • Object
show all
Includes:
LibraryHelper
Defined in:
lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb

Overview

Utility methods and constants for dealing with most types of variables.

Constant Summary collapse

PRIMITIVE_TYPE_SIZES =
{
  :int => 4,
  :__int8 => 1,
  :__int16 => 2,
  :__int32 => 4,
  :__int64 => 8,
  :bool => 1,
  :char => 1,
  :short => 2,
  :long => 4,
  :long_long => 8,
  :float => 4,
  :double => 8,
  :long_double => 8,
  :wchar_t => 2,
}
TYPE_DEFINITIONS =

Maps a data type to its corresponding primitive or special type :pointer. Note, primitive types are mapped to themselves.

typedef info: msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx

{
  ##
  # Primitives
  ##
  :int => :int,
  :__int8 => :__int8,
  :__int16 => :__int16,
  :__int32 => :__int32,
  :__int64 => :__int64,
  :bool => :bool,
  :char => :char,
  :short => :short,
  :long => :long,
  :long_long => :long_long,
  :float => :float,
  :double => :double,
  :long_double => :long_double,
  :wchar_t => :wchar_t,
  ##
  # Non-pointers
  ##
  #typedef WORD ATOM;
  :ATOM => :short,
  #typedef int BOOL;
  :BOOL => :int,
  #typedef BYTE BOOLEAN;
  :BOOLEAN => :char,
  #typedef unsigned char BYTE;
  :BYTE => :char,
  #typedef char CHAR;
  :CHAR => :char,
  #typedef DWORD COLORREF;
  :COLORREF => :long,
  #typedef unsigned long DWORD;
  :DWORD => :long,
  #typedef unsigned int DWORD32;
  :DWORD32 => :int,
  #typedef unsigned __int64 DWORD64;
  :DWORD64 => :__int64,
  #typedef float FLOAT;
  :FLOAT => :float,
  #typedef int HFILE;
  :HFILE => :int,
  #typedef LONG HRESULT;
  :HRESULT => :long,
  #typedef int INT;
  :INT => :int,
  #typedef signed int INT32;
  :INT32 => :int,
  #typedef signed __int64 INT64;
  :INT64 => :__int64,
  #typedef WORD LANGID;
  :LANGID => :short,
  #typedef DWORD LCID;
  :LCID => :long,
  #typedef DWORD LCTYPE;
  :LCTYPE => :long,
  #typedef DWORD LGRPID;
  :LGRPID => :long,
  #typedef long LONG;
  :LONG => :long,
  #typedef signed int LONG32;
  :LONG32 => :int,
  #typedef __int64 LONG64;
  :LONG64 => :__int64,
  #typedef PDWORD PLCID;
  :PLCID => :pointer,
  #typedef LPVOID SC_LOCK;
  :SC_LOCK => :pointer,
  #typedef short SHORT;
  :SHORT => :short,
  #typedef unsigned char UCHAR;
  :UCHAR => :char,
  #typedef unsigned int UINT;
  :UINT => :int,
  #typedef unsigned int UINT32;
  :UINT32 => :int,
  #typedef unsigned long ULONG;
  :ULONG => :long,
  #typedef unsigned int ULONG32;
  :ULONG32 => :int,
  #typedef unsigned __int64 ULONG64;
  :ULONG64 => :__int64,
  #typedef unsigned short USHORT;
  :USHORT => :short,
  #typedef wchar_t WCHAR;
  :WCHAR => :wchar_t,
  #typedef unsigned short WORD;
  :WORD => :short,
  ##
  # Pointers declared with *
  ##
  #typedef DWORD* LPCOLORREF;
  :LPCOLORREF => :pointer,
  #typedef void* LPCVOID;
  :LPCVOID => :pointer,
  #typedef WCHAR* LPCWSTR;
  :LPCWSTR => :pointer,
  #typedef DWORD* LPDWORD;
  :LPDWORD => :pointer,
  #typedef HANDLE* LPHANDLE;
  :LPHANDLE => :pointer,
  #typedef int* LPINT;
  :LPINT => :pointer,
  #typedef long* LPLONG;
  :LPLONG => :pointer,
  #typedef CHAR* LPSTR;
  :LPSTR => :pointer,
  #typedef void* LPVOID;
  :LPVOID => :pointer,
  #typedef WORD* LPWORD;
  :LPWORD => :pointer,
  #typedef WCHAR* LPWSTR;
  :LPWSTR => :pointer,
  #typedef BOOL* PBOOL;
  :PBOOL => :pointer,
  #typedef BOOLEAN* PBOOLEAN;
  :PBOOLEAN => :pointer,
  #typedef BYTE* PBYTE;
  :PBYTE => :pointer,
  #typedef CHAR* PCHAR;
  :PCHAR => :pointer,
  #typedef CHAR* PCSTR;
  :PCSTR => :pointer,
  #typedef WCHAR* PCWSTR;
  :PCWSTR => :pointer,
  #typedef DWORD* PDWORD;
  :PDWORD => :pointer,
  #typedef DWORDLONG* PDWORDLONG;
  :PDWORDLONG => :pointer,
  #typedef DWORD_PTR* PDWORD_PTR;
  :PDWORD_PTR => :pointer,
  #typedef DWORD32* PDWORD32;
  :PDWORD32 => :pointer,
  #typedef DWORD64* PDWORD64;
  :PDWORD64 => :pointer,
  #typedef FLOAT* PFLOAT;
  :PFLOAT => :pointer,
  #typedef HANDLE* PHANDLE;
  :PHANDLE => :pointer,
  #typedef HKEY* PHKEY;
  :PHKEY => :pointer,
  #typedef int* PINT;
  :PINT => :pointer,
  #typedef INT_PTR* PINT_PTR;
  :PINT_PTR => :pointer,
  #typedef INT32* PINT32;
  :PINT32 => :pointer,
  #typedef INT64* PINT64;
  :PINT64 => :pointer,
  #typedef LONG* PLONG;
  :PLONG => :pointer,
  #typedef LONGLONG* PLONGLONG;
  :PLONGLONG => :pointer,
  #typedef LONG_PTR* PLONG_PTR;
  :PLONG_PTR => :pointer,
  #typedef LONG32* PLONG32;
  :PLONG32 => :pointer,
  #typedef LONG64* PLONG64;
  :PLONG64 => :pointer,
  #typedef SHORT* PSHORT;
  :PSHORT => :pointer,
  #typedef SIZE_T* PSIZE_T;
  :PSIZE_T => :pointer,
  #typedef SSIZE_T* PSSIZE_T;
  :PSSIZE_T => :pointer,
  #typedef CHAR* PSTR;
  :PSTR => :pointer,
  #typedef TBYTE* PTBYTE;
  :PTBYTE => :pointer,
  #typedef TCHAR* PTCHAR;
  :PTCHAR => :pointer,
  #typedef UCHAR* PUCHAR;
  :PUCHAR => :pointer,
  #typedef UINT* PUINT;
  :PUINT => :pointer,
  #typedef UINT_PTR* PUINT_PTR;
  :PUINT_PTR => :pointer,
  #typedef UINT32* PUINT32;
  :PUINT32 => :pointer,
  #typedef UINT64* PUINT64;
  :PUINT64 => :pointer,
  #typedef ULONG* PULONG;
  :PULONG => :pointer,
  #typedef ULONGLONG* PULONGLONG;
  :PULONGLONG => :pointer,
  #typedef ULONG_PTR* PULONG_PTR;
  :PULONG_PTR => :pointer,
  #typedef ULONG32* PULONG32;
  :PULONG32 => :pointer,
  #typedef ULONG64* PULONG64;
  :PULONG64 => :pointer,
  #typedef USHORT* PUSHORT;
  :PUSHORT => :pointer,
  #typedef void* PVOID;
  :PVOID => :pointer,
  #typedef WCHAR* PWCHAR;
  :PWCHAR => :pointer,
  #typedef WORD* PWORD;
  :PWORD => :pointer,
  #typedef WCHAR* PWSTR;
  :PWSTR => :pointer,
  #typedef HANDLE HACCEL;
  :HACCEL => :pointer,
  ##
  #  Handles
  ##
  #typedef PVOID HANDLE;
  :HANDLE => :pointer,
  #typedef HANDLE HBITMAP;
  :HBITMAP => :pointer,
  #typedef HANDLE HBRUSH;
  :HBRUSH => :pointer,
  #typedef HANDLE HCOLORSPACE;
  :HCOLORSPACE => :pointer,
  #typedef HANDLE HCONV;
  :HCONV => :pointer,
  #typedef HANDLE HCONVLIST;
  :HCONVLIST => :pointer,
  #typedef HANDLE HDC;
  :HDC => :pointer,
  #typedef HANDLE HDDEDATA;
  :HDDEDATA => :pointer,
  #typedef HANDLE HDESK;
  :HDESK => :pointer,
  #typedef HANDLE HDROP;
  :HDROP => :pointer,
  #typedef HANDLE HDWP;
  :HDWP => :pointer,
  #typedef HANDLE HENHMETAFILE;
  :HENHMETAFILE => :pointer,
  #typedef HANDLE HFONT;
  :HFONT => :pointer,
  #typedef HANDLE HGDIOBJ;
  :HGDIOBJ => :pointer,
  #typedef HANDLE HGLOBAL;
  :HGLOBAL => :pointer,
  #typedef HANDLE HHOOK;
  :HHOOK => :pointer,
  #typedef HANDLE HICON;
  :HICON => :pointer,
  #typedef HANDLE HINSTANCE;
  :HINSTANCE => :pointer,
  #typedef HANDLE HKEY;
  :HKEY => :pointer,
  #typedef HANDLE HKL;
  :HKL => :pointer,
  #typedef HANDLE HLOCAL;
  :HLOCAL => :pointer,
  #typedef HANDLE HMENU;
  :HMENU => :pointer,
  #typedef HANDLE HMETAFILE;
  :HMETAFILE => :pointer,
  #typedef HANDLE HPALETTE;
  :HPALETTE => :pointer,
  #typedef HANDLE HPEN;
  :HPEN => :pointer,
  #typedef HANDLE HRGN;
  :HRGN => :pointer,
  #typedef HANDLE HRSRC;
  :HRSRC => :pointer,
  #typedef HANDLE HSZ;
  :HSZ => :pointer,
  #typedef HANDLE WINSTA;
  :WINSTA => :pointer,
  #typedef HANDLE HWND;
  :HWND => :pointer,
  #typedef HANDLE SC_HANDLE;
  :SC_HANDLE => :pointer,
  #typedef HANDLE SERVICE_STATUS_HANDLE;
  :SERVICE_STATUS_HANDLE => :pointer,
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from LibraryHelper

#asciiz_to_str, #assemble_buffer, #param_to_number, #str_to_ascii_z, #str_to_uni_z, #uniz_to_str

Constructor Details

#initialize(railgun, arch) ⇒ Util

param 'railgun' is a Railgun instance. param 'arch' is the client.arch



317
318
319
320
321
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 317

def initialize(railgun, arch)
  @railgun = railgun
  @is_64bit = arch == ARCH_X64
  @process_heap = nil
end

Instance Attribute Details

#is_64bitObject (protected)

Returns the value of attribute is_64bit.



712
713
714
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 712

def is_64bit
  @is_64bit
end

#railgunObject (protected)

Returns the value of attribute railgun.



712
713
714
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 712

def railgun
  @railgun
end

Instance Method Details

#alloc_and_write_data(data) ⇒ Object



352
353
354
355
356
357
358
359
360
361
362
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 352

def alloc_and_write_data(data)
  return nil if data.nil? || process_heap.nil?

  result = railgun.kernel32.HeapAlloc(process_heap, railgun.const('HEAP_ZERO'), data.length)
  return nil if result['return'].nil?

  addr = result['return']
  return nil unless railgun.memwrite(addr, data, data.length)

  addr
end

#alloc_and_write_string(value) ⇒ Object

Write ASCII strings to memory.

Given a string, returns a pointer to a null terminated CHARs array. InitializeStr(&Str,“string”);



420
421
422
423
424
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 420

def alloc_and_write_string(value)
  return nil if value.nil?

  alloc_and_write_data(str_to_ascii_z(value))
end

#alloc_and_write_wstring(value) ⇒ Object

Write Unicode strings to memory.

Given a string, returns a pointer to a null terminated WCHARs array.



406
407
408
409
410
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 406

def alloc_and_write_wstring(value)
  return nil if value.nil?

  alloc_and_write_data(str_to_uni_z(value))
end

#calc_padding(offset) ⇒ Object

Number of bytes that needed to be added to be aligned.



658
659
660
661
662
663
664
665
666
667
668
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 658

def calc_padding(offset)
  align = required_alignment

  # If offset is not aligned...
  if (offset % align) != 0
    # Calculate padding needed to be aligned
    align - (offset & (align - 1))
  else
    0
  end
end

#free_data(*ptrs) ⇒ Object Also known as: free_wstring, free_string



364
365
366
367
368
369
370
371
372
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 364

def free_data(*ptrs)
  return false if ptrs.empty?
  return false if process_heap.nil?

  results = railgun.multi(
    ptrs.map { |ptr| ['kernel32', 'HeapFree', [process_heap, 0, ptr.to_i]] }
  )
  results.map { |res| res['return'] }.all?
end

#is_array_type?(type) ⇒ Boolean

Returns whether the given type represents an array of another type For example BYTE, BYTE, or even PDWORD

Returns:

  • (Boolean)


565
566
567
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 565

def is_array_type?(type)
  return type =~ /^\w+\[\w+\]$/ ? true : false
end

#is_null_pointer(pointer) ⇒ Object

Returns true if pointer will be considered a 'null' pointer.

If pointer is nil or 0, returns true If pointer is a String, if 0 after unpacking, returns true false otherwise

See #unpack_pointer



344
345
346
347
348
349
350
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 344

def is_null_pointer(pointer)
  if pointer.kind_of? String
    pointer = unpack_pointer(pointer)
  end

  return pointer.nil? || pointer == 0
end

#is_pointer_type?(type) ⇒ Boolean

Returns true if the data type is a pointer, false otherwise

Returns:

  • (Boolean)


559
560
561
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 559

def is_pointer_type?(type)
  return TYPE_DEFINITIONS[type] == :pointer
end

#is_struct_type?(type) ⇒ Boolean

Returns true if the type passed describes a data structure, false otherwise

Returns:

  • (Boolean)


570
571
572
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 570

def is_struct_type?(type)
  return type.kind_of? Array
end

#judge_bit_field(value, mappings) ⇒ Object

Evaluates a bit field, returning a hash representing the meaning and state of each bit.

Parameters:

+value+:: a bit field represented by a Integer
+mappings+:: { 'WINAPI_CONSTANT_NAME' => :descriptive_symbol, ... }

Returns:

{ :descriptive_symbol => true/false, ... }


700
701
702
703
704
705
706
707
708
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 700

def judge_bit_field(value, mappings)
  flags = {}

  mappings.each do |constant_name, key|
    flags[key] = (value & railgun.const(constant_name)) != 0
  end

  flags
end

#memread(address, size, buffer = nil) ⇒ Object

Read a given number of bytes from memory or from a provided buffer.

If buffer is not provided, read size bytes from the client's memory. If buffer is provided, reads size characters from the index of address.



454
455
456
457
458
459
460
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 454

def memread(address, size, buffer = nil)
  if buffer.nil?
    return railgun.memread(address, size)
  else
    return buffer[address .. (address + size - 1)]
  end
end

#pointer_sizeObject

Returns the pointer size for this architecture



576
577
578
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 576

def pointer_size
  is_64bit ? 8 : 4
end

#read_array(type, length, bufptr, buffer = nil) ⇒ Object

Read length number of instances of type from bufptr .

bufptr is an index in buffer or, if buffer is nil, a memory address



519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 519

def read_array(type, length, bufptr, buffer = nil)
  if length <= 0
    return []
  end

  size = sizeof_type(type)
  # Grab the bytes that the array consists of
  buffer = memread(bufptr, size * length, buffer)

  offset = 0

  1.upto(length).map do |n|
    data = read_data(type, offset, buffer)

    offset = offset + size

    data
  end
end

#read_data(type, position, buffer = nil) ⇒ Object

Reads data structures and several windows data types



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 472

def read_data(type, position, buffer = nil)
  if buffer.nil?
    buffer = memread(position, sizeof_type(type))
    position = 0
  end

  # If we're asked to read a data structure, deligate to read_struct
  if is_struct_type?(type)
    return read_struct(type, buffer, position)
  end

  # If the type is an array with a given size...
  #    BYTE[3] for example or BYTE[ENCRYPTED_PWLEN] or even PDWORD[23]
  if is_array_type?(type)
    # Separate the element type from the size of the array
    element_type, length = split_array_type(type)

    # Have read_array take care of the rest
    return read_array(element_type, length, position, buffer)
  end

  size = sizeof_type(type)
  raw  = memread(position, size, buffer)

  # read/unpack data for the types we have hard-coded support for
  case type
  when :LPWSTR
    # null-terminated string of 16-bit Unicode characters
    return read_wstring(read_pointer(raw))
  when :DWORD
    # Both on x86 and x64, DWORD is 32 bits
    return raw.unpack('V').first
  when :BOOL
    return raw.unpack('V').first == 1
  when :LONG
    return raw.unpack('V').first
  end

  #If nothing worked thus far, return it raw
  return raw
end

#read_pointer(buffer, offset = 0) ⇒ Object

Read and unpack a pointer from the given buffer at a given offset



465
466
467
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 465

def read_pointer(buffer, offset = 0)
  unpack_pointer(buffer[offset, (offset + pointer_size)])
end

#read_string(pointer, length = nil) ⇒ Object

Reads null-terminated ASCII strings from memory.

Given a pointer to a null terminated array of CHARs, return a ruby String. If pointer is NULL (see #is_null_pointer) returns an empty string.



435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 435

def read_string(pointer, length=nil)
  if is_null_pointer(pointer)
    return ''
  end

  unless length
    length = railgun.kernel32.lstrlenA(pointer)['return']
  end

  chars = read_array(:CHAR, length, pointer)
  return chars.join('')
end

#read_struct(definition, buffer, offset = 0) ⇒ Object

Construct the data structure described in definition from buffer starting from the index offset



543
544
545
546
547
548
549
550
551
552
553
554
555
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 543

def read_struct(definition, buffer, offset = 0)
  data = {}

  offsets = struct_offsets(definition, offset)

  definition.each do |mapping|
    key, data_type = mapping

    data[key] = read_data(data_type, offsets.shift, buffer)
  end

  data
end

#read_wstring(pointer, length = nil) ⇒ Object

Reads null-terminated unicode strings from memory.

Given a pointer to a null terminated array of WCHARs, return a ruby String. If pointer is NULL (see #is_null_pointer) returns an empty string.



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 381

def read_wstring(pointer, length = nil)
  # Return an empty string for null pointers
  if is_null_pointer(pointer)
    return ''
  end

  # If length not provided, use lstrlenW
  if length.nil?
    length = railgun.kernel32.lstrlenW(pointer)['return']
  end

  # Retrieve the array of characters
  chars = read_array(:WCHAR, length, pointer)

  # Concatenate the characters and convert to a ruby string
  str = uniz_to_str(chars.join(''))

  return str
end

#required_alignmentObject



651
652
653
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 651

def required_alignment
  is_64bit ? 8 : 4
end

#sizeof_struct(struct) ⇒ Object

Calculates the size of struct after alignment.



619
620
621
622
623
624
625
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 619

def sizeof_struct(struct)
  offsets = struct_offsets(struct, 0)
  last_data_size = sizeof_type(struct.last[1])
  size_no_padding = offsets.last + last_data_size

  return size_no_padding + calc_padding(size_no_padding)
end

#sizeof_type(type) ⇒ Object

Return the size, in bytes, of the given type



581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 581

def sizeof_type(type)
  if is_pointer_type?(type)
    return pointer_size
  end

  if type.kind_of? String
    if is_array_type?(type)
      element_type, length = split_array_type(type)
      return length * sizeof_type(element_type)
    else
      return sizeof_type(type.to_sym)
    end
  end

  if is_struct_type?(type)
    return sizeof_struct(type)
  end

  if TYPE_DEFINITIONS.has_key?(type)
    primitive = TYPE_DEFINITIONS[type]

    if primitive == :pointer
      return pointer_size
    end

    if PRIMITIVE_TYPE_SIZES.has_key?(primitive)
      return PRIMITIVE_TYPE_SIZES[primitive]
    else
      raise "Type #{type} was mapped to non-existent primitive #{primitive}"
    end
  end

  raise "Unable to determine size for type #{type}."
end

#split_array_type(type) ⇒ Object

Given an explicit array definition (e.g. BYTE) return size (e.g. 23) and and type (e.g. BYTE). If a constant is given, attempt to resolve it that constant.



675
676
677
678
679
680
681
682
683
684
685
686
687
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 675

def split_array_type(type)
  if type =~ /^(\w+)\[(\w+)\]$/
    element_type = $1
    length = $2
    unless length =~ /^\d+$/
      length = railgun.const(length)
    end

    return element_type.to_sym, length.to_i
  else
    raise "Can not split non-array type #{type}"
  end
end

#struct_offsets(definition, offset) ⇒ Object

Given a description of a data structure, returns an Array containing the offset from the beginning for each subsequent element, taking into consideration alignment and padding.



632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 632

def struct_offsets(definition, offset)
  padding = 0
  offsets = []
  definition.each do |mapping|
    key, data_type = mapping
    if sizeof_type(data_type) > padding
      offset = offset + padding
    end

    offsets.push(offset)

    offset = offset + sizeof_type(data_type)
    padding = calc_padding(offset)
  end

  offsets
end

#unpack_pointer(packed_pointer) ⇒ Object

Given a packed pointer, unpacks it according to architecture



326
327
328
329
330
331
332
333
# File 'lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb', line 326

def unpack_pointer(packed_pointer)
  if is_64bit
    # Assume little endian
    packed_pointer.unpack('Q<')[0]
  else
    packed_pointer.unpack('V')[0]
  end
end