From 02dd5ac604fb9c5a908cbfde4d4840e0a61908e2 Mon Sep 17 00:00:00 2001 From: sjanusz-r7 Date: Fri, 18 Oct 2024 13:05:51 +0100 Subject: [PATCH] Monkey-patch Readline to fix unresponsiveness on Windows 11 --- lib/msf/ui/console/driver.rb | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index bce665b24eb9..d11126eccdb6 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -724,6 +724,46 @@ def choose_readline(opts) begin require 'readline' + + # Only Windows requires a monkey-patched RbReadline + return unless Rex::Compat.is_windows + + if defined?(::RbReadline) + ::RbReadline.instance_eval do + class << self + alias_method :old_rl_move_cursor_relative, :_rl_move_cursor_relative + alias_method :old_rl_get_screen_size, :_rl_get_screen_size + alias_method :old_space_to_eol, :space_to_eol + alias_method :old_insert_some_chars, :insert_some_chars + end + + def self.refresh_console_handle + # hConsoleHandle gets set only when RbReadline detects it is running on Windows. + # Therefore, we don't need to check Rex::Compat.is_windows, we can simply check if hConsoleHandle is nil or not. + @hConsoleHandle = @GetStdHandle.Call(::Readline::STD_OUTPUT_HANDLE) if @hConsoleHandle + end + + def self._rl_move_cursor_relative(*args) + refresh_console_handle + old_rl_move_cursor_relative(*args) + end + + def self._rl_get_screen_size(*args) + refresh_console_handle + old_rl_get_screen_size(*args) + end + + def self.space_to_eol(*args) + refresh_console_handle + old_space_to_eol(*args) + end + + def self.insert_some_chars(*args) + refresh_console_handle + old_insert_some_chars(*args) + end + end + end rescue ::LoadError => e if @rl_err.nil? && index # Then this is the first time the require failed and we have an index