Remove columns from column selector in certain listviews where those columns cause sort crashes. Add a right-click context menu option to view procedures from both the RPCALPC server list and the library server list. RPCI also now uses our own private build of ObjectListView control, as a nuget package.

This commit is contained in:
Aaron LeMasters 2023-01-18 17:48:21 -05:00
parent 4aea94cd86
commit 03abf7480e
7 changed files with 217 additions and 58 deletions

View File

@ -101,8 +101,8 @@
<Reference Include="NtApiDotNet.Forms, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\NtApiDotNet.Forms.1.1.33\lib\net461\NtApiDotNet.Forms.dll</HintPath>
</Reference>
<Reference Include="ObjectListView, Version=2.9.1.25410, Culture=neutral, PublicKeyToken=b1c5bf581481bcd4, processorArchitecture=MSIL">
<HintPath>packages\ObjectListView.Official.2.9.2-alpha2\lib\net20\ObjectListView.dll</HintPath>
<Reference Include="ObjectListView, Version=2.9.1.25354, Culture=neutral, PublicKeyToken=b1c5bf581481bcd4, processorArchitecture=MSIL">
<HintPath>packages\ObjectListView-ToB.2.9.4\lib\net20\ObjectListView.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />

View File

@ -15,13 +15,6 @@ using BrightIdeasSoftware;
using System.Drawing;
using System.Diagnostics;
using RpcInvestigator.TabPages;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using Newtonsoft.Json.Linq;
using RpcInvestigator.Util;
using System.ServiceModel.Channels;
using System.Text;
using RpcInvestigator.Windows;
namespace RpcInvestigator
{
@ -55,25 +48,35 @@ namespace RpcInvestigator
m_Listview.View = View.Details;
m_Listview.VirtualMode = true;
m_Listview.ShowGroups = false;
m_Listview.UseFiltering = true;
m_Listview.Alignment = ListViewAlignment.Left;
Generator.GenerateColumns(m_Listview, typeof(RpcAlpcServer), true);
foreach (var column in m_Listview.AllColumns)
{
if (column.Name.ToLower() == "endpoints")
if (column.Name.ToLower() == "endpoints" ||
column.Name.ToLower() == "securitydescriptor")
{
column.IsVisible = false;
}
if (column.Name.ToLower() == "securitydescriptor")
{
column.AspectGetter = delegate (object Row)
{
if (Row == null)
{
return "";
}
var server = Row as RpcAlpcServer;
if (server.SecurityDescriptor == null)
{
return "";
}
return server.SecurityDescriptor.ToString();
};
}
column.MaximumWidth = -1;
}
m_Listview.AllColumns.ForEach(col =>
{
if (col.Name == "SecurityDescriptor")
{
col.IsVisible = false;
}
});
//
// When a listview row is double-clicked, a new tab will open with endpoints
// for the selected RPC server. Right-click shows context menu.
@ -90,9 +93,36 @@ namespace RpcInvestigator
selectedRow.Name, selectedRow.Endpoints.ToList(), selectedRow.Name);
});
m_Listview.CellRightClick += RightClickHandler;
m_Listview.ColumnRightClick += ColumnRightClickOverride;
Controls.Add(m_Listview);
}
private void ColumnRightClickOverride(object sender, ColumnClickEventArgs e)
{
//
// Some of the columns we hide by default should never be shown,
// either because they contain binary data or lists of binary data.
// Such information is not easy to disable in the listview, so we'll
// strip those columns from the column selector context menu.
//
var args = (ColumnRightClickEventArgs)e;
var list = new List<ToolStripItem>();
foreach (var item in args.MenuStrip.Items)
{
if (item.GetType() == typeof(ToolStripMenuItem))
{
var toolstripItem = item as ToolStripMenuItem;
if (toolstripItem.Text.ToLower() == "endpoints")
{
continue;
}
}
list.Add((ToolStripItem)item);
}
args.MenuStrip.Items.Clear();
args.MenuStrip.Items.AddRange(list.ToArray());
}
public int GetCount()
{
if (m_Listview.Objects == null)
@ -200,9 +230,24 @@ namespace RpcInvestigator
TabPages.ContextMenu.BuildRightClickMenu(Args, new List<ToolStripMenuItem>{
new ToolStripMenuItem("Open in Library", null, ContextMenuOpenAlpcServerInLibrary),
new ToolStripMenuItem("View Security Descriptor", null, TabPages.ContextMenu.ContextMenuViewSecurityDescriptor),
new ToolStripMenuItem("View Procedures", null, ContextMenuViewProcedures),
});
}
private void ContextMenuViewProcedures(object Sender, EventArgs Args)
{
object tag = ((ToolStripMenuItem)Sender).Tag;
if (tag == null)
{
return;
}
var args = (CellRightClickEventArgs)tag;
var server = args.Model as RpcAlpcServer;
_ = m_TabManager.LoadRpcLibraryProceduresTab(new RpcLibraryFilter{
FilterType = RpcLibraryFilterType.FilterByKeyword,
Keyword = server.Name });
}
private
async
void

View File

@ -12,7 +12,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using NtApiDotNet;
using NtApiDotNet.Win32;
using System.Diagnostics;
using System.Linq;
@ -65,45 +65,77 @@ namespace RpcInvestigator
ToolStripStatusLabel ProgressLabel
)
{
Text = "Procedures";
Name = "Procedures";
var tabName = "Procedures";
if (Filter.FilterType != RpcLibraryFilterType.NoFilter)
{
tabName += " for '" + Filter.Keyword + "'";
}
Text = tabName;
Name = tabName;
ImageIndex = 3;
try
{
using (NtToken token = NtProcess.Current.OpenToken())
var searchResults = new List<RpcLibraryProcedure>();
ProgressBar.Step = 1;
ProgressBar.Value = 0;
ProgressBar.Visible = true;
await Task.Run(() =>
{
var searchResults = new List<RpcLibraryProcedure>();
ProgressBar.Step = 1;
ProgressBar.Value = 0;
ProgressBar.Visible = true;
await Task.Run(() =>
var results = m_Library.Find(Filter);
foreach (var server in results)
{
var results = m_Library.Find(Filter);
foreach (var server in results)
foreach (var procedure in server.Procedures)
{
foreach (var procedure in server.Procedures)
var formatter = DefaultNdrFormatter.Create(DefaultNdrFormatterFlags.RemoveComments);
string friendly = formatter.FormatProcedure(procedure);
searchResults.Add(new RpcLibraryProcedure()
{
var formatter = DefaultNdrFormatter.Create(DefaultNdrFormatterFlags.RemoveComments);
string friendly = formatter.FormatProcedure(procedure);
searchResults.Add(new RpcLibraryProcedure()
{
FilePath = server.FilePath,
InterfaceId = server.InterfaceId,
InterfaceVersion = server.InterfaceVersion,
Name = friendly,
});
};
}
});
if (searchResults.Count > 0)
{
m_Listview.SetObjects(searchResults);
m_Listview.AutoResizeColumns();
m_Listview.RebuildColumns();
FilePath = server.FilePath,
InterfaceId = server.InterfaceId,
InterfaceVersion = server.InterfaceVersion,
Name = friendly,
});
};
}
ProgressBar.Value = 0;
ProgressBar.Visible = false;
});
if (searchResults.Count > 0)
{
m_Listview.SetObjects(searchResults);
m_Listview.AutoResizeColumns();
m_Listview.RebuildColumns();
}
ProgressBar.Value = 0;
ProgressBar.Visible = false;
}
catch (Exception ex)
{
Trace(TraceLoggerType.RpcLibraryProcedureList,
TraceEventType.Error,
"Unable to retrieve RPC library procedure list: " + ex.Message);
}
return true;
}
public bool Build(RpcServer Server)
{
Text = "Procedures";
Name = "Procedures";
ImageIndex = 3;
var procs = new List<RpcLibraryProcedure>();
try
{
foreach (var procedure in Server.Procedures)
{
var formatter = DefaultNdrFormatter.Create(DefaultNdrFormatterFlags.RemoveComments);
string friendly = formatter.FormatProcedure(procedure);
procs.Add(new RpcLibraryProcedure()
{
FilePath = Server.FilePath,
InterfaceId = Server.InterfaceId,
InterfaceVersion = Server.InterfaceVersion,
Name = friendly,
});
}
}
catch (Exception ex)
@ -112,6 +144,12 @@ namespace RpcInvestigator
TraceEventType.Error,
"Unable to retrieve RPC library procedure list: " + ex.Message);
}
if (procs.Count > 0)
{
m_Listview.SetObjects(procs);
m_Listview.AutoResizeColumns();
m_Listview.RebuildColumns();
}
return true;
}

View File

@ -86,9 +86,39 @@ namespace RpcInvestigator
}
column.MaximumWidth = -1;
}
m_Listview.ColumnRightClick += ColumnRightClickOverride;
Controls.Add(m_Listview);
}
private void ColumnRightClickOverride(object sender, ColumnClickEventArgs e)
{
//
// Some of the columns we hide by default should never be shown,
// either because they contain binary data or lists of binary data.
// Such information is not easy to disable in the listview, so we'll
// strip those columns from the column selector context menu.
//
var args = (ColumnRightClickEventArgs)e;
var list = new List<ToolStripItem>();
foreach (var item in args.MenuStrip.Items)
{
if (item.GetType() == typeof(ToolStripMenuItem))
{
var toolstripItem = item as ToolStripMenuItem;
if (toolstripItem.Text.ToLower() == "procedures" ||
toolstripItem.Text.ToLower() == "server" ||
toolstripItem.Text.ToLower() == "complextypes" ||
toolstripItem.Text.ToLower() == "endpoints")
{
continue;
}
}
list.Add((ToolStripItem)item);
}
args.MenuStrip.Items.Clear();
args.MenuStrip.Items.AddRange(list.ToArray());
}
public void ScrollToServer(Guid InterfaceId)
{
if (m_Listview.Objects == null)
@ -168,7 +198,8 @@ namespace RpcInvestigator
{
TabPages.ContextMenu.BuildRightClickMenu(Args, new List<ToolStripMenuItem>{
new ToolStripMenuItem("New Client", null, ContextMenuNewClient),
new ToolStripMenuItem("Reset", null, ContextMenuResetSearch)
new ToolStripMenuItem("Reset", null, ContextMenuResetSearch),
new ToolStripMenuItem("View Procedures", null, ContextMenuViewProcedures)
});
TabPages.ContextMenu.AddSearchElements(Args);
}
@ -178,6 +209,18 @@ namespace RpcInvestigator
m_Listview.ModelFilter = null;
}
private void ContextMenuViewProcedures(object Sender, EventArgs Args)
{
object tag = ((ToolStripMenuItem)Sender).Tag;
if (tag == null)
{
return;
}
var args = (CellRightClickEventArgs)tag;
var server = args.Model as RpcServer;
_ = m_Manager.LoadRpcLibraryProceduresTab(server);
}
private void ContextMenuNewClient(object Sender, EventArgs Args)
{
object tag = ((ToolStripMenuItem)Sender).Tag;

View File

@ -134,6 +134,38 @@ namespace RpcInvestigator.TabPages
return libraryProceduresTab;
}
public RpcLibraryProcedureList LoadRpcLibraryProceduresTab(RpcServer Server)
{
TabPage tab;
RpcLibraryProcedureList libraryProceduresTab;
var tabName = "Procedures for ";
if (!string.IsNullOrEmpty(Server.ServiceName))
{
tabName += Server.ServiceName;
}
else if (!string.IsNullOrEmpty(Server.Name))
{
tabName += Server.Name;
}
else
{
tabName += Server.InterfaceId.ToString();
}
if (!TabExists(tabName, out tab))
{
tab = new RpcLibraryProcedureList(m_Library);
tab.Text = tabName; // override name
m_TabControl.TabPages.Add(tab);
}
libraryProceduresTab = tab as RpcLibraryProcedureList;
_ = libraryProceduresTab.Build(Server);
m_TabControl.SelectedTab = libraryProceduresTab;
m_StatusLabel.Text = "Loaded " + libraryProceduresTab.GetCount() +
" procedures from the library";
return libraryProceduresTab;
}
public bool TabExists(string Name, out TabPage Match)
{
Match = null;

View File

@ -53,6 +53,7 @@ namespace RpcInvestigator.Windows.Controls
AlternateRowBackColor = Color.LightBlue;
UseCompatibleStateImageBehavior = false;
VirtualMode = true;
UseFiltering = true;
if (m_Settings.m_SnifferColumns.Count() == 0)
{
m_ChosenColumns = new List<string>() {

View File

@ -3,13 +3,13 @@
<package id="FCTB" version="2.16.24" targetFramework="net481" />
<package id="GraphX" version="3.0.0" targetFramework="net481" />
<package id="Newtonsoft.Json" version="13.0.2" targetFramework="net481" />
<package id="NtApiDotNet" version="1.1.33" targetFramework="net472" />
<package id="NtApiDotNet.Forms" version="1.1.33" targetFramework="net472" />
<package id="ObjectListView.Official" version="2.9.2-alpha2" targetFramework="net472" />
<package id="NtApiDotNet" version="1.1.33" targetFramework="net481" />
<package id="NtApiDotNet.Forms" version="1.1.33" targetFramework="net481" />
<package id="ObjectListView-ToB" version="2.9.4" targetFramework="net481" />
<package id="QuickGraphCore" version="1.0.0" targetFramework="net481" />
<package id="System.Buffers" version="4.4.0" targetFramework="net472" />
<package id="System.Memory" version="4.5.3" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
<package id="System.Resources.Extensions" version="4.6.0" targetFramework="net472" />
<package id="System.Buffers" version="4.4.0" targetFramework="net481" />
<package id="System.Memory" version="4.5.3" targetFramework="net481" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net481" />
<package id="System.Resources.Extensions" version="4.6.0" targetFramework="net481" />
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net481" />
</packages>