New module tree view

git-svn-id: file:///home/svn/framework3/trunk@5264 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2008-01-02 06:18:24 +00:00
parent 6c1e3b74b4
commit c888b12285
3 changed files with 325 additions and 259 deletions

View File

@ -1,296 +1,352 @@
module Msf
module Ui
module Gtk2
module Ui
module Gtk2
##
# This class describe the modules treeview
##
class MyModuleTree < MyGlade
##
# This class describe the modules treeview
##
class MyModuleTree < MyGlade
@@completion = []
@@completion = []
PIX, CATEGORY, MODULE, ADV, APP = *(0..5).to_a
PIX, NAME, MOD, DESC, TYPE = *(0..5).to_a
DIR, EXP, AUX, PAY, ENC, NOP = *(0..5).to_a
include Msf::Ui::Gtk2::MyControls
include Msf::Ui::Gtk2::MyControls
def initialize(treeview, viewmodule)
super('menu_module')
def initialize(treeview, viewmodule)
super('menu_module')
@treeview1 = treeview
@treeview1.enable_search = true
@treeview1 = treeview
@treeview1.enable_search = true
@model = Gtk::TreeStore.new( Gdk::Pixbuf, # pixbuf
String, # Module name
Object, # Exploit?
TrueClass, # ADV?
String # Appartenance
)
# Register the model for later use
$gtk2driver.module_model = @model
@model = Gtk::TreeStore.new(
Gdk::Pixbuf, # pixbuf
String, # Module name
Object, # Module object
String, # Description
Fixnum # Module type
)
# Register the model for later use
$gtk2driver.module_model = @model
# Init buffer module with tags
buff = SkeletonTextBuffer.new()
viewmodule.set_buffer(buff)
viewmodule.set_editable(false)
viewmodule.set_cursor_visible(false)
@buffer = MyModuleView.new(buff)
# Init buffer module with tags
buff = SkeletonTextBuffer.new()
viewmodule.set_buffer(buff)
viewmodule.set_editable(false)
viewmodule.set_cursor_visible(false)
@buffer = MyModuleView.new(buff)
# Renderer Module
renderer_pix = Gtk::CellRendererPixbuf.new
renderer_module = Gtk::CellRendererText.new
# Renderer Module
renderer_pix = Gtk::CellRendererPixbuf.new
renderer_module = Gtk::CellRendererText.new
column_module = Gtk::TreeViewColumn.new
column_module.pack_start(renderer_pix, false)
column_module.set_cell_data_func(renderer_pix) do |column, cell, model, iter|
cell.pixbuf = iter[PIX]
end
column_module.pack_start(renderer_module, true)
column_module.set_cell_data_func(renderer_module) do |column, cell, model, iter|
cell.text = iter[CATEGORY]
end
column_module = Gtk::TreeViewColumn.new
column_module.pack_start(renderer_pix, false)
column_module.set_cell_data_func(renderer_pix) do |column, cell, model, iter|
cell.pixbuf = iter[PIX]
end
column_module.pack_start(renderer_module, true)
column_module.set_cell_data_func(renderer_module) do |column, cell, model, iter|
cell.text = iter[NAME]
end
#set model to treeview
@treeview1.set_size_request(380, -1)
@treeview1.set_model(@model)
column_desc = Gtk::TreeViewColumn.new
column_desc.pack_start(renderer_module, true)
column_desc.set_cell_data_func(renderer_module) do |column, cell, model, iter|
cell.text = iter[DESC]
end
@treeview1.rules_hint = true
@selection = @treeview1.selection
@treeview1.selection.mode = Gtk::SELECTION_BROWSE
#set model to treeview
@treeview1.set_size_request(380, -1)
@treeview1.set_model(@model)
@treeview1.append_column(column_module)
@treeview1.rules_hint = true
# Signals
@treeview1.signal_connect('cursor-changed') do |widget, event|
widget.selection.selected_each do |model, path, iter|
active(iter)
end
end
@selection = @treeview1.selection
@treeview1.selection.mode = Gtk::SELECTION_BROWSE
@treeview1.signal_connect('button_press_event') do |treeview, event|
if event.kind_of? Gdk::EventButton
@treeview1.append_column(column_module)
@treeview1.append_column(column_desc)
# Signals
@treeview1.signal_connect('cursor-changed') do |widget, event|
widget.selection.selected_each do |model, path, iter|
active(iter)
end
end
# Right click
if (event.button == 3)
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
begin
iter = @treeview1.model.get_iter(path)
if (iter.get_value(ADV) == false)
treeview.selection.select_path(path)
active(iter)
@menu_module.popup(nil, nil, event.button, event.time)
end
rescue
nil
end
@treeview1.signal_connect('button_press_event') do |treeview, event|
if event.kind_of? Gdk::EventButton
# Double click
elsif (event.event_type == Gdk::Event::BUTTON2_PRESS)
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
begin
iter = @treeview1.model.get_iter(path)
if (iter.get_value(ADV) == false)
if (iter.get_value(APP) == "Standard")
treeview.selection.select_path(path)
active(iter)
MsfAssistant::Exploit.new(iter.get_value(MODULE))
elsif (iter.get_value(APP) == "Auxiliary")
treeview.selection.select_path(path)
active(iter)
MsfAssistant::Auxiliary.new(iter.get_value(MODULE))
#MsfDialog::Error.new($gtk2driver.main, "Not available")
else
treeview.selection.select_path(path)
active(iter)
MsfDialog::Error.new($gtk2driver.main, "Not available")
end
end
rescue
nil
end
end
end
end
# Right click
if (event.button == 3)
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
begin
iter = @treeview1.model.get_iter(path)
if(true)
treeview.selection.select_path(path)
active(iter)
@menu_module.popup(nil, nil, event.button, event.time)
end
rescue
nil
end
@one_shot.signal_connect('activate') do |item|
if active_module = @selection.selected
type = active_module.get_value(APP)
if (type == "Standard")
MsfAssistant::Exploit.new(active_module.get_value(MODULE))
elsif (type == "Auxiliary")
MsfAssistant::Auxiliary.new(active_module.get_value(MODULE))
#MsfDialog::Error.new($gtk2driver.main, "Not available")
else
MsfDialog::Error.new($gtk2driver.main, "Not available")
end
end
end
# Double click
elsif (event.event_type == Gdk::Event::BUTTON2_PRESS)
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
begin
iter = @treeview1.model.get_iter(path)
# Add modules in the Gtk::TreeView
add_modules()
if (iter.get_value(TYPE) == EXP)
treeview.selection.select_path(path)
active(iter)
MsfAssistant::Exploit.new(iter.get_value(MOD))
elsif (iter.get_value(TYPE) == AUX)
treeview.selection.select_path(path)
active(iter)
MsfAssistant::Auxiliary.new(iter.get_value(MOD))
elsif (iter.get_value(TYPE) == DIR)
# Ignore
else
treeview.selection.select_path(path)
active(iter)
MsfDialog::Error.new($gtk2driver.main, "Not available")
end
# Configure the module completion handles for easy reference
$gtk2driver.module_completion = @@completion
rescue
nil
end
end
end
end
end # def initialize
@one_shot.signal_connect('activate') do |item|
if active_module = @selection.selected
type = active_module.get_value(TYPE)
if (type == EXP)
MsfAssistant::Exploit.new(active_module.get_value(MOD))
elsif (type == AUX)
MsfAssistant::Auxiliary.new(active_module.get_value(MOD))
elsif (type == DIR)
# Ignore
else
MsfDialog::Error.new($gtk2driver.main, "Not available")
end
end
end
#
# Add Exploits module in the treeview
#
def add_modules(filter=/.*/)
# Add modules in the Gtk::TreeView
add_modules()
# Add Parent "Standard (nbr exploits)"
iter = @model.append(nil)
iter.set_value(PIX, driver.get_icon("bug.png"))
iter.set_value(CATEGORY, "Exploits (#{framework.stats.num_exploits.to_s})")
iter.set_value(MODULE, nil)
iter.set_value(ADV, true)
# Configure the module completion handles for easy reference
$gtk2driver.module_completion = @@completion
# Add Exploits childs
framework.exploits.each_module do |mod, obj|
next if not mod.match(filter)
t_module = obj.new.name
child_iter = @model.append(iter)
child_iter.set_value(CATEGORY, t_module)
child_iter.set_value(MODULE, obj.new)
child_iter.set_value(ADV, false)
child_iter.set_value(APP, "Standard")
@@completion.push(t_module)
end
end # def initialize
# Add Parent "Auxiliary (nbr auxiliary)"
iter = @model.append(nil)
iter.set_value(PIX, driver.get_icon("zoom.png"))
iter.set_value(CATEGORY, "Auxiliary (#{framework.stats.num_auxiliary.to_s})")
iter.set_value(MODULE, nil)
iter.set_value(ADV, true)
# Add Auxiliary childs
framework.auxiliary.each_module do |mod, obj|
next if not mod.match(filter)
t_module = obj.new.name
child_iter = @model.append(iter)
child_iter.set_value(CATEGORY, t_module)
child_iter.set_value(MODULE, obj.new)
child_iter.set_value(ADV, false)
child_iter.set_value(APP, "Auxiliary")
@@completion.push(t_module)
end
#
# Add modules to a treeview store specified by hash
#
def add_modules_to_store(store, parent, text, entry, attrs={})
iter = store.append(parent)
if (entry.class == ::Hash)
iter[PIX] = driver.get_icon(attrs[:top_icon] || attrs[:dir_icon])
iter[NAME] = text
iter[MOD] = nil
iter[TYPE] = DIR
iter[DESC] = attrs[:top_desc] || ""
attrs.delete(:top_icon)
attrs.delete(:top_desc)
entry.keys.sort.each do |x|
add_modules_to_store(store, iter, x, entry[x], attrs)
end
else
iter[PIX] = driver.get_icon(attrs[:mod_icon])
iter[NAME] = entry.refname.split("/")[-1]
iter[MOD] = entry
iter[DESC] = entry.name
iter[TYPE] = attrs[:type]
#
# TODO: To implement later ...
#
# # Add Parent "Payloads (nbr payloads)"
# iter = @model.append(nil)
# iter.set_value(PIX, driver.get_icon("bomb.png"))
# iter.set_value(CATEGORY, "Payloads (#{framework.stats.num_payloads.to_s})")
# iter.set_value(MODULE, nil)
# iter.set_value(ADV, true)
#
# # Add Payloads childs
# framework.payloads.each_module do |mod, obj|
# next if not mod.match(filter)
# t_module = obj.new.name
# child_iter = @model.append(iter)
# child_iter.set_value(CATEGORY, t_module)
# child_iter.set_value(MODULE, obj.new)
# child_iter.set_value(ADV, false)
# child_iter.set_value(APP, "Payloads")
# @@completion.push(t_module)
# end
#
# # Add Parent "Nops (nbr nops)"
# iter = @model.append(nil)
# iter.set_value(PIX, driver.get_icon("encoders.png"))
# iter.set_value(CATEGORY, "NOPs (#{framework.stats.num_nops.to_s})")
# iter.set_value(MODULE, nil)
# iter.set_value(ADV, true)
#
# # Add nops childs
# framework.nops.each_module do |mod, obj|
# next if not mod.match(filter)
# t_module = obj.new.name
# child_iter = @model.append(iter)
# child_iter.set_value(CATEGORY, t_module)
# child_iter.set_value(MODULE, obj.new)
# child_iter.set_value(ADV, false)
# child_iter.set_value(APP, "NOPs")
# @@completion.push(t_module)
# end
#
# # Add Parent "Encoders (nbr encoders)"
# iter = @model.append(nil)
# iter.set_value(PIX, driver.get_icon("encoders.png"))
# iter.set_value(CATEGORY, "Encoders (#{framework.stats.num_encoders.to_s})")
# iter.set_value(MODULE, nil)
# iter.set_value(ADV, true)
#
# # Add Encoders childs
# framework.encoders.each_module do |mod, obj|
# next if not mod.match(filter)
# t_module = obj.new.name
# child_iter = @model.append(iter)
# child_iter.set_value(CATEGORY, t_module)
# child_iter.set_value(MODULE, obj.new)
# child_iter.set_value(ADV, false)
# iter.set_value(APP, "Encoders")
# @@completion.push(t_module)
# end
end # def add_modules
@@completion.push(entry.name)
end
end
#
# Display the module information
#
def active(iter)
if not iter[MODULE].nil?
@buffer.insert_module(iter.get_value(MODULE))
end
end
#
# Add Exploits module in the treeview
#
def add_modules(filter=/.*/)
#
# Refresh the module treeview with all msf modules
#
def refresh
@model.clear()
add_modules()
end
#
# remove all iters in array_iter
#
def remove(iter_array)
mod_exploits = {}
framework.exploits.each_module do |mod, obj|
parts = mod.split("/")
name = parts.pop
ref = mod_exploits
parts.each do |part|
ref[part] ||= {}
ref = ref[part]
end
# first loop to remove unmatched iter
iter_array.each do |iter|
if (iter[ADV] == false)
@model.remove(iter)
end
end
ref[name] = obj.new
end
# second loop to update parent iter with child iter
no_child = []
@model.each do |model, path, iter|
if (iter[ADV] == true)
no_child.push(iter) if not iter.has_child?
iter[CATEGORY] = iter[CATEGORY].sub(/[0-9]+/, iter.n_children.to_s)
end
end
mod_auxiliary = {}
framework.auxiliary.each_module do |mod, obj|
parts = mod.split("/")
name = parts.pop
ref = mod_auxiliary
parts.each do |part|
ref[part] ||= {}
ref = ref[part]
end
# remove iter
no_child.each do |iter|
@model.remove(iter)
end
end
ref[name] = obj.new
end
add_modules_to_store(
@model, nil, "Exploits", mod_exploits,
{
:top_icon => "bug.png",
:top_desc => "All loaded exploit modules (#{framework.stats.num_exploits.to_s})",
:dir_icon => "msf_local_folder.png",
:mod_icon => "bug.png",
:type => EXP
}
)
#
# expand the treeview
#
def expand
@treeview1.expand_all
end
add_modules_to_store(
@model, nil, "Auxiliary", mod_auxiliary,
{
:top_icon => "zoom.png",
:top_desc => "All loaded auxiliary modules (#{framework.stats.num_exploits.to_s})",
:dir_icon => "msf_local_folder.png",
:mod_icon => "zoom.png",
:type => EXP
}
)
end
#
# TODO: To implement later ...
#
# # Add Parent "Payloads (nbr payloads)"
# iter = @model.append(nil)
# iter.set_value(PIX, driver.get_icon("bomb.png"))
# iter.set_value(NAME, "Payloads (#{framework.stats.num_payloads.to_s})")
# iter.set_value(MOD, nil)
# iter.set_value(ADV, true)
#
# # Add Payloads childs
# framework.payloads.each_module do |mod, obj|
# next if not mod.match(filter)
# t_module = obj.new.name
# child_iter = @model.append(iter)
# child_iter.set_value(NAME, t_module)
# child_iter.set_value(MOD, obj.new)
# child_iter.set_value(ADV, false)
# child_iter.set_value(APP, "Payloads")
# @@completion.push(t_module)
# end
#
# # Add Parent "Nops (nbr nops)"
# iter = @model.append(nil)
# iter.set_value(PIX, driver.get_icon("encoders.png"))
# iter.set_value(NAME, "NOPs (#{framework.stats.num_nops.to_s})")
# iter.set_value(MOD, nil)
# iter.set_value(ADV, true)
#
# # Add nops childs
# framework.nops.each_module do |mod, obj|
# next if not mod.match(filter)
# t_module = obj.new.name
# child_iter = @model.append(iter)
# child_iter.set_value(NAME, t_module)
# child_iter.set_value(MOD, obj.new)
# child_iter.set_value(ADV, false)
# child_iter.set_value(APP, "NOPs")
# @@completion.push(t_module)
# end
#
# # Add Parent "Encoders (nbr encoders)"
# iter = @model.append(nil)
# iter.set_value(PIX, driver.get_icon("encoders.png"))
# iter.set_value(NAME, "Encoders (#{framework.stats.num_encoders.to_s})")
# iter.set_value(MOD, nil)
# iter.set_value(ADV, true)
#
# # Add Encoders childs
# framework.encoders.each_module do |mod, obj|
# next if not mod.match(filter)
# t_module = obj.new.name
# child_iter = @model.append(iter)
# child_iter.set_value(NAME, t_module)
# child_iter.set_value(MOD, obj.new)
# child_iter.set_value(ADV, false)
# iter.set_value(APP, "Encoders")
# @@completion.push(t_module)
# end
end # def add_modules
#
# Display the module information
#
def active(iter)
if not iter[MOD].nil?
@buffer.insert_module(iter.get_value(MOD))
end
end
#
# Refresh the module treeview with all msf modules
#
def refresh
@model.clear()
add_modules()
end
#
# remove all iters in array_iter
#
def remove(iter_array)
# first loop to remove unmatched iter
iter_array.each do |iter|
next if iter[TYPE] == DIR
@model.remove(iter)
end
return
# second loop to update parent iter with child iter
no_child = []
@model.each do |model, path, iter|
no_child.push(iter) if not iter.has_child?
iter[NAME] = iter[NAME].sub(/[0-9]+/, iter.n_children.to_s)
end
# remove iter
no_child.each do |iter|
@model.remove(iter)
end
end
#
# expand the treeview
#
def expand
@treeview1.expand_all
end
end
end
end
end
end
end

View File

@ -16,7 +16,7 @@ module Gtk2
@buffer.delete(*@buffer.bounds)
start = @buffer.get_iter_at_offset(0)
@buffer.insert_with_tags(start, "Type: ", '_')
@buffer.insert_with_tags(start, obj.type + "\n", 'red_bold_cust')
@buffer.insert_with_tags(start, obj.class.to_s + "\n", 'red_bold_cust')
@buffer.insert_with_tags(start, "Author(s): ", "_")
@buffer.insert_with_tags(start, obj.author_to_s + "\n", 'forestgreen_bold_cust')
@buffer.insert_with_tags(start, "Path: ", "_")

View File

@ -57,8 +57,18 @@ module Msf
# Perform the search
found = []
filter = Regexp.new(text, Regexp::IGNORECASE)
i_type = Msf::Ui::Gtk2::MyModuleTree::TYPE
i_type_dir = Msf::Ui::Gtk2::MyModuleTree::DIR
i_desc = Msf::Ui::Gtk2::MyModuleTree::DESC
i_name = Msf::Ui::Gtk2::MyModuleTree::NAME
i_mod = Msf::Ui::Gtk2::MyModuleTree::MOD
$gtk2driver.module_model.each do |model, path, iter|
if (not iter[1][filter])
next if iter[i_type] == i_type_dir
if ( iter[i_desc] =~ filter or iter[i_name] =~ filter)
# Its a keeper
else
found.push(iter)
end
end