Skip to content

Commit 0da9f4d

Browse files
committed
Refactor railgun "DLL" references to library
1 parent ea83cb0 commit 0da9f4d

File tree

4 files changed

+75
-71
lines changed

4 files changed

+75
-71
lines changed

lib/msf/core/post/windows/railgun.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ module Windows
77
module Railgun
88

99
# Go through each dll and add a corresponding convenience method of the same name
10-
Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun::BUILTIN_DLLS['windows'].each do |api|
10+
Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun::BUILTIN_LIBRARIES['windows'].each do |api|
1111
# We will be interpolating within an eval. We exercise due paranoia.
1212
unless api.to_s =~ /^\w+$/
13-
print_error 'Something is seriously wrong with Railgun.BUILTIN_DLLS list'
13+
print_error 'Something is seriously wrong with Railgun.BUILTIN_LIBRARIES list'
1414
next
1515
end
1616

lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb

Lines changed: 70 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class Railgun
6969
# class name: Def_my_dll
7070
# entry below: 'my_dll'
7171
#
72-
BUILTIN_DLLS = {
72+
BUILTIN_LIBRARIES = {
7373
'linux' => [
7474
'libc'
7575
].freeze,
@@ -95,33 +95,34 @@ class Railgun
9595
}.freeze
9696

9797
##
98-
# Returns a Hash containing DLLs added to this instance with #add_dll
99-
# as well as references to any frozen cached dlls added directly in #get_dll
100-
# and copies of any frozen dlls (added directly with #add_function)
101-
# that the user attempted to modify with #add_function.
98+
# Returns a Hash containing DLLs added to this instance with #add_library as
99+
# well as references to any frozen cached libraries added directly in
100+
# #get_library and copies of any frozen libraries (added directly with
101+
# #add_function) that the user attempted to modify with #add_function.
102102
#
103-
# Keys are friendly DLL names and values are the corresponding DLL instance
104-
attr_accessor :dlls
103+
# Keys are friendly library names and values are the corresponding library instance
104+
attr_accessor :libraries
105105

106106
##
107107
# Contains a reference to the client that corresponds to this instance of railgun
108108
attr_accessor :client
109109

110110
##
111-
# These DLLs are loaded lazily and then shared amongst all railgun instances.
112-
# For safety reasons this variable should only be read/written within #get_dll.
113-
@@cached_dlls = {}
111+
# These libraries are loaded lazily and then shared amongst all railgun
112+
# instances. For safety reasons this variable should only be read/written
113+
# within #get_library.
114+
@@cached_libraries = {}
114115

115-
# if you are going to touch @@cached_dlls, wear protection
116+
# if you are going to touch @@cached_libraries, wear protection
116117
@@cache_semaphore = Mutex.new
117118

118119
def initialize(client)
119120
self.client = client
120-
self.dlls = {}
121+
self.libraries = {}
121122
end
122123

123-
def self.builtin_dlls
124-
BUILTIN_DLLS[client.platform]
124+
def self.builtin_libraries
125+
BUILTIN_LIBRARIES[client.platform]
125126
end
126127

127128
#
@@ -196,106 +197,109 @@ def memwrite(address, data, length=nil)
196197
end
197198

198199
#
199-
# Adds a function to an existing DLL definition.
200+
# Adds a function to an existing library definition.
200201
#
201-
# If the DLL definition is frozen (ideally this should be the case for all
202-
# cached dlls) an unfrozen copy is created and used henceforth for this
202+
# If the library definition is frozen (ideally this should be the case for all
203+
# cached libraries) an unfrozen copy is created and used henceforth for this
203204
# instance.
204205
#
205-
def add_function(dll_name, function_name, return_type, params, remote_name=nil, calling_conv="stdcall")
206-
207-
unless known_dll_names.include?(dll_name)
208-
raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, "")}"
206+
def add_function(lib_name, function_name, return_type, params, remote_name=nil, calling_conv='stdcall')
207+
unless known_library_names.include?(lib_name)
208+
raise "Library #{lib_name} not found. Known libraries: #{PP.pp(known_library_names, '')}"
209209
end
210210

211-
dll = get_dll(dll_name)
211+
lib = get_library(lib_name)
212212

213-
# For backwards compatibility, we ensure the dll is thawed
214-
if dll.frozen?
215-
# Duplicate not only the dll, but its functions as well. Frozen status will be lost
216-
dll = Marshal.load(Marshal.dump(dll))
213+
# For backwards compatibility, we ensure the library is thawed
214+
if lib.frozen?
215+
# Duplicate not only the library, but its functions as well, frozen status will be lost
216+
lib = Marshal.load(Marshal.dump(lib))
217217

218-
# Update local dlls with the modifiable duplicate
219-
dlls[dll_name] = dll
218+
# Update local libraries with the modifiable duplicate
219+
libraries[lib_name] = lib
220220
end
221221

222-
dll.add_function(function_name, return_type, params, remote_name, calling_conv)
222+
lib.add_function(function_name, return_type, params, remote_name, calling_conv)
223223
end
224224

225225
#
226-
# Adds a DLL to this Railgun.
226+
# Adds a library to this Railgun.
227227
#
228228
# The +remote_name+ is the name used on the remote system and should be
229-
# set appropriately if you want to include a path or the DLL name contains
229+
# set appropriately if you want to include a path or the library name contains
230230
# non-ruby-approved characters.
231231
#
232-
# Raises an exception if a dll with the given name has already been
232+
# Raises an exception if a library with the given name has already been
233233
# defined.
234234
#
235-
def add_dll(dll_name, remote_name=dll_name)
236-
237-
if dlls.has_key? dll_name
238-
raise "A DLL of name #{dll_name} has already been loaded."
235+
def add_library(lib_name, remote_name=lib_name)
236+
if libraries.has_key? lib_name
237+
raise "A library of name #{lib_name} has already been loaded."
239238
end
240239

241-
dlls[dll_name] = DLL.new(remote_name, constant_manager)
240+
libraries[lib_name] = DLL.new(remote_name, constant_manager)
242241
end
242+
alias_method :add_dll, :add_library
243243

244-
245-
def known_dll_names
246-
return BUILTIN_DLLS[client.platform] | dlls.keys
244+
def known_library_names
245+
return BUILTIN_LIBRARIES[client.platform] | libraries.keys
247246
end
248247

249248
#
250-
# Attempts to provide a DLL instance of the given name. Handles lazy
251-
# loading and caching. Note that if a DLL of the given name does not
252-
# exist, returns nil
249+
# Attempts to provide a library instance of the given name. Handles lazy
250+
# loading and caching. Note that if a library of the given name does not exist
251+
# then nil is returned.
253252
#
254-
def get_dll(dll_name)
255-
# If the DLL is not local, we now either load it from cache or load it lazily.
256-
# In either case, a reference to the dll is stored in the collection "dlls"
257-
# If the DLL can not be found/created, no actions are taken
258-
unless dlls.has_key? dll_name
259-
# We read and write to @@cached_dlls and rely on state consistency
253+
def get_library(lib_name)
254+
# If the library is not local, we now either load it from cache or load it
255+
# lazily. In either case, a reference to the library is stored in the
256+
# collection "libraries". If the library can not be found/created, no
257+
# actions are taken.
258+
unless libraries.has_key? lib_name
259+
# use a platform-specific name for caching to avoid conflicts with
260+
# libraries that exist on multiple platforms, e.g. libc.
261+
cached_lib_name = "#{client.platform}.#{lib_name}"
262+
# We read and write to @@cached_libraries and rely on state consistency
260263
@@cache_semaphore.synchronize do
261-
if @@cached_dlls.has_key? dll_name
262-
dlls[dll_name] = @@cached_dlls[dll_name]
263-
elsif BUILTIN_DLLS[client.platform].include? dll_name
264+
if @@cached_libraries.has_key? cached_lib_name
265+
libraries[lib_name] = @@cached_libraries[cached_lib_name]
266+
elsif BUILTIN_LIBRARIES[client.platform].include? lib_name
264267
# I highly doubt this case will ever occur, but I am paranoid
265-
if dll_name !~ /^\w+$/
266-
raise "DLL name #{dll_name} is bad. Correct Railgun::BUILTIN_DLLS"
268+
if lib_name !~ /^\w+$/
269+
raise "Library name #{lib_name} is bad. Correct Railgun::BUILTIN_LIBRARIES['#{client.platform}']"
267270
end
268271

269-
require "rex/post/meterpreter/extensions/stdapi/railgun/def/#{client.platform}/def_#{dll_name}"
270-
dll = Def.const_get("Def_#{client.platform}_#{dll_name}").create_dll(constant_manager).freeze
272+
require "rex/post/meterpreter/extensions/stdapi/railgun/def/#{client.platform}/def_#{lib_name}"
273+
lib = Def.const_get("Def_#{client.platform}_#{lib_name}").create_dll(constant_manager).freeze
271274

272-
@@cached_dlls[dll_name] = dll
273-
dlls[dll_name] = dll
275+
@@cached_libraries[cached_lib_name] = lib
276+
libraries[lib_name] = lib
274277
end
275278
end
276279

277280
end
278281

279-
return dlls[dll_name]
282+
return libraries[lib_name]
280283
end
284+
alias_method :get_dll, :get_library
281285

282286
#
283287
# Fake having members like user32 and kernel32.
284288
# reason is that
285289
# ...user32.MessageBoxW()
286290
# is prettier than
287-
# ...dlls["user32"].functions["MessageBoxW"]()
291+
# ...libraries["user32"].functions["MessageBoxW"]()
288292
#
289-
def method_missing(dll_symbol, *args)
290-
dll_name = dll_symbol.to_s
293+
def method_missing(lib_symbol, *args)
294+
lib_name = lib_symbol.to_s
291295

292-
unless known_dll_names.include? dll_name
293-
raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, '')}"
296+
unless known_library_names.include? lib_name
297+
raise "Library #{lib_name} not found. Known libraries: #{PP.pp(known_library_names, '')}"
294298
end
295299

296-
dll = get_dll(dll_name)
300+
lib = get_library(lib_name)
297301

298-
return DLLWrapper.new(dll, client)
302+
return DLLWrapper.new(lib, client)
299303
end
300304

301305
#

modules/post/linux/gather/gnome_keyring_dump.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ def struct_gnomekeyringnetworkpassworddata
7474
end
7575

7676
def init_railgun_defs
77-
unless session.railgun.dlls.has_key?('libgnome_keyring')
78-
session.railgun.add_dll('libgnome_keyring', 'libgnome-keyring.so.0')
77+
unless session.railgun.libraries.has_key?('libgnome_keyring')
78+
session.railgun.add_library('libgnome_keyring', 'libgnome-keyring.so.0')
7979
end
8080
session.railgun.add_function(
8181
'libgnome_keyring',

modules/post/windows/manage/download_exec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def initialize(info={})
4242

4343
def add_railgun_urlmon
4444

45-
if client.railgun.dlls.find_all {|d| d.first == 'urlmon'}.empty?
45+
if client.railgun.libraries.find_all {|d| d.first == 'urlmon'}.empty?
4646
session.railgun.add_dll('urlmon','urlmon')
4747
session.railgun.add_function(
4848
'urlmon', 'URLDownloadToFileW', 'DWORD',

0 commit comments

Comments
 (0)