Class: Rex::Post::Meterpreter::Extensions::Stdapi::Sys::Thread

Inherits:
Thread
  • Object
show all
Includes:
ObjectAliasesContainer
Defined in:
lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb

Overview

This class implements the Rex::Post::Thread interface which wrappers a logical thread for a given process.

Instance Attribute Summary collapse

Attributes included from ObjectAliasesContainer

#aliases

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ObjectAliasesContainer

#dump_alias_tree, #initialize_aliases, #method_missing

Constructor Details

#initialize(process, handle, tid) ⇒ Thread

Initialize the thread instance.



33
34
35
36
37
38
39
40
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 33

def initialize(process, handle, tid)
  self.process = process
  self.handle  = handle
  self.tid     = tid

  # Ensure the remote object is closed when all references are removed
  ObjectSpace.define_finalizer(self, self.class.finalize(process.client, handle))
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Rex::Post::Meterpreter::ObjectAliasesContainer

Instance Attribute Details

#handleObject

:nodoc:



191
192
193
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 191

def handle
  @handle
end

#processObject

:nodoc:



191
192
193
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 191

def process
  @process
end

#tidObject

:nodoc:



191
192
193
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 191

def tid
  @tid
end

Class Method Details

.close(client, handle) ⇒ Object

Closes the thread handle.



174
175
176
177
178
179
180
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 174

def self.close(client, handle)
  request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_CLOSE)
  request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
  client.send_request(request, nil)
  handle = nil
  return true
end

.finalize(client, handle) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 42

def self.finalize(client,handle)
  proc do
    deferred_close_proc = proc do
      begin
        self.close(client, handle)
      rescue => e
        elog("finalize method for thread failed", error: e)
      end
    end

    # Schedule the finalizing logic out-of-band; as this logic might be called in the context of a Signal.trap, which can't synchronize mutexes
    client.framework.sessions.schedule(deferred_close_proc)
  end
end

Instance Method Details

#closeObject

Instance method



183
184
185
186
187
188
189
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 183

def close
  unless self.handle.nil?
    ObjectSpace.undefine_finalizer(self)
    self.class.close(self.process.client, self.handle)
    self.handle = nil
  end
end

#pretty_regsObject

Formats the registers in a pretty way.



152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 152

def pretty_regs
  regs = query_regs

  buf  = sprintf("eax=%.8x ebx=%.8x ecx=%.8x edx=%.8x esi=%.8x edi=%.8x\n",
                 regs['eax'], regs['ebx'], regs['ecx'], regs['edx'], regs['esi'], regs['edi'])
  buf += sprintf("eip=%.8x esp=%.8x ebp=%.8x\n",
                 regs['eip'], regs['esp'], regs['ebp'])
  buf += sprintf("cs=%.4x ss=%.4x ds=%.4x es=%.4x fs=%.4x gs=%.4x\n",
                 regs['cs'], regs['ss'], regs['ds'], regs['es'], regs['fs'], regs['gs'])

  return buf
end

#query_regsObject

Queries the register state of the thread.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 112

def query_regs
  request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_QUERY_REGS)
  regs    = {}

  request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)

  response = process.client.send_request(request)

  response.each(TLV_TYPE_REGISTER) { |reg|
    regs[reg.get_tlv_value(TLV_TYPE_REGISTER_NAME)] = reg.get_tlv_value(TLV_TYPE_REGISTER_VALUE_32)
  }

  return regs
end

#resumeObject

Resumes the thread’s execution.



79
80
81
82
83
84
85
86
87
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 79

def resume
  request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_RESUME)

  request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)

  process.client.send_request(request)

  return true
end

#set_regs(regs_hash) ⇒ Object

Sets the register state of the thread. The registers are supplied in the form of a hash.



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 131

def set_regs(regs_hash)
  request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_SET_REGS)

  request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)

  # Add all of the register that we're setting
  regs_hash.each_key { |name|
    t = request.add_tlv(TLV_TYPE_REGISTER)

    t.add_tlv(TLV_TYPE_REGISTER_NAME, name)
    t.add_tlv(TLV_TYPE_REGISTER_VALUE_32, regs_hash[name])
  }

  process.client.send_request(request)

  return true
end

#suspendObject

Suspends the thread’s execution.



66
67
68
69
70
71
72
73
74
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 66

def suspend
  request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_SUSPEND)

  request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)

  process.client.send_request(request)

  return true
end

#terminate(code) ⇒ Object

Terminates the thread’s execution.



92
93
94
95
96
97
98
99
100
101
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb', line 92

def terminate(code)
  request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_TERMINATE)

  request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
  request.add_tlv(TLV_TYPE_EXIT_CODE, code)

  process.client.send_request(request)

  return true
end