Various hacks for win32 mode

git-svn-id: file:///home/svn/framework3/trunk@3756 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
HD Moore 2006-07-27 00:59:00 +00:00
parent 5b319613ab
commit db8c76f679
4 changed files with 153 additions and 1 deletions

View File

@ -48,8 +48,13 @@ class Driver < Msf::Ui::Driver
#
def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {})
# The command prompt doesn't like bling bling'in colors.
# Windows-specific hackery
if (RUBY_PLATFORM =~ /win/)
# Start the readline console hack
Rex::Compat.win32_readline_daemon()
# Disable the color support
prompt = "msf"
prompt_char = ">"
end

View File

@ -47,6 +47,10 @@ require 'rex/proto'
require 'rex/parser/arguments'
require 'rex/parser/ini'
# Compatibility
require 'rex/compat'
# Overload the Kernel.sleep() function to be thread-safe
Kernel.class_eval("
def sleep(seconds)

112
lib/rex/compat.rb Normal file
View File

@ -0,0 +1,112 @@
require 'dl'
module Rex
###
#
# This class provides os-specific functionality
#
###
module Compat
STD_INPUT_HANDLE = -10
ENABLE_LINE_INPUT = 2
ENABLE_ECHO_INPUT = 4
ENABLE_PROCESSED_INPUT = 1
def self.win32_stdin_unblock
begin
@@k32 ||= DL.dlopen("kernel32.dll")
gsh = @@k32['GetStdHandle', 'LL']
gcm = @@k32['GetConsoleMode', 'LLP']
scm = @@k32['SetConsoleMode', 'LLL']
inp = gsh.call(STD_INPUT_HANDLE)[0]
inf = DL.malloc(DL.sizeof('L'))
gcm.call(inp, inf)
old_mode = inf.to_a('L', 1)[0]
new_mode = old_mode & ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT)
scm.call(inp, new_mode)
rescue ::Exception
raise $!
end
end
def self.win32_stdin_block
begin
@@k32 ||= DL.dlopen("kernel32.dll")
gsh = @@k32['GetStdHandle', 'LL']
gcm = @@k32['GetConsoleMode', 'LLP']
scm = @@k32['SetConsoleMode', 'LLL']
inp = gsh.call(STD_INPUT_HANDLE)[0]
inf = DL.malloc(DL.sizeof('L'))
gcm.call(inp, inf)
old_mode = inf.to_a('L', 1)[0]
new_mode = old_mode | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT
scm.call(inp, new_mode)
rescue ::Exception
raise $!
end
end
def self.win32_ruby_path
begin
@@k32 ||= DL.dlopen("kernel32.dll")
gmh = @@k32['GetModuleHandle', 'LP']
gmf = @@k32['GetModuleFileName', 'LLPL']
mod = gmh.call(nil)[0]
inf = DL.malloc(1024)
gmf.call(mod, inf, 1024)
return inf.to_s
rescue ::Exception
raise $!
end
end
def self.win32_winexec(cmd)
begin
@@k32 ||= DL.dlopen("kernel32.dll")
win = @@k32['WinExec', 'LPL']
win.call(cmd.to_ptr, 0)
rescue ::Exception
raise $!
end
end
def self.win32_readline_daemon
serv = nil
port = 1024
while (! serv and port < 65535)
begin
serv = TCPServer.new('127.0.0.1', (port += 1))
rescue ::Exception
end
end
path = win32_ruby_path()
rubyw = File.join(File.dirname(path.to_s), "ruby.exe")
helpr = File.join(File.dirname(__FILE__), 'win32_stdio.rb')
win32_winexec( [rubyw, helpr, port.to_s].join(" ") )
# Accept the forked child
clnt = serv.accept
# Shutdown the server
serv.close
# Replace stdin with the socket
$stdin.close
$stdin = clnt
end
end
end

31
lib/rex/win32_stdio.rb Normal file
View File

@ -0,0 +1,31 @@
#!/usr/bin/env ruby
require 'dl'
require 'socket'
$:.push(File.dirname(__FILE__))
require 'compat'
port = ARGV.shift() || exit(0)
# This script is used to provide async stdio on Windows
begin
sock = TCPSocket.new('127.0.0.1', port)
Rex::Compat.win32_stdin_unblock()
$stderr.puts "Starting stdio daemon..."
while (true)
c = $stdin.sysread(1)
$stderr.printf("%.2x \n", c[0])
sock.write(c)
sock.flush
end
rescue ::Exception
$stderr.puts "Exception: #{$!.to_s}"
end
Rex::Compat.win32_stdin_block()