librex 0.0.35 → 0.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +1 -1
- data/lib/rex/exploitation/javascriptosdetect.rb +3 -22
- data/lib/rex/exploitation/jsobfu.rb +489 -0
- data/lib/rex/io/stream_abstraction.rb +4 -3
- data/lib/rex/parser/acunetix_nokogiri.rb +394 -0
- data/lib/rex/parser/appscan_nokogiri.rb +366 -0
- data/lib/rex/parser/burp_session_nokogiri.rb +290 -0
- data/lib/rex/parser/nokogiri_doc_mixin.rb +5 -3
- data/lib/rex/pescan/scanner.rb +2 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +5 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +30 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +188 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +1 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +84 -14
- data/lib/rex/proto/http/header.rb +3 -3
- data/lib/rex/ropbuilder.rb +7 -0
- data/lib/rex/ropbuilder/rop.rb +257 -0
- data/lib/rex/ui/text/table.rb +9 -0
- metadata +10 -3
@@ -0,0 +1,290 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)),"nokogiri_doc_mixin")
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Parser
|
5
|
+
|
6
|
+
# If Nokogiri is available, define Burp Session document class.
|
7
|
+
#
|
8
|
+
# Burp Session XML files actually provide a lot, but since it also
|
9
|
+
# provides the originating url, we can pull most of the detail from
|
10
|
+
# the URI object.
|
11
|
+
load_nokogiri && class BurpSessionDocument < Nokogiri::XML::SAX::Document
|
12
|
+
|
13
|
+
include NokogiriDocMixin
|
14
|
+
|
15
|
+
# The resolver prefers your local /etc/hosts (or windows equiv), but will
|
16
|
+
# fall back to regular DNS. It retains a cache for the import to avoid
|
17
|
+
# spamming your network with DNS requests.
|
18
|
+
attr_reader :resolv_cache
|
19
|
+
|
20
|
+
# Since we try to resolve every time we hit a new web page, need to
|
21
|
+
# hang on to our misses. Presume that it's a permanent enough failure
|
22
|
+
# that it won't get fixed during this particular import
|
23
|
+
attr_reader :missed_cache
|
24
|
+
|
25
|
+
# If name resolution of the host fails out completely, you will not be
|
26
|
+
# able to import that Scan task. Other scan tasks in the same report
|
27
|
+
# should be unaffected.
|
28
|
+
attr_reader :parse_warning
|
29
|
+
|
30
|
+
def start_document
|
31
|
+
@parse_warnings = []
|
32
|
+
@parse_warned = []
|
33
|
+
@resolv_cache = {}
|
34
|
+
@missed_cache = []
|
35
|
+
end
|
36
|
+
|
37
|
+
def start_element(name=nil,attrs=[])
|
38
|
+
attrs = normalize_attrs(attrs)
|
39
|
+
block = @block
|
40
|
+
@state[:current_tag][name] = true
|
41
|
+
case name
|
42
|
+
when "host", "port", "protocol", "path"
|
43
|
+
@state[:has_text] = true
|
44
|
+
when "status"
|
45
|
+
@state[:has_text] = true
|
46
|
+
when "response"
|
47
|
+
@state[:has_text] = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def end_element(name=nil)
|
52
|
+
block = @block
|
53
|
+
case name
|
54
|
+
when "item" # Wrap up this item, but keep resolved web sites
|
55
|
+
collect_uri
|
56
|
+
report_web_site(&block)
|
57
|
+
handle_parse_warnings(&block)
|
58
|
+
report_web_page(&block)
|
59
|
+
report_web_service_info
|
60
|
+
report_web_host_info
|
61
|
+
# Reset the state once we close a host
|
62
|
+
@state = @state.select {|k| [:current_tag, :web_sites].include? k}
|
63
|
+
when "host"
|
64
|
+
@state[:has_text] = false
|
65
|
+
collect_host
|
66
|
+
@text = nil
|
67
|
+
when "port"
|
68
|
+
@state[:has_text] = false
|
69
|
+
collect_port
|
70
|
+
@text = nil
|
71
|
+
when "protocol"
|
72
|
+
@state[:has_text] = false
|
73
|
+
collect_protocol
|
74
|
+
@text = nil
|
75
|
+
when "path"
|
76
|
+
@state[:has_text] = false
|
77
|
+
collect_path_and_query
|
78
|
+
@text = nil
|
79
|
+
when "status"
|
80
|
+
@state[:has_text] = false
|
81
|
+
collect_status
|
82
|
+
@text = nil
|
83
|
+
when "response"
|
84
|
+
@state[:has_text] = false
|
85
|
+
collect_response
|
86
|
+
@text = nil
|
87
|
+
end
|
88
|
+
@state[:current_tag].delete name
|
89
|
+
end
|
90
|
+
|
91
|
+
def collect_host
|
92
|
+
return unless in_item
|
93
|
+
return unless has_text
|
94
|
+
@state[:host] = @text
|
95
|
+
end
|
96
|
+
|
97
|
+
def collect_port
|
98
|
+
return unless in_item
|
99
|
+
return unless has_text
|
100
|
+
return unless @text.to_i.to_s == @text.to_s
|
101
|
+
@state[:port] = @text.to_i
|
102
|
+
end
|
103
|
+
|
104
|
+
def collect_protocol
|
105
|
+
return unless in_item
|
106
|
+
return unless has_text
|
107
|
+
@state[:protocol] = @text
|
108
|
+
end
|
109
|
+
|
110
|
+
def collect_path_and_query
|
111
|
+
return unless in_item
|
112
|
+
return unless has_text
|
113
|
+
path,query = @text.split(/\?+/,2)
|
114
|
+
return unless path
|
115
|
+
if query
|
116
|
+
@state[:query] = "?#{query}" # Can be nil
|
117
|
+
end
|
118
|
+
if path =~ /https?:[\x5c\x2f][\x5c\x2f]+[^\x5c\x2f][^\x5c\x2f]+([^?]+)/
|
119
|
+
real_path = "/#{$1}"
|
120
|
+
else
|
121
|
+
real_path = path
|
122
|
+
end
|
123
|
+
@state[:path] = real_path
|
124
|
+
end
|
125
|
+
|
126
|
+
def collect_status
|
127
|
+
return unless in_item
|
128
|
+
return unless has_text
|
129
|
+
return unless @text.to_i.to_s == @text
|
130
|
+
@state[:status] = @text.to_i
|
131
|
+
end
|
132
|
+
|
133
|
+
def collect_uri
|
134
|
+
return unless in_item
|
135
|
+
return unless @state[:host]
|
136
|
+
return unless @state[:port]
|
137
|
+
return unless @state[:protocol]
|
138
|
+
return unless @state[:path]
|
139
|
+
url = @state[:protocol].to_s
|
140
|
+
url << "://"
|
141
|
+
url << @state[:host].to_s
|
142
|
+
url << ":"
|
143
|
+
url << @state[:port].to_s
|
144
|
+
url << @state[:path]
|
145
|
+
if @state[:query]
|
146
|
+
url << "?"
|
147
|
+
url << @state[:query]
|
148
|
+
end
|
149
|
+
@state[:uri] = URI.parse(url) rescue nil
|
150
|
+
end
|
151
|
+
|
152
|
+
def report_web_host_info
|
153
|
+
return unless @state[:web_site]
|
154
|
+
return unless @state[:uri].kind_of? URI::HTTP
|
155
|
+
return unless @state[:web_site].service.host.name.to_s.empty?
|
156
|
+
host_info = {:workspace => @args[:wspace]}
|
157
|
+
host_info[:address] = @state[:web_site].service.host.address
|
158
|
+
host_info[:name] = @state[:uri].host
|
159
|
+
report_db(:host, host_info)
|
160
|
+
end
|
161
|
+
|
162
|
+
def report_web_service_info
|
163
|
+
return unless @state[:web_site]
|
164
|
+
return unless @state[:service_info]
|
165
|
+
return unless @state[:web_site].service.info.to_s.empty?
|
166
|
+
service_info = {}
|
167
|
+
service_info[:host] = @state[:web_site].service.host
|
168
|
+
service_info[:port] = @state[:web_site].service.port
|
169
|
+
service_info[:proto] = @state[:web_site].service.proto
|
170
|
+
service_info[:info] = @state[:service_info]
|
171
|
+
db_report(:service, service_info)
|
172
|
+
end
|
173
|
+
|
174
|
+
def report_web_page(&block)
|
175
|
+
return unless @state[:uri].kind_of? URI::HTTP
|
176
|
+
return unless @state[:status]
|
177
|
+
return unless @state[:web_site]
|
178
|
+
return unless @state[:response_headers].kind_of? Hash
|
179
|
+
headers = {}
|
180
|
+
@state[:response_headers].each do |k,v|
|
181
|
+
headers[k.to_s.downcase] ||= []
|
182
|
+
headers[k.to_s.downcase] << v
|
183
|
+
end
|
184
|
+
if headers["server"].kind_of? Array
|
185
|
+
@state[:service_info] = headers["server"].first
|
186
|
+
end
|
187
|
+
return unless @state[:response_body]
|
188
|
+
web_page_info = {:workspace => @args[:wspace]}
|
189
|
+
web_page_info[:web_site] = @state[:web_site]
|
190
|
+
web_page_info[:code] = @state[:status]
|
191
|
+
web_page_info[:path] = @state[:uri].path
|
192
|
+
web_page_info[:headers] = headers
|
193
|
+
web_page_info[:body] = @state[:response_body]
|
194
|
+
web_page_info[:query] = @state[:uri].query
|
195
|
+
url = @state[:uri].to_s.gsub(/\?.*/,"")
|
196
|
+
db.emit(:web_page, url, &block) if block
|
197
|
+
db_report(:web_page, web_page_info)
|
198
|
+
end
|
199
|
+
|
200
|
+
def report_web_site(&block)
|
201
|
+
return unless @state[:uri].kind_of? URI::HTTP
|
202
|
+
vhost = @state[:uri].host
|
203
|
+
web_site_info = {:workspace => @args[:wspace]}
|
204
|
+
web_site_info[:vhost] = vhost
|
205
|
+
address = resolve_vhost_address(@state[:uri])
|
206
|
+
return unless address
|
207
|
+
web_site_info[:host] = address
|
208
|
+
web_site_info[:port] = @state[:uri].port
|
209
|
+
web_site_info[:ssl] = @state[:uri].kind_of? URI::HTTPS
|
210
|
+
web_site_obj = db_report(:web_site, web_site_info)
|
211
|
+
return unless web_site_obj
|
212
|
+
@state[:web_sites] ||= []
|
213
|
+
url = "#{@state[:uri].scheme}://#{@state[:uri].host}:#{@state[:uri].port}"
|
214
|
+
unless @state[:web_sites].include? web_site_obj
|
215
|
+
db.emit(:web_site, url, &block)
|
216
|
+
@state[:web_sites] << web_site_obj
|
217
|
+
end
|
218
|
+
@state[:web_site] = web_site_obj
|
219
|
+
end
|
220
|
+
|
221
|
+
def collect_response
|
222
|
+
return unless in_item
|
223
|
+
return unless has_text
|
224
|
+
response_text = @text.dup
|
225
|
+
response_header_text,response_body_text = response_text.split(/\r*\n\r*\n/n,2)
|
226
|
+
return unless response_header_text
|
227
|
+
response_header = Rex::Proto::Http::Packet::Header.new
|
228
|
+
response_header.from_s response_header_text
|
229
|
+
@state[:response_headers] = response_header
|
230
|
+
@state[:response_body] = response_body_text
|
231
|
+
end
|
232
|
+
|
233
|
+
def in_item
|
234
|
+
return false unless in_tag("item")
|
235
|
+
return false unless in_tag("items")
|
236
|
+
return true
|
237
|
+
end
|
238
|
+
|
239
|
+
def has_text
|
240
|
+
return false unless @text
|
241
|
+
return false if @text.strip.empty?
|
242
|
+
@text = @text.strip
|
243
|
+
end
|
244
|
+
|
245
|
+
def handle_parse_warnings(&block)
|
246
|
+
return if @parse_warnings.empty?
|
247
|
+
return unless block
|
248
|
+
@parse_warnings.each_with_index do |pwarn,i|
|
249
|
+
unless @parse_warned.include? i
|
250
|
+
db.emit(:warning, pwarn, &block)
|
251
|
+
@parse_warned << i
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def resolve_address(host)
|
257
|
+
return @resolv_cache[host] if @resolv_cache[host]
|
258
|
+
return false if @missed_cache.include? host
|
259
|
+
address = Rex::Socket.resolv_to_dotted(host) rescue nil
|
260
|
+
@resolv_cache[host] = address
|
261
|
+
if address
|
262
|
+
block = @block
|
263
|
+
db.emit(:address, address, &block) if block
|
264
|
+
else
|
265
|
+
@missed_cache << host
|
266
|
+
end
|
267
|
+
return address
|
268
|
+
end
|
269
|
+
|
270
|
+
# Alias this
|
271
|
+
def resolve_vhost_address(uri)
|
272
|
+
if uri.host
|
273
|
+
address = resolve_address(uri.host)
|
274
|
+
case address
|
275
|
+
when false
|
276
|
+
return false
|
277
|
+
when nil
|
278
|
+
@parse_warnings << "Could not resolve address for '#{uri.host}', skipping."
|
279
|
+
end
|
280
|
+
else
|
281
|
+
@parse_warnings << "Could not determine a host for this import."
|
282
|
+
end
|
283
|
+
address
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
@@ -126,7 +126,8 @@ module Parser
|
|
126
126
|
nonempty_data = data.reject {|k,v| v.nil?}
|
127
127
|
valid_attrs = db_valid_attributes(table)
|
128
128
|
raise "Unknown table `#{table}'" if valid_attrs.empty?
|
129
|
-
|
129
|
+
case table
|
130
|
+
when :note, :web_site, :web_page, :web_form, :web_vuln
|
130
131
|
just_the_facts = nonempty_data
|
131
132
|
else
|
132
133
|
just_the_facts = nonempty_data.select {|k,v| valid_attrs.include? k.to_s.to_sym}
|
@@ -149,8 +150,9 @@ module Parser
|
|
149
150
|
when :vuln
|
150
151
|
Msf::DBManager::Vuln.new.attribute_names.map {|x| x.to_sym} |
|
151
152
|
[:host, :refs, :workspace, :port, :proto]
|
152
|
-
when :note
|
153
|
-
|
153
|
+
when :note, :web_site, :web_page, :web_form, :web_vuln
|
154
|
+
# These guys don't complain
|
155
|
+
[:anything]
|
154
156
|
else
|
155
157
|
[]
|
156
158
|
end
|
data/lib/rex/pescan/scanner.rb
CHANGED
@@ -31,6 +31,7 @@ module Scanner
|
|
31
31
|
if(param['disasm'])
|
32
32
|
#puts [msg].pack('H*').inspect
|
33
33
|
insns = []
|
34
|
+
|
34
35
|
msg.gsub!("; ", "\n")
|
35
36
|
if msg.include?("retn")
|
36
37
|
msg.gsub!("retn", "ret")
|
@@ -39,7 +40,7 @@ module Scanner
|
|
39
40
|
begin
|
40
41
|
d2 = Metasm::Shellcode.assemble(Metasm::Ia32.new, msg).disassemble
|
41
42
|
rescue Metasm::ParseError
|
42
|
-
d2 = Metasm::Shellcode.disassemble(Metasm::Ia32.new, [msg].pack('H*')
|
43
|
+
d2 = Metasm::Shellcode.disassemble(Metasm::Ia32.new, [msg].pack('H*'))
|
43
44
|
end
|
44
45
|
addr = 0
|
45
46
|
while ((di = d2.disassemble_instruction(addr)))
|
@@ -79,6 +79,8 @@ KEY_CREATE_SUB_KEY = 0x00000004
|
|
79
79
|
KEY_ENUMERATE_SUB_KEYS = 0x00000008
|
80
80
|
KEY_NOTIFY = 0x00000010
|
81
81
|
KEY_CREATE_LINK = 0x00000020
|
82
|
+
KEY_WOW64_64KEY = 0x00000100
|
83
|
+
KEY_WOW64_32KEY = 0x00000200
|
82
84
|
KEY_READ = (STANDARD_RIGHTS_READ | KEY_QUERY_VALUE |
|
83
85
|
KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & ~SYNCHRONIZE
|
84
86
|
KEY_WRITE = (STANDARD_RIGHTS_WRITE | KEY_SET_VALUE |
|
@@ -7,6 +7,7 @@ require 'rex/post/meterpreter/extensions/stdapi/constants'
|
|
7
7
|
require 'rex/post/meterpreter/extensions/stdapi/stdapi'
|
8
8
|
require 'rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key'
|
9
9
|
require 'rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value'
|
10
|
+
require 'rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key'
|
10
11
|
|
11
12
|
module Rex
|
12
13
|
module Post
|
@@ -44,9 +45,37 @@ class Registry
|
|
44
45
|
return RegistrySubsystem::RegistryKey.new(client, root_key, base_key, perm, root_key)
|
45
46
|
end
|
46
47
|
|
47
|
-
|
48
|
+
request = Packet.create_request('stdapi_registry_open_key')
|
49
|
+
|
50
|
+
request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
|
51
|
+
request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
|
52
|
+
request.add_tlv(TLV_TYPE_PERMISSION, perm)
|
53
|
+
|
54
|
+
response = client.send_request(request)
|
55
|
+
|
56
|
+
return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryKey.new(
|
57
|
+
client, root_key, base_key, perm, response.get_tlv(TLV_TYPE_HKEY).value)
|
48
58
|
end
|
49
59
|
|
60
|
+
#
|
61
|
+
# Opens the supplied registry key on the specified remote host. Requires that the
|
62
|
+
# current process has credentials to access the target and that the target has the
|
63
|
+
# remote registry service running.
|
64
|
+
#
|
65
|
+
def Registry.open_remote_key(target_host, root_key)
|
66
|
+
|
67
|
+
request = Packet.create_request('stdapi_registry_open_remote_key')
|
68
|
+
|
69
|
+
request.add_tlv(TLV_TYPE_TARGET_HOST, target_host)
|
70
|
+
request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
|
71
|
+
|
72
|
+
|
73
|
+
response = client.send_request(request)
|
74
|
+
|
75
|
+
return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RemoteRegistryKey.new(
|
76
|
+
client, target_host, root_key, response.get_tlv(TLV_TYPE_HKEY).value)
|
77
|
+
end
|
78
|
+
|
50
79
|
#
|
51
80
|
# Creates the supplied registry key or opens it if it already exists.
|
52
81
|
#
|
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rex/post/meterpreter/extensions/stdapi/constants'
|
4
|
+
require 'rex/post/meterpreter/extensions/stdapi/sys/registry'
|
5
|
+
|
6
|
+
module Rex
|
7
|
+
module Post
|
8
|
+
module Meterpreter
|
9
|
+
module Extensions
|
10
|
+
module Stdapi
|
11
|
+
module Sys
|
12
|
+
module RegistrySubsystem
|
13
|
+
|
14
|
+
###
|
15
|
+
#
|
16
|
+
# Class wrapper around a remote registry key on the remote side
|
17
|
+
#
|
18
|
+
###
|
19
|
+
class RemoteRegistryKey
|
20
|
+
|
21
|
+
|
22
|
+
#
|
23
|
+
# Initializes an instance of a registry key using the supplied properties
|
24
|
+
# and HKEY handle from the server.
|
25
|
+
#
|
26
|
+
def initialize(client, target_host, root_key, hkey)
|
27
|
+
self.client = client
|
28
|
+
self.root_key = root_key
|
29
|
+
self.target_host = target_host
|
30
|
+
self.hkey = hkey
|
31
|
+
|
32
|
+
ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.hkey) )
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.finalize(client,hkey)
|
36
|
+
proc { self.close(client,hkey) }
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
#
|
41
|
+
# Enumerators
|
42
|
+
#
|
43
|
+
##
|
44
|
+
|
45
|
+
#
|
46
|
+
# Enumerates all of the child keys within this registry key.
|
47
|
+
#
|
48
|
+
def each_key(&block)
|
49
|
+
return enum_key.each(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Enumerates all of the child values within this registry key.
|
54
|
+
#
|
55
|
+
def each_value(&block)
|
56
|
+
return enum_value.each(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Retrieves all of the registry keys that are direct descendents of
|
61
|
+
# the class' registry key.
|
62
|
+
#
|
63
|
+
def enum_key()
|
64
|
+
return self.client.sys.registry.enum_key(self.hkey)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Retrieves all of the registry values that exist within the opened
|
69
|
+
# registry key.
|
70
|
+
#
|
71
|
+
def enum_value()
|
72
|
+
return self.client.sys.registry.enum_value(self.hkey)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
##
|
77
|
+
#
|
78
|
+
# Registry key interaction
|
79
|
+
#
|
80
|
+
##
|
81
|
+
|
82
|
+
#
|
83
|
+
# Opens a registry key that is relative to this registry key.
|
84
|
+
#
|
85
|
+
def open_key(base_key, perm = KEY_READ)
|
86
|
+
return self.client.sys.registry.open_key(self.hkey, base_key, perm)
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Creates a registry key that is relative to this registry key.
|
91
|
+
#
|
92
|
+
def create_key(base_key, perm = KEY_READ)
|
93
|
+
return self.client.sys.registry.create_key(self.hkey, base_key, perm)
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Deletes a registry key that is relative to this registry key.
|
98
|
+
#
|
99
|
+
def delete_key(base_key, recursive = true)
|
100
|
+
return self.client.sys.registry.delete_key(self.hkey, base_key, recursive)
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Closes the open key. This must be called if the registry
|
105
|
+
# key was opened.
|
106
|
+
#
|
107
|
+
def self.close(client, hkey)
|
108
|
+
if hkey != nil
|
109
|
+
return client.sys.registry.close_key(hkey)
|
110
|
+
end
|
111
|
+
|
112
|
+
return false
|
113
|
+
end
|
114
|
+
|
115
|
+
# Instance method for the same
|
116
|
+
def close()
|
117
|
+
self.class.close(self.client, self.hkey)
|
118
|
+
end
|
119
|
+
|
120
|
+
##
|
121
|
+
#
|
122
|
+
# Registry value interaction
|
123
|
+
#
|
124
|
+
##
|
125
|
+
|
126
|
+
#
|
127
|
+
# Sets a value relative to the opened registry key.
|
128
|
+
#
|
129
|
+
def set_value(name, type, data)
|
130
|
+
return self.client.sys.registry.set_value(self.hkey, name, type, data)
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Queries the attributes of the supplied registry value relative to
|
135
|
+
# the opened registry key.
|
136
|
+
#
|
137
|
+
def query_value(name)
|
138
|
+
return self.client.sys.registry.query_value(self.hkey, name)
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Queries the class of the specified key
|
143
|
+
#
|
144
|
+
def query_class
|
145
|
+
return self.client.sys.registry.query_class(self.hkey)
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Delete the supplied registry value.
|
150
|
+
#
|
151
|
+
def delete_value(name)
|
152
|
+
return self.client.sys.registry.delete_value(self.hkey, name)
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
#
|
157
|
+
# Serializers
|
158
|
+
#
|
159
|
+
##
|
160
|
+
|
161
|
+
#
|
162
|
+
# Returns the path to the key.
|
163
|
+
#
|
164
|
+
def to_s
|
165
|
+
return "\\\\" + self.target_host + "\\" + self.root_key.to_s + "\\"
|
166
|
+
end
|
167
|
+
|
168
|
+
#
|
169
|
+
# The open handle to the key on the server.
|
170
|
+
#
|
171
|
+
attr_reader :hkey
|
172
|
+
#
|
173
|
+
# The root key name, such as HKEY_LOCAL_MACHINE.
|
174
|
+
#
|
175
|
+
attr_reader :root_key
|
176
|
+
#
|
177
|
+
# The remote machine name, such as PDC01
|
178
|
+
#
|
179
|
+
attr_reader :target_host
|
180
|
+
|
181
|
+
protected
|
182
|
+
|
183
|
+
attr_accessor :client # :nodoc:
|
184
|
+
attr_writer :hkey, :root_key, :target_host # :nodoc:
|
185
|
+
end
|
186
|
+
|
187
|
+
end; end; end; end; end; end; end
|
188
|
+
|