@@ -50,7 +50,10 @@ def net_server_enum(server_type=SV_TYPE_ALL, domain=nil)
50
50
51
51
case result [ 'return' ]
52
52
when 0
53
- hosts = read_server_structs ( result [ 'bufptr' ] , result [ 'totalentries' ] , domain , server_type )
53
+ # Railgun assumes PDWORDS are pointers and returns 8 bytes for x64 architectures.
54
+ # Therefore we need to truncate the result value to an actual
55
+ # DWORD for entriesread or totalentries.
56
+ hosts = read_server_structs ( result [ 'bufptr' ] , ( result [ 'entriesread' ] % 4294967296 ) , domain , server_type )
54
57
when ERROR_NO_BROWSER_SERVERS_FOUND
55
58
print_error ( "ERROR_NO_BROWSER_SERVERS_FOUND" )
56
59
return nil
@@ -65,26 +68,28 @@ def net_server_enum(server_type=SV_TYPE_ALL, domain=nil)
65
68
end
66
69
67
70
def read_server_structs ( start_ptr , count , domain , server_type )
68
- base = 0
69
- struct_size = 8
70
71
hosts = [ ]
72
+ return hosts if count <= 0
71
73
72
- if count == 0
73
- return hosts
74
- end
74
+ ptr_size = client . railgun . util . pointer_size
75
+ ptr = ( ptr_size == 8 ) ? 'Q<' : 'V'
76
+
77
+ base = 0
78
+ # Struct -> Ptr, Ptr
79
+ struct_size = ptr_size * 2
75
80
76
81
mem = client . railgun . memread ( start_ptr , struct_size *count )
77
82
78
83
count . times do
79
84
x = { }
80
- x [ :version ] = mem [ ( base + 0 ) , 4 ] . unpack ( "V*" ) [ 0 ]
81
- nameptr = mem [ ( base + 4 ) , 4 ] . unpack ( "V*" ) [ 0 ]
85
+ x [ :version ] = mem [ ( base + 0 ) , ptr_size ] . unpack ( ptr ) . first
86
+ nameptr = mem [ ( base + ptr_size ) , ptr_size ] . unpack ( ptr ) . first
82
87
x [ :name ] = UnicodeByteStringToAscii ( client . railgun . memread ( nameptr , 255 ) )
83
88
hosts << x
84
89
base += struct_size
85
90
end
86
91
87
- return hosts
92
+ hosts
88
93
end
89
94
90
95
def net_session_enum ( hostname , username )
@@ -105,7 +110,7 @@ def net_session_enum(hostname, username)
105
110
case result [ 'return' ]
106
111
when 0
107
112
vprint_error ( "#{ hostname } Session identified" )
108
- sessions = read_session_structs ( result [ 'bufptr' ] , result [ 'totalentries' ] , hostname )
113
+ sessions = read_session_structs ( result [ 'bufptr' ] , ( result [ 'entriesread' ] % 4294967296 ) , hostname )
109
114
when ERROR_ACCESS_DENIED
110
115
vprint_error ( "#{ hostname } Access denied..." )
111
116
return nil
@@ -130,25 +135,31 @@ def net_session_enum(hostname, username)
130
135
end
131
136
132
137
def read_session_structs ( start_ptr , count , hostname )
133
- base = 0
134
- struct_size = 16
135
138
sessions = [ ]
139
+ return sessions if count <= 0
140
+
141
+ ptr_size = client . railgun . util . pointer_size
142
+ ptr = ( ptr_size == 8 ) ? 'Q<' : 'V'
143
+
144
+ base = 0
145
+ # Struct -> Ptr, Ptr, Dword Dword
146
+ struct_size = ( ptr_size * 2 ) + 8
136
147
mem = client . railgun . memread ( start_ptr , struct_size *count )
137
-
148
+
138
149
count . times do
139
150
sess = { }
140
- cnameptr = mem [ ( base + 0 ) , 4 ] . unpack ( "V*" ) [ 0 ]
141
- usernameptr = mem [ ( base + 4 ) , 4 ] . unpack ( "V*" ) [ 0 ]
142
- sess [ :usetime ] = mem [ ( base + 8 ) , 4 ] . unpack ( "V*" ) [ 0 ]
143
- sess [ :idletime ] = mem [ ( base + 12 ) , 4 ] . unpack ( "V*" ) [ 0 ]
151
+ cnameptr = mem [ ( base + 0 ) , ptr_size ] . unpack ( ptr ) . first
152
+ usernameptr = mem [ ( base + ptr_size ) , ptr_size ] . unpack ( ptr ) . first
153
+ sess [ :usetime ] = mem [ ( base + ( ptr_size * 2 ) ) , 4 ] . unpack ( 'V' ) . first
154
+ sess [ :idletime ] = mem [ ( base + ( ptr_size * 2 ) + 4 ) , 4 ] . unpack ( 'V' ) . first
144
155
sess [ :cname ] = UnicodeByteStringToAscii ( client . railgun . memread ( cnameptr , 255 ) )
145
156
sess [ :username ] = UnicodeByteStringToAscii ( client . railgun . memread ( usernameptr , 255 ) )
146
157
sess [ :hostname ] = hostname
147
158
sessions << sess
148
159
base = base + struct_size
149
160
end
150
161
151
- return sessions
162
+ sessions
152
163
end
153
164
154
165
end # NetAPI
0 commit comments