CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb
Views: 11792
1
# -*- coding: binary -*-
2
3
require 'rex/post/thread'
4
require 'rex/post/meterpreter/client'
5
require 'rex/post/meterpreter/extensions/stdapi/constants'
6
7
module Rex
8
module Post
9
module Meterpreter
10
module Extensions
11
module Stdapi
12
module Sys
13
14
##
15
#
16
# This class implements the Rex::Post::Thread interface which
17
# wrappers a logical thread for a given process.
18
#
19
##
20
class Thread < Rex::Post::Thread
21
22
include Rex::Post::Meterpreter::ObjectAliasesContainer
23
24
##
25
#
26
# Constructor
27
#
28
##
29
30
#
31
# Initialize the thread instance.
32
#
33
def initialize(process, handle, tid)
34
self.process = process
35
self.handle = handle
36
self.tid = tid
37
38
# Ensure the remote object is closed when all references are removed
39
ObjectSpace.define_finalizer(self, self.class.finalize(process.client, handle))
40
end
41
42
def self.finalize(client,handle)
43
proc do
44
deferred_close_proc = proc do
45
begin
46
self.close(client, handle)
47
rescue => e
48
elog("finalize method for thread failed", error: e)
49
end
50
end
51
52
# 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
53
client.framework.sessions.schedule(deferred_close_proc)
54
end
55
end
56
57
##
58
#
59
# Execution
60
#
61
##
62
63
#
64
# Suspends the thread's execution.
65
#
66
def suspend
67
request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_SUSPEND)
68
69
request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
70
71
process.client.send_request(request)
72
73
return true
74
end
75
76
#
77
# Resumes the thread's execution.
78
#
79
def resume
80
request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_RESUME)
81
82
request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
83
84
process.client.send_request(request)
85
86
return true
87
end
88
89
#
90
# Terminates the thread's execution.
91
#
92
def terminate(code)
93
request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_TERMINATE)
94
95
request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
96
request.add_tlv(TLV_TYPE_EXIT_CODE, code)
97
98
process.client.send_request(request)
99
100
return true
101
end
102
103
##
104
#
105
# Register manipulation
106
#
107
##
108
109
#
110
# Queries the register state of the thread.
111
#
112
def query_regs
113
request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_QUERY_REGS)
114
regs = {}
115
116
request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
117
118
response = process.client.send_request(request)
119
120
response.each(TLV_TYPE_REGISTER) { |reg|
121
regs[reg.get_tlv_value(TLV_TYPE_REGISTER_NAME)] = reg.get_tlv_value(TLV_TYPE_REGISTER_VALUE_32)
122
}
123
124
return regs
125
end
126
127
#
128
# Sets the register state of the thread. The registers are supplied
129
# in the form of a hash.
130
#
131
def set_regs(regs_hash)
132
request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_SET_REGS)
133
134
request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
135
136
# Add all of the register that we're setting
137
regs_hash.each_key { |name|
138
t = request.add_tlv(TLV_TYPE_REGISTER)
139
140
t.add_tlv(TLV_TYPE_REGISTER_NAME, name)
141
t.add_tlv(TLV_TYPE_REGISTER_VALUE_32, regs_hash[name])
142
}
143
144
process.client.send_request(request)
145
146
return true
147
end
148
149
#
150
# Formats the registers in a pretty way.
151
#
152
def pretty_regs
153
regs = query_regs
154
155
buf = sprintf("eax=%.8x ebx=%.8x ecx=%.8x edx=%.8x esi=%.8x edi=%.8x\n",
156
regs['eax'], regs['ebx'], regs['ecx'], regs['edx'], regs['esi'], regs['edi'])
157
buf += sprintf("eip=%.8x esp=%.8x ebp=%.8x\n",
158
regs['eip'], regs['esp'], regs['ebp'])
159
buf += sprintf("cs=%.4x ss=%.4x ds=%.4x es=%.4x fs=%.4x gs=%.4x\n",
160
regs['cs'], regs['ss'], regs['ds'], regs['es'], regs['fs'], regs['gs'])
161
162
return buf
163
end
164
165
##
166
#
167
# Closure
168
#
169
##
170
171
#
172
# Closes the thread handle.
173
#
174
def self.close(client, handle)
175
request = Packet.create_request(COMMAND_ID_STDAPI_SYS_PROCESS_THREAD_CLOSE)
176
request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
177
client.send_request(request, nil)
178
handle = nil
179
return true
180
end
181
182
# Instance method
183
def close
184
unless self.handle.nil?
185
ObjectSpace.undefine_finalizer(self)
186
self.class.close(self.process.client, self.handle)
187
self.handle = nil
188
end
189
end
190
191
attr_reader :process, :handle, :tid # :nodoc:
192
protected
193
attr_writer :process, :handle, :tid # :nodoc:
194
195
end
196
197
end; end; end; end; end; end
198
199