Refactor and clean up reload_lib -a and others
parent
3ca95933a1
commit
ab56ac6655
|
@ -5,8 +5,9 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
@@irb_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-e" => [ true, "Expression to evaluate." ])
|
||||
'-h' => [false, 'Help menu.' ],
|
||||
'-e' => [true, 'Expression to evaluate.']
|
||||
)
|
||||
|
||||
def initialize(driver)
|
||||
super
|
||||
|
@ -18,11 +19,11 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
|
||||
def commands
|
||||
{
|
||||
'irb' => 'Drop into irb scripting mode',
|
||||
'pry' => 'Open a Pry session on the current module or Framework',
|
||||
'irb' => 'Open an interactive Ruby shell in the current context',
|
||||
'pry' => 'Open the Pry debugger on the current module or Framework',
|
||||
'edit' => 'Edit the current module or a file with the preferred editor',
|
||||
'reload_lib' => 'Reload one or more library files from specified paths',
|
||||
'log' => 'Displays framework.log starting at the bottom if possible'
|
||||
'reload_lib' => 'Reload Ruby library files from specified paths',
|
||||
'log' => 'Display framework.log paged to the end if possible'
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -35,45 +36,53 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
end
|
||||
|
||||
# XXX: This will try to reload *any* .rb and break on modules
|
||||
# If silent is true, errors will not be printed
|
||||
def reload_file(path, silent=false)
|
||||
unless File.exist?(path) && path.end_with?('.rb')
|
||||
print_error("#{path} must exist and be a .rb file") unless silent
|
||||
def reload_file(path, print_errors: true)
|
||||
full_path = File.expand_path(path)
|
||||
|
||||
unless File.exist?(full_path) && full_path.end_with?('.rb')
|
||||
print_error("#{full_path} must exist and be a .rb file") if print_errors
|
||||
return
|
||||
end
|
||||
|
||||
# The file must exist to reach this, so we try our best here
|
||||
if path =~ %r{^(?:\./)?modules/}
|
||||
print_error("Reloading Metasploit modules is not supported (try 'reload')") unless silent
|
||||
if full_path.start_with?(Msf::Config.module_directory, Msf::Config.user_module_directory)
|
||||
print_error('Reloading Metasploit modules is not supported (try "reload")') if print_errors
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Reloading #{path}")
|
||||
load path
|
||||
print_status("Reloading #{full_path}")
|
||||
load full_path
|
||||
end
|
||||
|
||||
# NOTE: At present, we include *.rb and exclude modules
|
||||
def reload_changed_files
|
||||
# Using an array avoids shelling out, so we avoid escaping/quoting
|
||||
changed_files = %w[git diff --name-only *.rb :!modules]
|
||||
|
||||
output, status = Open3.capture2e(*changed_files, chdir: Msf::Config.install_root)
|
||||
|
||||
unless status.success?
|
||||
print_error("Git is not available: #{output.chomp}")
|
||||
return
|
||||
end
|
||||
|
||||
def reload_diff_files
|
||||
output, status = Open3.capture2e(*%w(git diff --name-only *.rb :!modules), chdir: Msf::Config.install_root)
|
||||
if status.success?
|
||||
files = output.split("\n")
|
||||
|
||||
files.each do |file|
|
||||
f = File.join(Msf::Config.install_root, file)
|
||||
reload_file(f, true)
|
||||
end
|
||||
else
|
||||
print_error "Git is not available."
|
||||
reload_file(file, print_errors: false)
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_irb_help
|
||||
print_line "Usage: irb"
|
||||
print_line 'Usage: irb'
|
||||
print_line
|
||||
print_line "Execute commands in a Ruby environment"
|
||||
print_line 'Open an interactive Ruby shell in the current context.'
|
||||
print @@irb_opts.usage
|
||||
end
|
||||
|
||||
#
|
||||
# Goes into IRB scripting mode
|
||||
# Open an interactive Ruby shell in the current context
|
||||
#
|
||||
def cmd_irb(*args)
|
||||
expressions = []
|
||||
|
@ -90,10 +99,16 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
end
|
||||
|
||||
if expressions.empty?
|
||||
print_status("Starting IRB shell...\n")
|
||||
print_status('Starting IRB shell...')
|
||||
|
||||
begin
|
||||
Rex::Ui::Text::IrbShell.new(binding).run
|
||||
if active_module
|
||||
print_status("You are in #{active_module.fullname}\n")
|
||||
Rex::Ui::Text::IrbShell.new(active_module).run
|
||||
else
|
||||
print_status("You are in the \"framework\" object\n")
|
||||
Rex::Ui::Text::IrbShell.new(framework).run
|
||||
end
|
||||
rescue
|
||||
print_error("Error during IRB: #{$!}\n\n#{$@.join("\n")}")
|
||||
end
|
||||
|
@ -103,6 +118,11 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
driver.input.reset_tab_completion
|
||||
end
|
||||
else
|
||||
# XXX: No vprint_status here either
|
||||
if framework.datastore['VERBOSE'].to_s == 'true'
|
||||
print_status("You are executing expressions in #{binding.receiver}")
|
||||
end
|
||||
|
||||
expressions.each { |expression| eval(expression, binding) }
|
||||
end
|
||||
end
|
||||
|
@ -118,12 +138,12 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
def cmd_pry_help
|
||||
print_line 'Usage: pry'
|
||||
print_line
|
||||
print_line 'Open a Pry session on the current module or Framework.'
|
||||
print_line 'Open the Pry debugger on the current module or Framework.'
|
||||
print_line
|
||||
end
|
||||
|
||||
#
|
||||
# Open a Pry session on the current module or Framework
|
||||
# Open the Pry debugger on the current module or Framework
|
||||
#
|
||||
def cmd_pry(*args)
|
||||
if args.include?('-h')
|
||||
|
@ -155,7 +175,7 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
print_line
|
||||
print_line "Edit the currently active module or a local file with #{local_editor}."
|
||||
print_line 'If a library file is specified, it will automatically be reloaded after editing.'
|
||||
print_line "Otherwise, you can reload the active module with 'reload' or 'rerun'."
|
||||
print_line 'Otherwise, you can reload the active module with "reload" or "rerun".'
|
||||
print_line
|
||||
end
|
||||
|
||||
|
@ -206,32 +226,32 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
end
|
||||
|
||||
def cmd_reload_lib_help
|
||||
cmd_reload_lib '-h'
|
||||
cmd_reload_lib('-h')
|
||||
end
|
||||
|
||||
#
|
||||
# Reload one or more library files from specified paths
|
||||
# Reload Ruby library files from specified paths
|
||||
#
|
||||
def cmd_reload_lib(*args)
|
||||
opts = OptionParser.new do |opts|
|
||||
options = OptionParser.new do |opts|
|
||||
opts.banner = 'Usage: reload_lib lib/to/reload.rb [...]'
|
||||
opts.separator 'Reload specified Ruby library files.'
|
||||
opts.separator ''
|
||||
opts.separator 'Reload Ruby library files from specified paths.'
|
||||
opts.separator ''
|
||||
|
||||
opts.on '-h', '--help', 'Help banner.' do
|
||||
return print(opts.help)
|
||||
end
|
||||
|
||||
opts.on '-a', '--all', 'Reload all* changed files in your current git working tree.
|
||||
opts.on '-a', '--all', 'Reload all* changed files in your current Git working tree.
|
||||
*Excludes modules and non-Ruby files.' do
|
||||
reload_diff_files
|
||||
reload_changed_files
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
rest = opts.order(args)
|
||||
rest.each { |path| reload_file(path) }
|
||||
files = options.order(args)
|
||||
files.each { |file| reload_file(file) }
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -244,15 +264,15 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
def cmd_log_help
|
||||
print_line 'Usage: log'
|
||||
print_line
|
||||
print_line 'Displays framework.log starting at the bottom if possible.'
|
||||
print_line "For full effect, 'setg LogLevel 3' before running modules."
|
||||
print_line 'Display framework.log paged to the end if possible.'
|
||||
print_line 'For full effect, "setg LogLevel 3" before running modules.'
|
||||
print_line
|
||||
print_line "Log location: #{File.join(Msf::Config.log_directory, 'framework.log')}"
|
||||
print_line
|
||||
end
|
||||
|
||||
#
|
||||
# Displays framework.log starting at the bottom if possible
|
||||
# Display framework.log paged to the end if possible
|
||||
#
|
||||
def cmd_log(*args)
|
||||
path = File.join(Msf::Config.log_directory, 'framework.log')
|
||||
|
|
|
@ -34,12 +34,14 @@ class Console::CommandDispatcher::Core
|
|||
end
|
||||
|
||||
@@irb_opts = Rex::Parser::Arguments.new(
|
||||
'-h' => [false, 'Help banner.'],
|
||||
'-e' => [true, 'Expression to evaluate.'])
|
||||
'-h' => [false, 'Help menu.' ],
|
||||
'-e' => [true, 'Expression to evaluate.']
|
||||
)
|
||||
|
||||
@@load_opts = Rex::Parser::Arguments.new(
|
||||
'-l' => [false, 'List all available extensions'],
|
||||
'-h' => [false, 'Help menu.'])
|
||||
'-h' => [false, 'Help menu.' ],
|
||||
'-l' => [false, 'List all available extensions.']
|
||||
)
|
||||
|
||||
#
|
||||
# List of supported commands.
|
||||
|
@ -52,8 +54,8 @@ class Console::CommandDispatcher::Core
|
|||
'channel' => 'Displays information or control active channels',
|
||||
'exit' => 'Terminate the meterpreter session',
|
||||
'help' => 'Help menu',
|
||||
'irb' => 'Drop into irb scripting mode',
|
||||
'pry' => 'Open a Pry session on the current session',
|
||||
'irb' => 'Open an interactive Ruby shell on the current session',
|
||||
'pry' => 'Open the Pry debugger on the current session',
|
||||
'use' => 'Deprecated alias for "load"',
|
||||
'load' => 'Load one or more meterpreter extensions',
|
||||
'machine_id' => 'Get the MSF ID of the machine attached to the session',
|
||||
|
@ -532,7 +534,7 @@ class Console::CommandDispatcher::Core
|
|||
def cmd_irb_help
|
||||
print_line('Usage: irb')
|
||||
print_line
|
||||
print_line('Execute commands in a Ruby environment')
|
||||
print_line('Open an interactive Ruby shell on the current session.')
|
||||
print @@irb_opts.usage
|
||||
end
|
||||
|
||||
|
@ -542,7 +544,7 @@ class Console::CommandDispatcher::Core
|
|||
end
|
||||
|
||||
#
|
||||
# Runs the IRB scripting shell
|
||||
# Open an interactive Ruby shell on the current session
|
||||
#
|
||||
def cmd_irb(*args)
|
||||
expressions = []
|
||||
|
@ -561,12 +563,16 @@ class Console::CommandDispatcher::Core
|
|||
framework = client.framework
|
||||
|
||||
if expressions.empty?
|
||||
print_status('Starting IRB shell')
|
||||
print_status('The "client" variable holds the meterpreter client')
|
||||
print_line
|
||||
print_status('Starting IRB shell...')
|
||||
print_status("You are in the \"client\" (session) object\n")
|
||||
|
||||
Rex::Ui::Text::IrbShell.new(binding).run
|
||||
Rex::Ui::Text::IrbShell.new(client).run
|
||||
else
|
||||
# XXX: No vprint_status here
|
||||
if framework.datastore['VERBOSE'].to_s == 'true'
|
||||
print_status("You are executing expressions in #{binding.receiver}")
|
||||
end
|
||||
|
||||
expressions.each { |expression| eval(expression, binding) }
|
||||
end
|
||||
end
|
||||
|
@ -574,12 +580,12 @@ class Console::CommandDispatcher::Core
|
|||
def cmd_pry_help
|
||||
print_line 'Usage: pry'
|
||||
print_line
|
||||
print_line 'Open a Pry session on the current session.'
|
||||
print_line 'Open the Pry debugger on the current session.'
|
||||
print_line
|
||||
end
|
||||
|
||||
#
|
||||
# Open a Pry session on the current session
|
||||
# Open the Pry debugger on the current session
|
||||
#
|
||||
def cmd_pry(*args)
|
||||
if args.include?('-h')
|
||||
|
|
Loading…
Reference in New Issue