Class: PSRP::MessageEncoder

Inherits:
Message
  • Object
show all
Defined in:
lib/wsmv/psrp_message.rb

Overview

Constant Summary collapse

TEMPLATES =
{
  SESSION_CAPABILITY: 'session_capability',
  INIT_RUNSPACEPOOL: 'init_runspacepool',
  CREATE_PIPELINE: 'create_pipeline',
  RUNSPACE_AVAILABILITY: 'runspace_availability'

}
@@obj_id =
0

Constants inherited from Message

PSRP::Message::BLOB_HEADER_LEN, PSRP::Message::BLOB_MAX_LEN, PSRP::Message::MESSAGE_TYPES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Message

#uuid_to_windows_guid_bytes

Constructor Details

#initialize(shell_id, command_id, message_type, context = nil) ⇒ MessageEncoder

Returns a new instance of MessageEncoder.

Parameters:

  • payload (String)

    The PSRP payload as serialized XML



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/wsmv/psrp_message.rb', line 163

def initialize(shell_id, command_id, message_type, context = nil)
  fail 'shell_id cannot be nil' if shell_id.nil?
  @@obj_id += 1
  @id = @@obj_id
  @shell_id = shell_id
  @command_id = command_id
  @message_type = MESSAGE_TYPES[message_type]
  @payload = render(TEMPLATES[message_type], context).force_encoding('utf-8').bytes

  num_fragments = 1
  num_fragments += (@payload.length / BLOB_MAX_LEN)
  if (@payload.length % BLOB_MAX_LEN) == 0
    num_fragments -= 1
  end

  @fragments = []

  for i in 0..(num_fragments - 1)
    start_pos = (i * BLOB_MAX_LEN)
    end_pos = ((i + 1) * BLOB_MAX_LEN) - 1

    if num_fragments == 1
      flags = [3]
    elsif i == 0
      flags = [1]
    elsif i == (num_fragments - 1)
      flags = [2]
    else
      flags = [0]
    end

    @fragments.push(bytes(@payload[start_pos..end_pos], i, flags))
  end      
end

Instance Attribute Details

#fragmentsObject (readonly)

Returns the value of attribute fragments.



143
144
145
# File 'lib/wsmv/psrp_message.rb', line 143

def fragments
  @fragments
end

Instance Method Details

#bytes(blob, frag_id, flags) ⇒ Array<Byte>

Returns the raw PSRP message bytes ready for transfer to Windows inside a WinRM message. rubocop:disable Metrics/AbcSize

Returns:

  • (Array<Byte>)

    Unencoded raw byte array of the PSRP message.



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/wsmv/psrp_message.rb', line 214

def bytes(blob, frag_id, flags)

  # Packet fragment headers
  message = message_id
  message += fragment_id(frag_id)
  message += flags

  if frag_id == 0
    # packet fragment header
    message += blob_length(blob, BLOB_HEADER_LEN)

    # PSRP message header
    message += blob_destination
    message += message_type
    message += runspace_pool_id
    message += pipeline_id
    message += byte_order_mark + blob
  
  else
    # packet fragment header
    message += blob_length(blob, 0)
    # PSRP fragment
    message += blob
  end
  message
end

#render(template, context = nil) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Renders the specified template with the given context

Parameters:

  • template (String)

    The base filename of the PSRP message template.

  • context (Hash) (defaults to: nil)

    Any options required for rendering the template.

Returns:

  • (String)

    The rendered XML PSRP message.



203
204
205
206
207
208
# File 'lib/wsmv/psrp_message.rb', line 203

def render(template, context = nil)
  template_path = File.expand_path(
    "#{File.dirname(__FILE__)}/templates/#{template}.xml.erb")
  template = File.read(template_path)
  Erubis::Eruby.new(template).result(context)
end