ruby_smb 1.0.0 → 1.1.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.travis.yml +4 -1
- data/README.md +35 -47
- data/examples/enum_registry_key.rb +28 -0
- data/examples/enum_registry_values.rb +30 -0
- data/examples/pipes.rb +2 -1
- data/examples/read_registry_key_value.rb +32 -0
- data/lib/ruby_smb/client/authentication.rb +43 -25
- data/lib/ruby_smb/client/echo.rb +20 -2
- data/lib/ruby_smb/client/negotiation.rb +27 -12
- data/lib/ruby_smb/client/tree_connect.rb +20 -14
- data/lib/ruby_smb/client/utils.rb +2 -2
- data/lib/ruby_smb/client/winreg.rb +46 -0
- data/lib/ruby_smb/client.rb +28 -4
- data/lib/ruby_smb/dcerpc/bind.rb +2 -2
- data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
- data/lib/ruby_smb/dcerpc/error.rb +3 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
- data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
- data/lib/ruby_smb/dcerpc/request.rb +28 -9
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
- data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
- data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
- data/lib/ruby_smb/dcerpc.rb +38 -0
- data/lib/ruby_smb/dispatcher/socket.rb +3 -1
- data/lib/ruby_smb/error.rb +40 -1
- data/lib/ruby_smb/generic_packet.rb +33 -4
- data/lib/ruby_smb/smb1/file.rb +67 -11
- data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
- data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/pipe.rb +86 -5
- data/lib/ruby_smb/smb1/tree.rb +40 -2
- data/lib/ruby_smb/smb2/file.rb +97 -1
- data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
- data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
- data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +8 -2
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
- data/lib/ruby_smb/smb2/pipe.rb +98 -11
- data/lib/ruby_smb/smb2/tree.rb +44 -6
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +0 -1
- data/ruby_smb.gemspec +3 -3
- data/spec/lib/ruby_smb/client_spec.rb +271 -11
- data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
- data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +3 -1
- data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
- data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
- data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
- data/spec/lib/ruby_smb/smb2/file_spec.rb +295 -2
- data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +78 -0
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +8 -0
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +322 -145
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +214 -0
- data.tar.gz.sig +0 -0
- metadata +70 -11
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
- data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
- data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +0 -37
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
class Client
|
|
3
|
+
module Winreg
|
|
4
|
+
|
|
5
|
+
def connect_to_winreg(host)
|
|
6
|
+
share = "\\\\#{host}\\IPC$"
|
|
7
|
+
tree = @tree_connects.find {|tree| tree.share == share}
|
|
8
|
+
tree = tree_connect(share) unless tree
|
|
9
|
+
named_pipe = tree.open_file(filename: "winreg", write: true, read: true)
|
|
10
|
+
if block_given?
|
|
11
|
+
res = yield named_pipe
|
|
12
|
+
named_pipe.close
|
|
13
|
+
res
|
|
14
|
+
else
|
|
15
|
+
named_pipe
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def has_registry_key?(host, key)
|
|
20
|
+
connect_to_winreg(host) do |named_pipe|
|
|
21
|
+
named_pipe.has_registry_key?(key)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def read_registry_key_value(host, key, value_name)
|
|
26
|
+
connect_to_winreg(host) do |named_pipe|
|
|
27
|
+
named_pipe.read_registry_key_value(key, value_name)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def enum_registry_key(host, key)
|
|
32
|
+
connect_to_winreg(host) do |named_pipe|
|
|
33
|
+
named_pipe.enum_registry_key(key)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def enum_registry_values(host, key)
|
|
38
|
+
connect_to_winreg(host) do |named_pipe|
|
|
39
|
+
named_pipe.enum_registry_values(key)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
data/lib/ruby_smb/client.rb
CHANGED
|
@@ -8,6 +8,7 @@ module RubySMB
|
|
|
8
8
|
require 'ruby_smb/client/tree_connect'
|
|
9
9
|
require 'ruby_smb/client/echo'
|
|
10
10
|
require 'ruby_smb/client/utils'
|
|
11
|
+
require 'ruby_smb/client/winreg'
|
|
11
12
|
|
|
12
13
|
include RubySMB::Client::Negotiation
|
|
13
14
|
include RubySMB::Client::Authentication
|
|
@@ -15,6 +16,7 @@ module RubySMB
|
|
|
15
16
|
include RubySMB::Client::TreeConnect
|
|
16
17
|
include RubySMB::Client::Echo
|
|
17
18
|
include RubySMB::Client::Utils
|
|
19
|
+
include RubySMB::Client::Winreg
|
|
18
20
|
|
|
19
21
|
# The Default SMB1 Dialect string used in an SMB1 Negotiate Request
|
|
20
22
|
SMB1_DIALECT_SMB1_DEFAULT = 'NT LM 0.12'.freeze
|
|
@@ -297,15 +299,32 @@ module RubySMB
|
|
|
297
299
|
# Sends a LOGOFF command to the remote server to terminate the session
|
|
298
300
|
#
|
|
299
301
|
# @return [WindowsError::ErrorCode] the NTStatus of the response
|
|
302
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response packet is not a LogoffResponse packet
|
|
300
303
|
def logoff!
|
|
301
304
|
if smb2
|
|
302
305
|
request = RubySMB::SMB2::Packet::LogoffRequest.new
|
|
303
306
|
raw_response = send_recv(request)
|
|
304
307
|
response = RubySMB::SMB2::Packet::LogoffResponse.read(raw_response)
|
|
308
|
+
unless response.valid?
|
|
309
|
+
raise RubySMB::Error::InvalidPacket.new(
|
|
310
|
+
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
311
|
+
expected_cmd: RubySMB::SMB2::Packet::LogoffResponse::COMMAND,
|
|
312
|
+
received_proto: response.smb2_header.protocol,
|
|
313
|
+
received_cmd: response.smb2_header.command
|
|
314
|
+
)
|
|
315
|
+
end
|
|
305
316
|
else
|
|
306
317
|
request = RubySMB::SMB1::Packet::LogoffRequest.new
|
|
307
318
|
raw_response = send_recv(request)
|
|
308
319
|
response = RubySMB::SMB1::Packet::LogoffResponse.read(raw_response)
|
|
320
|
+
unless response.valid?
|
|
321
|
+
raise RubySMB::Error::InvalidPacket.new(
|
|
322
|
+
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
323
|
+
expected_cmd: RubySMB::SMB1::Packet::LogoffResponse::COMMAND,
|
|
324
|
+
received_proto: response.smb_header.protocol,
|
|
325
|
+
received_cmd: response.smb_header.command
|
|
326
|
+
)
|
|
327
|
+
end
|
|
309
328
|
end
|
|
310
329
|
wipe_state!
|
|
311
330
|
response.status_code
|
|
@@ -380,14 +399,19 @@ module RubySMB
|
|
|
380
399
|
# @param name [String] the NetBIOS name to request
|
|
381
400
|
# @return [TrueClass] if session request is granted
|
|
382
401
|
# @raise [RubySMB::Error::NetBiosSessionService] if session request is refused
|
|
402
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response packet is not a NBSS packet
|
|
383
403
|
def session_request(name = '*SMBSERVER')
|
|
384
404
|
session_request = session_request_packet(name)
|
|
385
405
|
dispatcher.send_packet(session_request, nbss_header: false)
|
|
386
406
|
raw_response = dispatcher.recv_packet(full_response: true)
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
407
|
+
begin
|
|
408
|
+
session_header = RubySMB::Nbss::SessionHeader.read(raw_response)
|
|
409
|
+
if session_header.session_packet_type == RubySMB::Nbss::NEGATIVE_SESSION_RESPONSE
|
|
410
|
+
negative_session_response = RubySMB::Nbss::NegativeSessionResponse.read(raw_response)
|
|
411
|
+
raise RubySMB::Error::NetBiosSessionService, "Session Request failed: #{negative_session_response.error_msg}"
|
|
412
|
+
end
|
|
413
|
+
rescue IOError
|
|
414
|
+
raise RubySMB::Error::InvalidPacket, 'Not a NBSS packet'
|
|
391
415
|
end
|
|
392
416
|
|
|
393
417
|
return true
|
data/lib/ruby_smb/dcerpc/bind.rb
CHANGED
|
@@ -35,8 +35,8 @@ module RubySMB
|
|
|
35
35
|
|
|
36
36
|
pdu_header :pdu_header, label: 'PDU header'
|
|
37
37
|
|
|
38
|
-
uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value:
|
|
39
|
-
uint16 :max_recv_frag, label: 'max receive frag size', initial_value:
|
|
38
|
+
uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
|
|
39
|
+
uint16 :max_recv_frag, label: 'max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
|
|
40
40
|
uint32 :assoc_group_id, label: 'ncarnation of client-server assoc group'
|
|
41
41
|
|
|
42
42
|
p_cont_list_t :p_context_list, label: 'Presentation context list', endpoint: -> { endpoint }
|
|
@@ -46,8 +46,8 @@ module RubySMB
|
|
|
46
46
|
|
|
47
47
|
pdu_header :pdu_header, label: 'PDU header'
|
|
48
48
|
|
|
49
|
-
uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value:
|
|
50
|
-
uint16 :max_recv_frag, label: 'Max receive frag size', initial_value:
|
|
49
|
+
uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
|
|
50
|
+
uint16 :max_recv_frag, label: 'Max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
|
|
51
51
|
uint32 :assoc_group_id, label: 'Association group ID'
|
|
52
52
|
port_any_t :sec_addr, label: 'Secondary address'
|
|
53
53
|
string :pad, length: -> { pad_length }
|
data/lib/ruby_smb/dcerpc/ndr.rb
CHANGED
|
@@ -7,36 +7,115 @@ module RubySMB
|
|
|
7
7
|
VER_MAJOR = 2
|
|
8
8
|
VER_MINOR = 0
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
# An NDR Top-level Full Pointers representation as defined in
|
|
11
|
+
# [Transfer Syntax NDR - Top-level Full Pointers](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_11_01)
|
|
12
|
+
# This class must be inherited and the subclass must have a #referent protperty
|
|
13
|
+
class NdrTopLevelFullPointer < BinData::Primitive
|
|
11
14
|
endian :little
|
|
12
15
|
|
|
13
|
-
uint32
|
|
14
|
-
uint32 :offset, initial_value: 0
|
|
15
|
-
uint32 :actual_count, initial_value: -> { str.length }
|
|
16
|
-
stringz16 :str, read_length: -> { actual_count }
|
|
16
|
+
uint32 :referent_identifier, initial_value: 0x00020000
|
|
17
17
|
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
def get
|
|
19
|
+
is_a_null_pointer? ? 0 : self.referent
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def set(v)
|
|
23
|
+
if v.is_a?(Integer) && v == 0
|
|
24
|
+
self.referent_identifier = 0
|
|
25
|
+
else
|
|
26
|
+
self.referent = v
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def is_a_null_pointer?
|
|
31
|
+
self.referent_identifier == 0
|
|
22
32
|
end
|
|
23
33
|
end
|
|
24
34
|
|
|
25
|
-
|
|
35
|
+
# An NDR Conformant and Varying String representation as defined in
|
|
36
|
+
# [Transfer Syntax NDR - Conformant and Varying Strings](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_04_02)
|
|
37
|
+
# The string elements are Stringz16 (unicode)
|
|
38
|
+
class NdrString < BinData::Primitive
|
|
26
39
|
endian :little
|
|
27
40
|
|
|
28
|
-
uint32
|
|
29
|
-
|
|
41
|
+
uint32 :max_count
|
|
42
|
+
uint32 :offset, initial_value: 0
|
|
43
|
+
uint32 :actual_count
|
|
44
|
+
stringz16 :str, read_length: -> { actual_count }, onlyif: -> { actual_count > 0 }
|
|
30
45
|
|
|
31
|
-
def
|
|
32
|
-
self.
|
|
46
|
+
def get
|
|
47
|
+
self.actual_count == 0 ? 0 : self.str
|
|
33
48
|
end
|
|
34
49
|
|
|
50
|
+
def set(v)
|
|
51
|
+
if v.is_a?(Integer) && v == 0
|
|
52
|
+
self.actual_count = 0
|
|
53
|
+
else
|
|
54
|
+
self.str = v
|
|
55
|
+
self.max_count = self.actual_count = str.to_binary_s.size / 2
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# A pointer to a NdrString structure
|
|
61
|
+
class NdrLpStr < NdrTopLevelFullPointer
|
|
62
|
+
endian :little
|
|
63
|
+
|
|
64
|
+
ndr_string :referent, onlyif: -> { !is_a_null_pointer? }
|
|
65
|
+
|
|
35
66
|
def to_s
|
|
36
|
-
self.
|
|
67
|
+
is_a_null_pointer? ? "\0" : self.referent
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# An NDR Context Handle representation as defined in
|
|
72
|
+
# [IDL Data Type Declarations - Basic Type Declarations](http://pubs.opengroup.org/onlinepubs/9629399/apdxn.htm#tagcjh_34_01)
|
|
73
|
+
class NdrContextHandle < BinData::Primitive
|
|
74
|
+
endian :little
|
|
75
|
+
uint32 :context_handle_attributes
|
|
76
|
+
uuid :context_handle_uuid
|
|
77
|
+
|
|
78
|
+
def get
|
|
79
|
+
{:context_handle_attributes => context_handle_attributes, :context_handle_uuid => context_handle_uuid}
|
|
37
80
|
end
|
|
81
|
+
|
|
82
|
+
def set(handle)
|
|
83
|
+
if handle.is_a?(Hash)
|
|
84
|
+
self.context_handle_attributes = handle[:context_handle_attributes]
|
|
85
|
+
self.context_handle_uuid = handle[:context_handle_uuid]
|
|
86
|
+
elsif handle.is_a?(NdrContextHandle)
|
|
87
|
+
read(handle.to_binary_s)
|
|
88
|
+
else
|
|
89
|
+
read(handle.to_s)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# A pointer to a DWORD
|
|
95
|
+
class NdrLpDword < NdrTopLevelFullPointer
|
|
96
|
+
endian :little
|
|
97
|
+
|
|
98
|
+
uint32 :referent, onlyif: -> { !is_a_null_pointer? }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# An NDR Uni-dimensional Conformant-varying Arrays representation as defined in:
|
|
102
|
+
# [Transfer Syntax NDR - NDR Constructed Types](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_03_04)
|
|
103
|
+
class NdrLpByte < BinData::Record
|
|
104
|
+
endian :little
|
|
105
|
+
|
|
106
|
+
uint32 :referent_identifier, initial_value: 0x00020000
|
|
107
|
+
uint32 :max_count, initial_value: -> { actual_count }, onlyif: -> { referent_identifier != 0 }
|
|
108
|
+
uint32 :offset, initial_value: 0, onlyif: -> { referent_identifier != 0 }
|
|
109
|
+
uint32 :actual_count, initial_value: -> { bytes.size }, onlyif: -> { referent_identifier != 0 }
|
|
110
|
+
array :bytes, :type => :uint8, initial_length: -> { actual_count }, onlyif: -> { referent_identifier != 0 }
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# A pointer to a Windows FILETIME structure
|
|
114
|
+
class NdrLpFileTime < NdrTopLevelFullPointer
|
|
115
|
+
endian :little
|
|
116
|
+
|
|
117
|
+
file_time :referent, onlyif: -> { !is_a_null_pointer? }
|
|
38
118
|
end
|
|
39
119
|
end
|
|
40
120
|
end
|
|
41
|
-
|
|
42
121
|
end
|
|
@@ -21,7 +21,7 @@ module RubySMB
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
uint32 :packed_drep, label: 'NDR data representation format label', initial_value: 0x10
|
|
24
|
-
uint16 :frag_length, label: 'Total length of fragment', initial_value: -> { parent.
|
|
24
|
+
uint16 :frag_length, label: 'Total length of fragment', initial_value: -> { parent.num_bytes }
|
|
25
25
|
uint16 :auth_length, label: 'Length of auth_value'
|
|
26
26
|
uint32 :call_id, label: 'Call identifier', initial_value: 1
|
|
27
27
|
end
|
|
@@ -6,19 +6,38 @@ module RubySMB
|
|
|
6
6
|
endian :little
|
|
7
7
|
|
|
8
8
|
pdu_header :pdu_header, label: 'PDU header'
|
|
9
|
+
uint32 :alloc_hint, label: 'Allocation hint', initial_value: -> { stub.num_bytes }
|
|
10
|
+
uint16 :p_cont_id, label: 'Presentation context identification'
|
|
11
|
+
uint16 :opnum, label: 'Operation Number'
|
|
12
|
+
uuid :object, label: 'Object UID', onlyif: -> { pdu_header.pfc_flags.object_uuid == 1 }
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
choice :stub, label: 'Stub', selection: -> { @obj.parent.get_parameter(:endpoint) || '' } do
|
|
15
|
+
choice 'Winreg', selection: -> { opnum } do
|
|
16
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCR, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCR
|
|
17
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCU, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCU
|
|
18
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKLM, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKLM
|
|
19
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPD, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPD
|
|
20
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKU, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKU
|
|
21
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCC, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCC
|
|
22
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPT, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPT
|
|
23
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPN, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPN
|
|
24
|
+
close_key_request RubySMB::Dcerpc::Winreg::REG_CLOSE_KEY
|
|
25
|
+
enum_key_request RubySMB::Dcerpc::Winreg::REG_ENUM_KEY
|
|
26
|
+
enum_value_request RubySMB::Dcerpc::Winreg::REG_ENUM_VALUE
|
|
27
|
+
open_key_request RubySMB::Dcerpc::Winreg::REG_OPEN_KEY
|
|
28
|
+
query_info_key_request RubySMB::Dcerpc::Winreg::REG_QUERY_INFO_KEY
|
|
29
|
+
query_value_request RubySMB::Dcerpc::Winreg::REG_QUERY_VALUE
|
|
30
|
+
string :default
|
|
31
|
+
end
|
|
32
|
+
choice 'Srvsvc', selection: -> { opnum } do
|
|
33
|
+
net_share_enum_all RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL, host: -> { host rescue '' }
|
|
34
|
+
string :default
|
|
35
|
+
end
|
|
36
|
+
string :default
|
|
18
37
|
end
|
|
19
38
|
|
|
20
39
|
string :auth_verifier, label: 'Authentication verifier',
|
|
21
|
-
onlyif:
|
|
40
|
+
onlyif: -> { pdu_header.auth_length > 0 },
|
|
22
41
|
read_length: -> { pdu_header.auth_length }
|
|
23
42
|
|
|
24
43
|
def initialize_instance
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'ruby_smb/dcerpc/ndr'
|
|
2
|
+
|
|
3
|
+
module RubySMB
|
|
4
|
+
module Dcerpc
|
|
5
|
+
|
|
6
|
+
# A RRP_UNICODE_STRING structure as defined in
|
|
7
|
+
# [2.2.4 RRP_UNICODE_STRING](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/c0c90f11-a4c4-496a-ac09-8a8a3697ceef)
|
|
8
|
+
class RrpUnicodeString < BinData::Primitive
|
|
9
|
+
endian :little
|
|
10
|
+
|
|
11
|
+
uint16 :buffer_length, initial_value: -> { buffer.to_s == "\0" ? 0 : buffer.actual_count * 2 }
|
|
12
|
+
uint16 :maximum_length, initial_value: -> { buffer.to_s == "\0" ? 0 : buffer.max_count * 2 }
|
|
13
|
+
ndr_lp_str :buffer
|
|
14
|
+
|
|
15
|
+
def get
|
|
16
|
+
self.buffer
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def set(buf)
|
|
20
|
+
self.buffer = buf
|
|
21
|
+
self.buffer_length = self.buffer.to_s == "\0" ? 0 : self.buffer.actual_count * 2
|
|
22
|
+
self.maximum_length = self.buffer.to_s == "\0" ? 0 : self.buffer.max_count * 2
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# A pointer to a RRP_UNICODE_STRING structure
|
|
27
|
+
class PrrpUnicodeString < Ndr::NdrTopLevelFullPointer
|
|
28
|
+
endian :little
|
|
29
|
+
|
|
30
|
+
rrp_unicode_string :referent, onlyif: -> { !is_a_null_pointer? }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
@@ -5,6 +5,10 @@ module RubySMB
|
|
|
5
5
|
#https://msdn.microsoft.com/en-us/library/cc247293.aspx
|
|
6
6
|
|
|
7
7
|
class NetShareEnumAll < BinData::Record
|
|
8
|
+
attr_reader :opnum
|
|
9
|
+
|
|
10
|
+
mandatory_parameter :host
|
|
11
|
+
|
|
8
12
|
endian :little
|
|
9
13
|
|
|
10
14
|
uint32 :referent_id, initial_value: 0x00000001
|
|
@@ -27,6 +31,11 @@ module RubySMB
|
|
|
27
31
|
uint32 :resume_referent_id, initial_value: 0x00000001
|
|
28
32
|
uint32 :resume_handle, initial_value: 0
|
|
29
33
|
|
|
34
|
+
def initialize_instance
|
|
35
|
+
super
|
|
36
|
+
@opnum = NET_SHARE_ENUM_ALL
|
|
37
|
+
end
|
|
38
|
+
|
|
30
39
|
def pad_length
|
|
31
40
|
offset = (server_unc.abs_offset + server_unc.to_binary_s.length) % 4
|
|
32
41
|
(4 - offset) % 4
|
|
@@ -10,6 +10,16 @@ module RubySMB
|
|
|
10
10
|
NET_SHARE_ENUM_ALL = 0xF
|
|
11
11
|
|
|
12
12
|
require 'ruby_smb/dcerpc/srvsvc/net_share_enum_all'
|
|
13
|
+
|
|
14
|
+
def net_share_enum_all(host)
|
|
15
|
+
bind(endpoint: RubySMB::Dcerpc::Srvsvc)
|
|
16
|
+
|
|
17
|
+
net_share_enum_all_request_packet = RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.new(host: host)
|
|
18
|
+
response = dcerpc_request(net_share_enum_all_request_packet)
|
|
19
|
+
|
|
20
|
+
shares = RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.parse_response(response)
|
|
21
|
+
shares.map{|s|{name: s[0], type: s[1], comment: s[2]}}
|
|
22
|
+
end
|
|
13
23
|
end
|
|
14
24
|
end
|
|
15
25
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module Dcerpc
|
|
3
|
+
module Winreg
|
|
4
|
+
|
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
|
6
|
+
|
|
7
|
+
# This class represents a BaseRegCloseKey Request Packet as defined in
|
|
8
|
+
# [3.1.5.6 BaseRegCloseKey (Opnum 5)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/bc7545ff-0a54-4465-a95a-396b5c2995df)
|
|
9
|
+
class CloseKeyRequest < BinData::Record
|
|
10
|
+
attr_reader :opnum
|
|
11
|
+
|
|
12
|
+
endian :little
|
|
13
|
+
|
|
14
|
+
rpc_hkey :hkey
|
|
15
|
+
|
|
16
|
+
def initialize_instance
|
|
17
|
+
super
|
|
18
|
+
@opnum = REG_CLOSE_KEY
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module Dcerpc
|
|
3
|
+
module Winreg
|
|
4
|
+
|
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
|
6
|
+
|
|
7
|
+
# This class represents a BaseRegCloseKey Response Packet as defined in
|
|
8
|
+
# [3.1.5.6 BaseRegCloseKey (Opnum 5)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/bc7545ff-0a54-4465-a95a-396b5c2995df)
|
|
9
|
+
class CloseKeyResponse < BinData::Record
|
|
10
|
+
attr_reader :opnum
|
|
11
|
+
|
|
12
|
+
endian :little
|
|
13
|
+
|
|
14
|
+
rpc_hkey :hkey
|
|
15
|
+
uint32 :error_status
|
|
16
|
+
|
|
17
|
+
def initialize_instance
|
|
18
|
+
super
|
|
19
|
+
@opnum = REG_CLOSE_KEY
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module Dcerpc
|
|
3
|
+
module Winreg
|
|
4
|
+
|
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
|
6
|
+
|
|
7
|
+
# This class represents a BaseRegEnumKey Request Packet as defined in
|
|
8
|
+
# [3.1.5.10 BaseRegEnumKey (Opnum 9)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/668627e9-e0eb-4ab1-911f-0af589beeac3)
|
|
9
|
+
class EnumKeyRequest < BinData::Record
|
|
10
|
+
attr_reader :opnum
|
|
11
|
+
|
|
12
|
+
endian :little
|
|
13
|
+
|
|
14
|
+
rpc_hkey :hkey
|
|
15
|
+
uint32 :dw_index
|
|
16
|
+
rrp_unicode_string :lp_name
|
|
17
|
+
string :pad1, length: -> { pad_length1 }
|
|
18
|
+
prrp_unicode_string :lp_class
|
|
19
|
+
string :pad2, length: -> { pad_length2 }
|
|
20
|
+
ndr_lp_file_time :lpft_last_write_time
|
|
21
|
+
|
|
22
|
+
def initialize_instance
|
|
23
|
+
super
|
|
24
|
+
@opnum = REG_ENUM_KEY
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Determines the correct length for the padding in front of
|
|
28
|
+
# #lp_class. It should always force a 4-byte alignment.
|
|
29
|
+
def pad_length1
|
|
30
|
+
offset = (lp_name.abs_offset + lp_name.to_binary_s.length) % 4
|
|
31
|
+
(4 - offset) % 4
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Determines the correct length for the padding in front of
|
|
35
|
+
# #lpft_last_write_time. It should always force a 4-byte alignment.
|
|
36
|
+
def pad_length2
|
|
37
|
+
offset = (lp_class.abs_offset + lp_class.to_binary_s.length) % 4
|
|
38
|
+
(4 - offset) % 4
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module Dcerpc
|
|
3
|
+
module Winreg
|
|
4
|
+
|
|
5
|
+
# This class represents a BaseRegEnumKey Response Packet as defined in
|
|
6
|
+
# [3.1.5.10 BaseRegEnumKey (Opnum 9)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/668627e9-e0eb-4ab1-911f-0af589beeac3)
|
|
7
|
+
class EnumKeyResponse < BinData::Record
|
|
8
|
+
attr_reader :opnum
|
|
9
|
+
|
|
10
|
+
endian :little
|
|
11
|
+
|
|
12
|
+
rrp_unicode_string :lp_name
|
|
13
|
+
string :pad1, length: -> { pad_length1 }
|
|
14
|
+
prrp_unicode_string :lp_class, initial_value: 0
|
|
15
|
+
string :pad2, length: -> { pad_length2 }
|
|
16
|
+
ndr_lp_file_time :lpft_last_write_time
|
|
17
|
+
uint32 :error_status
|
|
18
|
+
|
|
19
|
+
def initialize_instance
|
|
20
|
+
super
|
|
21
|
+
@opnum = REG_ENUM_KEY
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Determines the correct length for the padding in front of
|
|
25
|
+
# #lp_class. It should always force a 4-byte alignment.
|
|
26
|
+
def pad_length1
|
|
27
|
+
offset = (lp_name.abs_offset + lp_name.to_binary_s.length) % 4
|
|
28
|
+
(4 - offset) % 4
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Determines the correct length for the padding in front of
|
|
32
|
+
# #lpft_last_write_time. It should always force a 4-byte alignment.
|
|
33
|
+
def pad_length2
|
|
34
|
+
offset = (lp_class.abs_offset + lp_class.to_binary_s.length) % 4
|
|
35
|
+
(4 - offset) % 4
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module Dcerpc
|
|
3
|
+
module Winreg
|
|
4
|
+
|
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
|
6
|
+
|
|
7
|
+
# This class represents a BaseRegEnumValue Request Packet as defined in
|
|
8
|
+
# [3.1.5.11 BaseRegEnumValue (Opnum 10)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/56e99ef3-05dc-4f24-bcf5-9cff00412945)
|
|
9
|
+
class EnumValueRequest < BinData::Record
|
|
10
|
+
attr_reader :opnum
|
|
11
|
+
|
|
12
|
+
endian :little
|
|
13
|
+
|
|
14
|
+
rpc_hkey :hkey
|
|
15
|
+
uint32 :dw_index
|
|
16
|
+
rrp_unicode_string :lp_value_name
|
|
17
|
+
string :pad, length: -> { pad_length }
|
|
18
|
+
ndr_lp_dword :lp_type
|
|
19
|
+
ndr_lp_byte :lp_data
|
|
20
|
+
ndr_lp_dword :lpcb_data
|
|
21
|
+
ndr_lp_dword :lpcb_len
|
|
22
|
+
|
|
23
|
+
def initialize_instance
|
|
24
|
+
super
|
|
25
|
+
@opnum = REG_ENUM_VALUE
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Determines the correct length for the padding in front of
|
|
29
|
+
# #lp_type. It should always force a 4-byte alignment.
|
|
30
|
+
def pad_length
|
|
31
|
+
offset = (lp_value_name.abs_offset + lp_value_name.to_binary_s.length) % 4
|
|
32
|
+
(4 - offset) % 4
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module Dcerpc
|
|
3
|
+
module Winreg
|
|
4
|
+
|
|
5
|
+
# This class represents a BaseRegEnumValue Response Packet as defined in
|
|
6
|
+
# [3.1.5.11 BaseRegEnumValue (Opnum 10)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/56e99ef3-05dc-4f24-bcf5-9cff00412945)
|
|
7
|
+
class EnumValueResponse < BinData::Record
|
|
8
|
+
attr_reader :opnum
|
|
9
|
+
|
|
10
|
+
endian :little
|
|
11
|
+
|
|
12
|
+
rrp_unicode_string :lp_value_name
|
|
13
|
+
string :pad, length: -> { pad_length }
|
|
14
|
+
ndr_lp_dword :lp_type
|
|
15
|
+
ndr_lp_byte :lp_data
|
|
16
|
+
ndr_lp_dword :lpcb_data
|
|
17
|
+
ndr_lp_dword :lpcb_len
|
|
18
|
+
uint32 :error_status
|
|
19
|
+
|
|
20
|
+
def initialize_instance
|
|
21
|
+
super
|
|
22
|
+
@opnum = REG_ENUM_VALUE
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Determines the correct length for the padding in front of
|
|
26
|
+
# #lp_type. It should always force a 4-byte alignment.
|
|
27
|
+
def pad_length
|
|
28
|
+
offset = (lp_value_name.abs_offset + lp_value_name.to_binary_s.length) % 4
|
|
29
|
+
(4 - offset) % 4
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|