mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
7bd28e4357
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@2304 21ef857c-d57f-4fe0-8362-d861dc6d29cd
315 lines
10 KiB
C#
315 lines
10 KiB
C#
using System;
|
|
using System.Windows.Forms;
|
|
using ProcessHacker.Common;
|
|
using ProcessHacker.Common.Ui;
|
|
using ProcessHacker.Native;
|
|
using ProcessHacker.Native.Api;
|
|
using ProcessHacker.Native.Objects;
|
|
using ProcessHacker.Native.Security;
|
|
using ProcessHacker.Native.Symbols;
|
|
using ProcessHacker.Native.Ui;
|
|
|
|
namespace ProcessAnalyzer
|
|
{
|
|
public partial class MainWindow : Form
|
|
{
|
|
private int _pid;
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
|
|
try
|
|
{
|
|
KProcessHacker.Instance = new KProcessHacker();
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
Win32.LoadLibrary("C:\\Program Files\\Debugging Tools for Windows (x86)\\dbghelp.dll");
|
|
|
|
listHandleTraces.ListViewItemSorter = new SortedListViewComparer(listHandleTraces);
|
|
}
|
|
|
|
private void openProcessToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
this.ChooseProcess();
|
|
}
|
|
|
|
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
this.Close();
|
|
}
|
|
|
|
private void ShowException(string operation, Exception ex)
|
|
{
|
|
MessageBox.Show(operation + ": " + ex.Message, "Process Analyzer", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
|
|
#region Handle Tracing
|
|
|
|
private SymbolProvider _symbols;
|
|
private ProcessHandleTraceCollection _currentHtCollection;
|
|
|
|
private void ChooseProcess()
|
|
{
|
|
ChooseProcessDialog cpd = new ChooseProcessDialog();
|
|
|
|
if (cpd.ShowDialog() == DialogResult.OK)
|
|
_pid = cpd.SelectedPid;
|
|
}
|
|
|
|
private void PopulateHandleTraceList()
|
|
{
|
|
listHandleTraces.BeginUpdate();
|
|
listHandleTraces.Items.Clear();
|
|
|
|
for (int i = 0; i < _currentHtCollection.Count; i++)
|
|
{
|
|
var trace = _currentHtCollection[i];
|
|
ListViewItem item = new ListViewItem(
|
|
new string[]
|
|
{
|
|
i.ToString(),
|
|
"0x" + trace.Handle.ToString("x"),
|
|
trace.Type.ToString(),
|
|
trace.ClientId.ThreadId.ToString()
|
|
});
|
|
|
|
item.Tag = i;
|
|
listHandleTraces.Items.Add(item);
|
|
}
|
|
|
|
listHandleTraces.EndUpdate();
|
|
}
|
|
|
|
private void buttonEnableHandleTracing_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
using (var phandle = new ProcessHandle(_pid, ProcessAccess.SetInformation))
|
|
phandle.EnableHandleTracing();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.ShowException("Error enabling handle tracing", ex);
|
|
}
|
|
}
|
|
|
|
private void buttonDisableHandleTracing_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
using (var phandle = new ProcessHandle(_pid, ProcessAccess.SetInformation))
|
|
phandle.DisableHandleTracing();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.ShowException("Error disabling handle tracing", ex);
|
|
}
|
|
}
|
|
|
|
private void buttonSnapshot_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
using (var phandle = new ProcessHandle(_pid, ProcessAccess.QueryInformation | ProcessAccess.VmRead))
|
|
{
|
|
_currentHtCollection = phandle.GetHandleTraces();
|
|
|
|
if (_symbols != null)
|
|
_symbols.Dispose();
|
|
|
|
SymbolProvider.Options |= SymbolOptions.DeferredLoads;
|
|
_symbols = new SymbolProvider(phandle);
|
|
|
|
WorkQueue.GlobalQueueWorkItem(new Action(() =>
|
|
{
|
|
var symbols = _symbols;
|
|
|
|
_symbols.PreloadModules = true;
|
|
|
|
try
|
|
{
|
|
foreach (var module in phandle.GetModules())
|
|
{
|
|
try
|
|
{
|
|
symbols.LoadModule(module.FileName, module.BaseAddress);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
try
|
|
{
|
|
foreach (var module in Windows.GetKernelModules())
|
|
{
|
|
try
|
|
{
|
|
symbols.LoadModule(module.FileName, module.BaseAddress);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}));
|
|
}
|
|
|
|
this.PopulateHandleTraceList();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.ShowException("Error getting the handle trace snapshot", ex);
|
|
}
|
|
}
|
|
|
|
private void listHandleTraces_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (_currentHtCollection == null || listHandleTraces.SelectedItems.Count != 1)
|
|
return;
|
|
|
|
var trace = _currentHtCollection[(int)listHandleTraces.SelectedItems[0].Tag];
|
|
|
|
listHandleStack.BeginUpdate();
|
|
listHandleStack.Items.Clear();
|
|
|
|
foreach (var address in trace.Stack)
|
|
{
|
|
ListViewItem item = new ListViewItem();
|
|
|
|
item.Text = "0x" + address.ToInt32().ToString("x8");
|
|
item.SubItems.Add(new ListViewItem.ListViewSubItem(item, _symbols.GetSymbolFromAddress(address.ToUInt64())));
|
|
listHandleStack.Items.Add(item);
|
|
}
|
|
|
|
listHandleStack.EndUpdate();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Hidden Objects
|
|
|
|
private struct KVars
|
|
{
|
|
public IntPtr NonPagedPoolStartAddress;
|
|
public IntPtr NonPagedPoolSizeAddress;
|
|
public IntPtr NonPagedPoolStart;
|
|
public uint NonPagedPoolSize;
|
|
public IntPtr PsProcessTypeAddress;
|
|
public IntPtr PsProcessType;
|
|
public IntPtr PsThreadTypeAddress;
|
|
public IntPtr PsThreadType;
|
|
}
|
|
|
|
private unsafe KVars GetKVars()
|
|
{
|
|
SymbolProvider symbols = new SymbolProvider();
|
|
|
|
symbols.LoadModule(Windows.KernelFileName, Windows.KernelBase);
|
|
|
|
KVars vars = new KVars();
|
|
|
|
vars.NonPagedPoolStartAddress = symbols.GetSymbolFromName("MmNonPagedPoolStart").Address.ToIntPtr();
|
|
vars.NonPagedPoolSizeAddress = symbols.GetSymbolFromName("MmMaximumNonPagedPoolInBytes").Address.ToIntPtr();
|
|
vars.PsProcessTypeAddress = symbols.GetSymbolFromName("PsProcessType").Address.ToIntPtr();
|
|
vars.PsThreadTypeAddress = symbols.GetSymbolFromName("PsThreadType").Address.ToIntPtr();
|
|
|
|
int bytesRead;
|
|
|
|
KProcessHacker.Instance.KphReadVirtualMemoryUnsafe(
|
|
ProcessHandle.Current,
|
|
vars.NonPagedPoolStartAddress.ToInt32(),
|
|
&vars.NonPagedPoolStart,
|
|
IntPtr.Size,
|
|
out bytesRead
|
|
);
|
|
KProcessHacker.Instance.KphReadVirtualMemoryUnsafe(
|
|
ProcessHandle.Current,
|
|
vars.NonPagedPoolSizeAddress.ToInt32(),
|
|
&vars.NonPagedPoolSize,
|
|
sizeof(uint),
|
|
out bytesRead
|
|
);
|
|
KProcessHacker.Instance.KphReadVirtualMemoryUnsafe(
|
|
ProcessHandle.Current,
|
|
vars.PsProcessTypeAddress.ToInt32(),
|
|
&vars.PsProcessType,
|
|
IntPtr.Size,
|
|
out bytesRead
|
|
);
|
|
KProcessHacker.Instance.KphReadVirtualMemoryUnsafe(
|
|
ProcessHandle.Current,
|
|
vars.PsThreadTypeAddress.ToInt32(),
|
|
&vars.PsThreadType,
|
|
IntPtr.Size,
|
|
out bytesRead
|
|
);
|
|
|
|
symbols.Dispose();
|
|
|
|
return vars;
|
|
}
|
|
|
|
private unsafe void ScanHiddenObjects()
|
|
{
|
|
KVars vars = this.GetKVars();
|
|
int bytesRead;
|
|
|
|
throw new NotSupportedException();
|
|
|
|
listHiddenObjects.Items.Clear();
|
|
|
|
using (var currentPage = new MemoryAlloc(Windows.PageSize))
|
|
{
|
|
for (
|
|
IntPtr address = vars.NonPagedPoolStart;
|
|
address.CompareTo(vars.NonPagedPoolStart.Increment(vars.NonPagedPoolSize)) == -1;
|
|
address = address.Increment(Windows.PageSize)
|
|
)
|
|
{
|
|
try
|
|
{
|
|
KProcessHacker.Instance.KphReadVirtualMemoryUnsafe(
|
|
ProcessHandle.Current,
|
|
address.ToInt32(),
|
|
(IntPtr)currentPage,
|
|
Windows.PageSize,
|
|
out bytesRead
|
|
);
|
|
}
|
|
catch
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for (
|
|
IntPtr inner = address;
|
|
inner.CompareTo(address.Increment(Windows.PageSize)) == -1;
|
|
inner = inner.Increment(8)
|
|
)
|
|
{
|
|
}
|
|
|
|
labelObjectsScanProgress.Text = string.Format("Scanned 0x{0:x8}", address.ToInt32());
|
|
Application.DoEvents();
|
|
}
|
|
}
|
|
|
|
labelObjectsScanProgress.Text = "Finished.";
|
|
}
|
|
|
|
private void buttonScanHiddenObjects_Click(object sender, EventArgs e)
|
|
{
|
|
this.ScanHiddenObjects();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|