mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
dbghelp.dll support!
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1047 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -2,6 +2,7 @@ Process Hacker
|
||||
|
||||
1.3.6.6
|
||||
* NEW:
|
||||
* Proper symbol support with dbghelp.dll
|
||||
* Aggressive mode (start with "-a" command line option)
|
||||
* FIXED:
|
||||
* Service properties Key handle leak
|
||||
|
||||
@@ -87,6 +87,8 @@ namespace ProcessHacker
|
||||
|
||||
private void listThreads_SelectedIndexChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
this.Cursor = Cursors.WaitCursor;
|
||||
|
||||
if (listThreads.SelectedItems.Count == 1)
|
||||
{
|
||||
try
|
||||
@@ -94,9 +96,18 @@ namespace ProcessHacker
|
||||
int tid = int.Parse(listThreads.SelectedItems[0].Name);
|
||||
ProcessItem process = Program.HackerWindow.ProcessProvider.Dictionary[_pid];
|
||||
ProcessThread thread = Misc.GetThreadById(Process.GetProcessById(_pid), tid);
|
||||
string fileName;
|
||||
|
||||
fileModule.Text = _provider.Symbols.GetModuleFromAddress(_provider.Dictionary[tid].StartAddressI);
|
||||
fileModule.Enabled = true;
|
||||
try
|
||||
{
|
||||
_provider.Symbols.GetSymbolFromAddress(_provider.Dictionary[tid].StartAddressI, out fileName);
|
||||
fileModule.Text = fileName;
|
||||
fileModule.Enabled = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
fileModule.Enabled = false;
|
||||
}
|
||||
|
||||
if (thread.ThreadState == ThreadState.Wait)
|
||||
{
|
||||
@@ -136,6 +147,8 @@ namespace ProcessHacker
|
||||
|
||||
if (this.SelectedIndexChanged != null)
|
||||
this.SelectedIndexChanged(sender, e);
|
||||
|
||||
this.Cursor = Cursors.Default;
|
||||
}
|
||||
|
||||
private void ThreadList_KeyDown(object sender, KeyEventArgs e)
|
||||
@@ -201,6 +214,7 @@ namespace ProcessHacker
|
||||
_provider.DictionaryModified -= new ThreadProvider.ProviderDictionaryModified(provider_DictionaryModified);
|
||||
_provider.DictionaryRemoved -= new ThreadProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved);
|
||||
_provider.Updated -= new ThreadProvider.ProviderUpdateOnce(provider_Updated);
|
||||
_provider.LoadingStateChanged -= new ThreadProvider.LoadingStateChangedDelegate(provider_LoadingStateChanged);
|
||||
}
|
||||
|
||||
_provider = value;
|
||||
@@ -220,6 +234,7 @@ namespace ProcessHacker
|
||||
_provider.DictionaryModified += new ThreadProvider.ProviderDictionaryModified(provider_DictionaryModified);
|
||||
_provider.DictionaryRemoved += new ThreadProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved);
|
||||
_provider.Updated += new ThreadProvider.ProviderUpdateOnce(provider_Updated);
|
||||
_provider.LoadingStateChanged += new ThreadProvider.LoadingStateChangedDelegate(provider_LoadingStateChanged);
|
||||
|
||||
_pid = _provider.PID;
|
||||
_process = Process.GetProcessById(_pid);
|
||||
@@ -326,6 +341,17 @@ namespace ProcessHacker
|
||||
listThreads.Items[item.TID.ToString()].Remove();
|
||||
}
|
||||
|
||||
private void provider_LoadingStateChanged(bool loading)
|
||||
{
|
||||
this.BeginInvoke(new MethodInvoker(delegate
|
||||
{
|
||||
if (loading)
|
||||
listThreads.Cursor = Cursors.AppStarting;
|
||||
else
|
||||
listThreads.Cursor = Cursors.Default;
|
||||
}));
|
||||
}
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
Properties.Settings.Default.ThreadListViewColumns = ColumnSettings.SaveSettings(listThreads);
|
||||
@@ -468,23 +494,13 @@ namespace ProcessHacker
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadWindow window;
|
||||
|
||||
try
|
||||
{
|
||||
window = Program.GetThreadWindow(_pid,
|
||||
Int32.Parse(listThreads.SelectedItems[0].SubItems[0].Text),
|
||||
_provider.Symbols,
|
||||
new Program.ThreadWindowInvokeAction(delegate(ThreadWindow f)
|
||||
{
|
||||
try
|
||||
{
|
||||
f.Show();
|
||||
f.Activate();
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}));
|
||||
(new ThreadWindow(
|
||||
_pid,
|
||||
Int32.Parse(listThreads.SelectedItems[0].SubItems[0].Text),
|
||||
_provider.Symbols)
|
||||
).ShowDialog(this);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
@@ -216,6 +216,11 @@ namespace ProcessHacker
|
||||
}, this.Handle);
|
||||
}
|
||||
|
||||
private void apiLoggerMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
(new Forms.ApiLogWindow()).Show();
|
||||
}
|
||||
|
||||
private void findHandlesMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (HandleFilterWindow == null)
|
||||
@@ -1851,6 +1856,8 @@ namespace ProcessHacker
|
||||
|
||||
HistoryManager.GlobalMaxCount = Properties.Settings.Default.MaxSamples;
|
||||
ProcessHacker.Components.Plotter.GlobalMoveStep = Properties.Settings.Default.PlotterStep;
|
||||
|
||||
Win32.LoadLibrary(Properties.Settings.Default.DbgHelpPath);
|
||||
}
|
||||
|
||||
public void QueueMessage(string message)
|
||||
@@ -2227,35 +2234,6 @@ namespace ProcessHacker
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadSymbols()
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(o =>
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] modules =
|
||||
{
|
||||
"advapi32.dll", "comctl32.dll", "crypt32.dll", "dnsapi.dll",
|
||||
"gdi32.dll", "imagehlp.dll", "kernel32.dll",
|
||||
"ntdll.dll", "ole32.dll", "psapi.dll", "rpcrt4.dll", "shell32.dll",
|
||||
"user32.dll", "winsta.dll", "wintrust.dll", "wtsapi32.dll" };
|
||||
|
||||
foreach (string module in modules)
|
||||
{
|
||||
try
|
||||
{
|
||||
SymbolProvider.BaseInstance.LoadSymbolsFromLibrary(Environment.SystemDirectory + "\\" + module,
|
||||
(uint)Win32.GetModuleHandle(module));
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}));
|
||||
}
|
||||
|
||||
private void LoadApplyCommandLineArgs()
|
||||
{
|
||||
tabControl.SelectedTab = tabControl.TabPages["tab" + Program.SelectTab];
|
||||
@@ -2292,7 +2270,6 @@ namespace ProcessHacker
|
||||
this.LoadSettings();
|
||||
this.LoadControls();
|
||||
this.LoadAddShortcuts();
|
||||
this.LoadSymbols();
|
||||
this.ResumeLayout();
|
||||
|
||||
if ((!Properties.Settings.Default.StartHidden && !Program.StartHidden) ||
|
||||
@@ -2368,10 +2345,5 @@ namespace ProcessHacker
|
||||
}
|
||||
base.OnResize(e);
|
||||
}
|
||||
|
||||
private void apiLoggerMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
(new Forms.ApiLogWindow()).Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+122
-26
@@ -59,6 +59,8 @@
|
||||
this.checkHideHandlesWithNoName = new System.Windows.Forms.CheckBox();
|
||||
this.checkVerifySignatures = new System.Windows.Forms.CheckBox();
|
||||
this.tabHighlighting = new System.Windows.Forms.TabPage();
|
||||
this.buttonDisableAll = new System.Windows.Forms.Button();
|
||||
this.buttonEnableAll = new System.Windows.Forms.Button();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.listHighlightingColors = new System.Windows.Forms.ListView();
|
||||
this.columnDescription = new System.Windows.Forms.ColumnHeader();
|
||||
@@ -84,11 +86,16 @@
|
||||
this.colorMemoryPB = new ProcessHacker.Components.ColorModifier();
|
||||
this.colorCPUUT = new ProcessHacker.Components.ColorModifier();
|
||||
this.colorCPUKT = new ProcessHacker.Components.ColorModifier();
|
||||
this.tabSymbols = new System.Windows.Forms.TabPage();
|
||||
this.checkUndecorate = new System.Windows.Forms.CheckBox();
|
||||
this.textSearchPath = new System.Windows.Forms.TextBox();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.buttonDbghelpBrowse = new System.Windows.Forms.Button();
|
||||
this.textDbghelpPath = new System.Windows.Forms.TextBox();
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.label22 = new System.Windows.Forms.Label();
|
||||
this.toolTipProvider = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.buttonCancel = new System.Windows.Forms.Button();
|
||||
this.buttonEnableAll = new System.Windows.Forms.Button();
|
||||
this.buttonDisableAll = new System.Windows.Forms.Button();
|
||||
((System.ComponentModel.ISupportInitialize)(this.textUpdateInterval)).BeginInit();
|
||||
this.tabControl.SuspendLayout();
|
||||
this.tabGeneral.SuspendLayout();
|
||||
@@ -99,6 +106,7 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this.textHighlightingDuration)).BeginInit();
|
||||
this.tabPlotting.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.textStep)).BeginInit();
|
||||
this.tabSymbols.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
@@ -207,6 +215,7 @@
|
||||
this.tabControl.Controls.Add(this.tabAdvanced);
|
||||
this.tabControl.Controls.Add(this.tabHighlighting);
|
||||
this.tabControl.Controls.Add(this.tabPlotting);
|
||||
this.tabControl.Controls.Add(this.tabSymbols);
|
||||
this.tabControl.Location = new System.Drawing.Point(12, 12);
|
||||
this.tabControl.Name = "tabControl";
|
||||
this.tabControl.SelectedIndex = 0;
|
||||
@@ -522,6 +531,30 @@
|
||||
this.tabHighlighting.Text = "Highlighting";
|
||||
this.tabHighlighting.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// buttonDisableAll
|
||||
//
|
||||
this.buttonDisableAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonDisableAll.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonDisableAll.Location = new System.Drawing.Point(336, 312);
|
||||
this.buttonDisableAll.Name = "buttonDisableAll";
|
||||
this.buttonDisableAll.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonDisableAll.TabIndex = 12;
|
||||
this.buttonDisableAll.Text = "&Disable All";
|
||||
this.buttonDisableAll.UseVisualStyleBackColor = true;
|
||||
this.buttonDisableAll.Click += new System.EventHandler(this.buttonDisableAll_Click);
|
||||
//
|
||||
// buttonEnableAll
|
||||
//
|
||||
this.buttonEnableAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonEnableAll.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonEnableAll.Location = new System.Drawing.Point(255, 312);
|
||||
this.buttonEnableAll.Name = "buttonEnableAll";
|
||||
this.buttonEnableAll.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonEnableAll.TabIndex = 12;
|
||||
this.buttonEnableAll.Text = "&Enable All";
|
||||
this.buttonEnableAll.UseVisualStyleBackColor = true;
|
||||
this.buttonEnableAll.Click += new System.EventHandler(this.buttonEnableAll_Click);
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
@@ -801,6 +834,84 @@
|
||||
this.colorCPUKT.Size = new System.Drawing.Size(40, 20);
|
||||
this.colorCPUKT.TabIndex = 11;
|
||||
//
|
||||
// tabSymbols
|
||||
//
|
||||
this.tabSymbols.Controls.Add(this.checkUndecorate);
|
||||
this.tabSymbols.Controls.Add(this.textSearchPath);
|
||||
this.tabSymbols.Controls.Add(this.label10);
|
||||
this.tabSymbols.Controls.Add(this.buttonDbghelpBrowse);
|
||||
this.tabSymbols.Controls.Add(this.textDbghelpPath);
|
||||
this.tabSymbols.Controls.Add(this.label9);
|
||||
this.tabSymbols.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabSymbols.Name = "tabSymbols";
|
||||
this.tabSymbols.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabSymbols.Size = new System.Drawing.Size(417, 341);
|
||||
this.tabSymbols.TabIndex = 4;
|
||||
this.tabSymbols.Text = "Symbols";
|
||||
this.tabSymbols.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkUndecorate
|
||||
//
|
||||
this.checkUndecorate.AutoSize = true;
|
||||
this.checkUndecorate.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.checkUndecorate.Location = new System.Drawing.Point(6, 60);
|
||||
this.checkUndecorate.Name = "checkUndecorate";
|
||||
this.checkUndecorate.Size = new System.Drawing.Size(128, 18);
|
||||
this.checkUndecorate.TabIndex = 5;
|
||||
this.checkUndecorate.Text = "Undecorate symbols";
|
||||
this.toolTipProvider.SetToolTip(this.checkUndecorate, "If selected, C++ symbol names will be undecorated.");
|
||||
this.checkUndecorate.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// textSearchPath
|
||||
//
|
||||
this.textSearchPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textSearchPath.Location = new System.Drawing.Point(99, 34);
|
||||
this.textSearchPath.Name = "textSearchPath";
|
||||
this.textSearchPath.Size = new System.Drawing.Size(312, 20);
|
||||
this.textSearchPath.TabIndex = 4;
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(6, 37);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(68, 13);
|
||||
this.label10.TabIndex = 3;
|
||||
this.label10.Text = "Search path:";
|
||||
//
|
||||
// buttonDbghelpBrowse
|
||||
//
|
||||
this.buttonDbghelpBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonDbghelpBrowse.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonDbghelpBrowse.Location = new System.Drawing.Point(336, 6);
|
||||
this.buttonDbghelpBrowse.Name = "buttonDbghelpBrowse";
|
||||
this.buttonDbghelpBrowse.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonDbghelpBrowse.TabIndex = 2;
|
||||
this.buttonDbghelpBrowse.Text = "Browse...";
|
||||
this.buttonDbghelpBrowse.UseVisualStyleBackColor = true;
|
||||
this.buttonDbghelpBrowse.Click += new System.EventHandler(this.buttonDbghelpBrowse_Click);
|
||||
//
|
||||
// textDbghelpPath
|
||||
//
|
||||
this.textDbghelpPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textDbghelpPath.Location = new System.Drawing.Point(99, 8);
|
||||
this.textDbghelpPath.Name = "textDbghelpPath";
|
||||
this.textDbghelpPath.Size = new System.Drawing.Size(231, 20);
|
||||
this.textDbghelpPath.TabIndex = 1;
|
||||
//
|
||||
// label9
|
||||
//
|
||||
this.label9.AutoSize = true;
|
||||
this.label9.Location = new System.Drawing.Point(6, 11);
|
||||
this.label9.Name = "label9";
|
||||
this.label9.Size = new System.Drawing.Size(87, 13);
|
||||
this.label9.TabIndex = 0;
|
||||
this.label9.Text = "Dbghelp.dll path:";
|
||||
this.toolTipProvider.SetToolTip(this.label9, "Select the most recent version of dbghelp.dll available, usually distributed with" +
|
||||
" Debugging Tools for Windows.");
|
||||
//
|
||||
// label22
|
||||
//
|
||||
this.label22.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
@@ -831,30 +942,6 @@
|
||||
this.buttonCancel.UseVisualStyleBackColor = true;
|
||||
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
|
||||
//
|
||||
// buttonEnableAll
|
||||
//
|
||||
this.buttonEnableAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonEnableAll.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonEnableAll.Location = new System.Drawing.Point(255, 312);
|
||||
this.buttonEnableAll.Name = "buttonEnableAll";
|
||||
this.buttonEnableAll.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonEnableAll.TabIndex = 12;
|
||||
this.buttonEnableAll.Text = "&Enable All";
|
||||
this.buttonEnableAll.UseVisualStyleBackColor = true;
|
||||
this.buttonEnableAll.Click += new System.EventHandler(this.buttonEnableAll_Click);
|
||||
//
|
||||
// buttonDisableAll
|
||||
//
|
||||
this.buttonDisableAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonDisableAll.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonDisableAll.Location = new System.Drawing.Point(336, 312);
|
||||
this.buttonDisableAll.Name = "buttonDisableAll";
|
||||
this.buttonDisableAll.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonDisableAll.TabIndex = 12;
|
||||
this.buttonDisableAll.Text = "&Disable All";
|
||||
this.buttonDisableAll.UseVisualStyleBackColor = true;
|
||||
this.buttonDisableAll.Click += new System.EventHandler(this.buttonDisableAll_Click);
|
||||
//
|
||||
// OptionsWindow
|
||||
//
|
||||
this.AcceptButton = this.buttonOK;
|
||||
@@ -889,6 +976,8 @@
|
||||
this.tabPlotting.ResumeLayout(false);
|
||||
this.tabPlotting.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.textStep)).EndInit();
|
||||
this.tabSymbols.ResumeLayout(false);
|
||||
this.tabSymbols.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@@ -956,5 +1045,12 @@
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
private System.Windows.Forms.Button buttonDisableAll;
|
||||
private System.Windows.Forms.Button buttonEnableAll;
|
||||
private System.Windows.Forms.TabPage tabSymbols;
|
||||
private System.Windows.Forms.Label label9;
|
||||
private System.Windows.Forms.TextBox textSearchPath;
|
||||
private System.Windows.Forms.Label label10;
|
||||
private System.Windows.Forms.Button buttonDbghelpBrowse;
|
||||
private System.Windows.Forms.TextBox textDbghelpPath;
|
||||
private System.Windows.Forms.CheckBox checkUndecorate;
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,16 @@ namespace ProcessHacker
|
||||
catch
|
||||
{
|
||||
checkReplaceTaskManager.Enabled = false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
textDbghelpPath.Text = Properties.Settings.Default.DbgHelpPath;
|
||||
textSearchPath.Text = Properties.Settings.Default.DbgHelpSearchPath;
|
||||
checkUndecorate.Checked = (Symbols.Options & Win32.SYMBOL_OPTIONS.UndName) != 0;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
checkShowTrayIcon_CheckedChanged(null, null);
|
||||
}
|
||||
@@ -333,6 +342,15 @@ namespace ProcessHacker
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Properties.Settings.Default.DbgHelpPath = textDbghelpPath.Text;
|
||||
Properties.Settings.Default.DbgHelpSearchPath = textSearchPath.Text;
|
||||
Properties.Settings.Default.DbgHelpUndecorate = checkUndecorate.Checked;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
Program.HackerWindow.ProcessProvider.Interval = Properties.Settings.Default.RefreshInterval;
|
||||
Program.HackerWindow.ServiceProvider.Interval = Properties.Settings.Default.RefreshInterval;
|
||||
Program.HackerWindow.NetworkProvider.Interval = Properties.Settings.Default.RefreshInterval;
|
||||
@@ -417,5 +435,16 @@ namespace ProcessHacker
|
||||
foreach (ListViewItem item in listHighlightingColors.Items)
|
||||
item.Checked = false;
|
||||
}
|
||||
|
||||
private void buttonDbghelpBrowse_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog();
|
||||
|
||||
ofd.Filter = "dbghelp.dll|dbghelp.dll|DLL files (*.dll)|*.dll|All files (*.*)|*.*";
|
||||
ofd.FileName = textDbghelpPath.Text;
|
||||
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
textDbghelpPath.Text = ofd.FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-21
@@ -23,9 +23,6 @@
|
||||
if (_thandle != null)
|
||||
_thandle.Dispose();
|
||||
|
||||
Program.ThreadWindows.Remove(Id);
|
||||
Program.UpdateWindows();
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
@@ -46,7 +43,6 @@
|
||||
this.suspendMenuItem = new System.Windows.Forms.MenuItem();
|
||||
this.resumeMenuItem = new System.Windows.Forms.MenuItem();
|
||||
this.terminateMenuItem = new System.Windows.Forms.MenuItem();
|
||||
this.windowMenuItem = new System.Windows.Forms.MenuItem();
|
||||
this.timerUpdate = new System.Windows.Forms.Timer(this.components);
|
||||
this.listViewCallStack = new System.Windows.Forms.ListView();
|
||||
this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
|
||||
@@ -69,8 +65,7 @@
|
||||
// mainMenu
|
||||
//
|
||||
this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.threadMenuItem,
|
||||
this.windowMenuItem});
|
||||
this.threadMenuItem});
|
||||
//
|
||||
// threadMenuItem
|
||||
//
|
||||
@@ -119,11 +114,6 @@
|
||||
this.terminateMenuItem.Text = "&Terminate";
|
||||
this.terminateMenuItem.Click += new System.EventHandler(this.terminateMenuItem_Click);
|
||||
//
|
||||
// windowMenuItem
|
||||
//
|
||||
this.windowMenuItem.Index = 1;
|
||||
this.windowMenuItem.Text = "&Window";
|
||||
//
|
||||
// timerUpdate
|
||||
//
|
||||
this.timerUpdate.Enabled = true;
|
||||
@@ -143,7 +133,7 @@
|
||||
this.listViewCallStack.Location = new System.Drawing.Point(6, 19);
|
||||
this.listViewCallStack.Name = "listViewCallStack";
|
||||
this.listViewCallStack.ShowItemToolTips = true;
|
||||
this.listViewCallStack.Size = new System.Drawing.Size(363, 137);
|
||||
this.listViewCallStack.Size = new System.Drawing.Size(363, 140);
|
||||
this.listViewCallStack.TabIndex = 0;
|
||||
this.listViewCallStack.UseCompatibleStateImageBehavior = false;
|
||||
this.listViewCallStack.View = System.Windows.Forms.View.Details;
|
||||
@@ -170,7 +160,7 @@
|
||||
this.groupBoxCallStack.Controls.Add(this.listViewCallStack);
|
||||
this.groupBoxCallStack.Location = new System.Drawing.Point(12, 34);
|
||||
this.groupBoxCallStack.Name = "groupBoxCallStack";
|
||||
this.groupBoxCallStack.Size = new System.Drawing.Size(375, 191);
|
||||
this.groupBoxCallStack.Size = new System.Drawing.Size(375, 194);
|
||||
this.groupBoxCallStack.TabIndex = 1;
|
||||
this.groupBoxCallStack.TabStop = false;
|
||||
this.groupBoxCallStack.Text = "Call Stack";
|
||||
@@ -179,7 +169,7 @@
|
||||
//
|
||||
this.fileModule.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.fileModule.Location = new System.Drawing.Point(57, 161);
|
||||
this.fileModule.Location = new System.Drawing.Point(57, 164);
|
||||
this.fileModule.Name = "fileModule";
|
||||
this.fileModule.ReadOnly = false;
|
||||
this.fileModule.Size = new System.Drawing.Size(231, 24);
|
||||
@@ -189,7 +179,7 @@
|
||||
//
|
||||
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(6, 167);
|
||||
this.label1.Location = new System.Drawing.Point(6, 170);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(45, 13);
|
||||
this.label1.TabIndex = 4;
|
||||
@@ -199,7 +189,7 @@
|
||||
//
|
||||
this.buttonWalk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonWalk.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonWalk.Location = new System.Drawing.Point(294, 162);
|
||||
this.buttonWalk.Location = new System.Drawing.Point(294, 165);
|
||||
this.buttonWalk.Name = "buttonWalk";
|
||||
this.buttonWalk.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonWalk.TabIndex = 3;
|
||||
@@ -212,9 +202,9 @@
|
||||
this.groupRegisters.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.groupRegisters.Controls.Add(this.listViewRegisters);
|
||||
this.groupRegisters.Location = new System.Drawing.Point(12, 231);
|
||||
this.groupRegisters.Location = new System.Drawing.Point(12, 234);
|
||||
this.groupRegisters.Name = "groupRegisters";
|
||||
this.groupRegisters.Size = new System.Drawing.Size(375, 153);
|
||||
this.groupRegisters.Size = new System.Drawing.Size(375, 129);
|
||||
this.groupRegisters.TabIndex = 2;
|
||||
this.groupRegisters.TabStop = false;
|
||||
this.groupRegisters.Text = "Registers";
|
||||
@@ -230,7 +220,7 @@
|
||||
this.listViewRegisters.FullRowSelect = true;
|
||||
this.listViewRegisters.Location = new System.Drawing.Point(6, 19);
|
||||
this.listViewRegisters.Name = "listViewRegisters";
|
||||
this.listViewRegisters.Size = new System.Drawing.Size(363, 128);
|
||||
this.listViewRegisters.Size = new System.Drawing.Size(363, 104);
|
||||
this.listViewRegisters.TabIndex = 0;
|
||||
this.listViewRegisters.UseCompatibleStateImageBehavior = false;
|
||||
this.listViewRegisters.View = System.Windows.Forms.View.Details;
|
||||
@@ -261,13 +251,17 @@
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(399, 396);
|
||||
this.ClientSize = new System.Drawing.Size(399, 375);
|
||||
this.Controls.Add(this.labelThreadUser);
|
||||
this.Controls.Add(this.groupRegisters);
|
||||
this.Controls.Add(this.groupBoxCallStack);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.Menu = this.mainMenu;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "ThreadWindow";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Thread";
|
||||
this.Load += new System.EventHandler(this.ThreadWindow_Load);
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ThreadWindow_FormClosing);
|
||||
@@ -284,7 +278,6 @@
|
||||
|
||||
private wyDay.Controls.VistaMenu vistaMenu;
|
||||
private System.Windows.Forms.MainMenu mainMenu;
|
||||
private System.Windows.Forms.MenuItem windowMenuItem;
|
||||
private System.Windows.Forms.Timer timerUpdate;
|
||||
private System.Windows.Forms.GroupBox groupBoxCallStack;
|
||||
private System.Windows.Forms.ListView listViewCallStack;
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ProcessHacker
|
||||
private int _tid;
|
||||
private Win32.ProcessHandle _phandle;
|
||||
private Win32.ThreadHandle _thandle;
|
||||
private SymbolProvider _symbols;
|
||||
private Symbols _symbols;
|
||||
|
||||
public const string DisplayFormat = "0x{0:x8}";
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace ProcessHacker
|
||||
get { return _pid + "-" + _tid; }
|
||||
}
|
||||
|
||||
public ThreadWindow(int PID, int TID, SymbolProvider symbols)
|
||||
public ThreadWindow(int PID, int TID, Symbols symbols)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -55,8 +55,6 @@ namespace ProcessHacker
|
||||
_tid = TID;
|
||||
_symbols = symbols;
|
||||
|
||||
Program.ThreadWindows.Add(Id, this);
|
||||
|
||||
this.Text = Win32.GetNameFromPID(_pid) + " (PID " + _pid.ToString() +
|
||||
") - Thread " + _tid.ToString();
|
||||
|
||||
@@ -109,16 +107,6 @@ namespace ProcessHacker
|
||||
{ }
|
||||
}
|
||||
|
||||
public MenuItem WindowMenuItem
|
||||
{
|
||||
get { return windowMenuItem; }
|
||||
}
|
||||
|
||||
public wyDay.Controls.VistaMenu VistaMenu
|
||||
{
|
||||
get { return vistaMenu; }
|
||||
}
|
||||
|
||||
private void ThreadWindow_Load(object sender, EventArgs e)
|
||||
{
|
||||
listViewCallStack.SetTheme("explorer");
|
||||
@@ -169,8 +157,6 @@ namespace ProcessHacker
|
||||
|
||||
this.Size = Properties.Settings.Default.ThreadWindowSize;
|
||||
ColumnSettings.LoadSettings(Properties.Settings.Default.CallStackColumns, listViewCallStack);
|
||||
|
||||
Program.UpdateWindows();
|
||||
}
|
||||
|
||||
private void ThreadWindow_FormClosing(object sender, FormClosingEventArgs e)
|
||||
@@ -262,7 +248,7 @@ namespace ProcessHacker
|
||||
//}
|
||||
|
||||
if (!Win32.StackWalk64(Win32.MachineType.IMAGE_FILE_MACHINE_i386, _phandle, _thandle,
|
||||
ref stackFrame, ref context, readMemoryProc, null, null, 0))
|
||||
ref stackFrame, ref context, readMemoryProc, Win32.SymFunctionTableAccess64, Win32.SymGetModuleBase64, 0))
|
||||
break;
|
||||
|
||||
if (stackFrame.AddrPC.Offset == 0)
|
||||
@@ -272,7 +258,7 @@ namespace ProcessHacker
|
||||
|
||||
ListViewItem newItem = listViewCallStack.Items.Add(new ListViewItem(new string[] {
|
||||
"0x" + addr.ToString("x8"),
|
||||
_symbols.GetNameFromAddress(addr)
|
||||
_symbols.GetSymbolFromAddress(addr)
|
||||
}));
|
||||
|
||||
newItem.Tag = addr;
|
||||
@@ -410,7 +396,10 @@ namespace ProcessHacker
|
||||
{
|
||||
if (listViewCallStack.SelectedItems.Count == 1)
|
||||
{
|
||||
fileModule.Text = _symbols.GetModuleFromAddress((uint)listViewCallStack.SelectedItems[0].Tag);
|
||||
string fileName;
|
||||
|
||||
_symbols.GetSymbolFromAddress((uint)listViewCallStack.SelectedItems[0].Tag, out fileName);
|
||||
fileModule.Text = fileName;
|
||||
fileModule.Enabled = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -609,6 +609,7 @@
|
||||
<Compile Include="SharpDevelop\Wrappers\Util.cs" />
|
||||
<Compile Include="Actions\ProcessActions.cs" />
|
||||
<Compile Include="Singleton.cs" />
|
||||
<Compile Include="Symbols\Symbols.cs" />
|
||||
<Compile Include="UsageIcon.cs" />
|
||||
<Compile Include="GenericViewMenu.cs" />
|
||||
<Compile Include="PE\PEException.cs" />
|
||||
@@ -704,7 +705,6 @@
|
||||
<Compile Include="Structs\StructField.cs" />
|
||||
<Compile Include="Structs\StructDef.cs" />
|
||||
<Compile Include="Structs\StructParser.cs" />
|
||||
<Compile Include="Symbols\SymbolProvider.cs" />
|
||||
<Compile Include="Win32\API\Enums.cs" />
|
||||
<Compile Include="Win32\API\Structs.cs" />
|
||||
<Compile Include="Win32\API\Functions.cs" />
|
||||
|
||||
@@ -70,10 +70,6 @@ namespace ProcessHacker
|
||||
public static Dictionary<string, ResultsWindow> ResultsWindows = new Dictionary<string, ResultsWindow>();
|
||||
public static Dictionary<string, Thread> ResultsThreads = new Dictionary<string, Thread>();
|
||||
|
||||
public const bool ThreadWindowsThreaded = false;
|
||||
public static Dictionary<string, ThreadWindow> ThreadWindows = new Dictionary<string, ThreadWindow>();
|
||||
public static Dictionary<string, Thread> ThreadThreads = new Dictionary<string, Thread>();
|
||||
|
||||
public const bool PEWindowsThreaded = false;
|
||||
public static Dictionary<string, PEWindow> PEWindows = new Dictionary<string, PEWindow>();
|
||||
public static Dictionary<string, Thread> PEThreads = new Dictionary<string, Thread>();
|
||||
@@ -735,68 +731,6 @@ namespace ProcessHacker
|
||||
return rw;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the thread window on a separate thread.
|
||||
/// </summary>
|
||||
public static ThreadWindow GetThreadWindow(int PID, int TID, SymbolProvider symbols)
|
||||
{
|
||||
return GetThreadWindow(PID, TID, symbols, new ThreadWindowInvokeAction(delegate { }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the thread window on a separate thread and invokes an action on that thread.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to be performed.</param>
|
||||
public static ThreadWindow GetThreadWindow(int PID, int TID, SymbolProvider symbols, ThreadWindowInvokeAction action)
|
||||
{
|
||||
ThreadWindow tw = null;
|
||||
string id = PID + "-" + TID;
|
||||
|
||||
if (ThreadWindows.ContainsKey(id))
|
||||
{
|
||||
tw = ThreadWindows[id];
|
||||
|
||||
tw.Invoke(action, tw);
|
||||
|
||||
return tw;
|
||||
}
|
||||
|
||||
if (ThreadWindowsThreaded)
|
||||
{
|
||||
Thread t = new Thread(new ThreadStart(delegate
|
||||
{
|
||||
tw = new ThreadWindow(PID, TID, symbols);
|
||||
|
||||
id = tw.Id;
|
||||
|
||||
action(tw);
|
||||
|
||||
try
|
||||
{
|
||||
Application.Run(tw);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
Program.ThreadThreads.Remove(id);
|
||||
}));
|
||||
|
||||
t.SetApartmentState(ApartmentState.STA);
|
||||
t.Start();
|
||||
|
||||
while (id == "") Thread.Sleep(1);
|
||||
Program.ThreadThreads.Add(id, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
tw = new ThreadWindow(PID, TID, symbols);
|
||||
action(tw);
|
||||
tw.Show();
|
||||
}
|
||||
|
||||
return tw;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the PE window on a separate thread.
|
||||
/// </summary>
|
||||
@@ -1011,7 +945,6 @@ namespace ProcessHacker
|
||||
|
||||
dics.Add(Program.MemoryEditors);
|
||||
dics.Add(Program.ResultsWindows);
|
||||
dics.Add(Program.ThreadWindows);
|
||||
dics.Add(Program.PEWindows);
|
||||
dics.Add(Program.PWindows);
|
||||
|
||||
|
||||
+36
@@ -1248,5 +1248,41 @@ namespace ProcessHacker.Properties {
|
||||
this["UseColorGuiThreads"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("dbghelp.dll")]
|
||||
public string DbgHelpPath {
|
||||
get {
|
||||
return ((string)(this["DbgHelpPath"]));
|
||||
}
|
||||
set {
|
||||
this["DbgHelpPath"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string DbgHelpSearchPath {
|
||||
get {
|
||||
return ((string)(this["DbgHelpSearchPath"]));
|
||||
}
|
||||
set {
|
||||
this["DbgHelpSearchPath"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool DbgHelpUndecorate {
|
||||
get {
|
||||
return ((bool)(this["DbgHelpUndecorate"]));
|
||||
}
|
||||
set {
|
||||
this["DbgHelpUndecorate"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,5 +308,14 @@
|
||||
<Setting Name="UseColorGuiThreads" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="DbgHelpPath" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">dbghelp.dll</Value>
|
||||
</Setting>
|
||||
<Setting Name="DbgHelpSearchPath" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="DbgHelpUndecorate" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -89,8 +89,6 @@ namespace ProcessHacker
|
||||
|
||||
public class ProcessSystemProvider : Provider<int, ProcessItem>
|
||||
{
|
||||
private const bool CacheFileVerifyResults = false;
|
||||
|
||||
public class FileProcessResult
|
||||
{
|
||||
public int PID;
|
||||
@@ -110,7 +108,7 @@ namespace ProcessHacker
|
||||
private HistoryManager<string, float> _floatHistory = new HistoryManager<string, float>();
|
||||
private HistoryManager<bool, string> _mostUsageHistory = new HistoryManager<bool, string>();
|
||||
|
||||
private delegate void ProcessFileDelegate(int pid, string fileName);
|
||||
private delegate void ProcessFileDelegate(int pid, string fileName, bool useCache);
|
||||
|
||||
public ProcessSystemProvider()
|
||||
: base()
|
||||
@@ -233,7 +231,7 @@ namespace ProcessHacker
|
||||
this.Performance = performance;
|
||||
}
|
||||
|
||||
private void ProcessFile(int pid, string fileName)
|
||||
private void ProcessFile(int pid, string fileName, bool forced)
|
||||
{
|
||||
FileProcessResult fpResult = new FileProcessResult();
|
||||
|
||||
@@ -248,7 +246,7 @@ namespace ProcessHacker
|
||||
// 1. the function-to-library ratio is lower than 4
|
||||
// (on average less than 4 functions are imported from each library)
|
||||
// 2. it references more than 3 libraries but less than 14 libraries.
|
||||
if (fileName != null)
|
||||
if (fileName != null && (Properties.Settings.Default.VerifySignatures || forced))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -294,7 +292,7 @@ namespace ProcessHacker
|
||||
|
||||
try
|
||||
{
|
||||
if (Properties.Settings.Default.VerifySignatures)
|
||||
if (Properties.Settings.Default.VerifySignatures || forced)
|
||||
{
|
||||
if (fileName != null)
|
||||
{
|
||||
@@ -302,7 +300,7 @@ namespace ProcessHacker
|
||||
|
||||
lock (_fileResults)
|
||||
{
|
||||
if (CacheFileVerifyResults && _fileResults.ContainsKey(uniName))
|
||||
if (!forced && _fileResults.ContainsKey(uniName))
|
||||
{
|
||||
fpResult.VerifyResult = _fileResults[uniName];
|
||||
}
|
||||
@@ -317,7 +315,10 @@ namespace ProcessHacker
|
||||
fpResult.VerifyResult = Win32.VerifyResult.NoSignature;
|
||||
}
|
||||
|
||||
//_fileResults.Add(uniName, fpResult.VerifyResult);
|
||||
if (!_fileResults.ContainsKey(uniName))
|
||||
_fileResults.Add(uniName, fpResult.VerifyResult);
|
||||
else
|
||||
_fileResults[uniName] = fpResult.VerifyResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,7 +367,7 @@ namespace ProcessHacker
|
||||
|
||||
public void QueueFileProcessing(int pid)
|
||||
{
|
||||
(new ProcessFileDelegate(this.ProcessFile)).BeginInvoke(pid, this.Dictionary[pid].FileName,
|
||||
(new ProcessFileDelegate(this.ProcessFile)).BeginInvoke(pid, this.Dictionary[pid].FileName, true,
|
||||
r => { }, null);
|
||||
}
|
||||
|
||||
@@ -747,7 +748,7 @@ namespace ProcessHacker
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
(new ProcessFileDelegate(this.ProcessFile)).BeginInvoke(pid, item.FileName,
|
||||
(new ProcessFileDelegate(this.ProcessFile)).BeginInvoke(pid, item.FileName, false,
|
||||
r => { }, null);
|
||||
}
|
||||
|
||||
@@ -866,9 +867,9 @@ namespace ProcessHacker
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
if (item.IsPacked && item.ProcessingAttempts < 5)
|
||||
if (item.IsPacked && item.ProcessingAttempts < 3)
|
||||
{
|
||||
(new ProcessFileDelegate(this.ProcessFile)).BeginInvoke(pid, item.FileName,
|
||||
(new ProcessFileDelegate(this.ProcessFile)).BeginInvoke(pid, item.FileName, true,
|
||||
r => { }, null);
|
||||
item.ProcessingAttempts++;
|
||||
}
|
||||
|
||||
@@ -47,14 +47,23 @@ namespace ProcessHacker
|
||||
public string StartAddress;
|
||||
public Win32.KWAIT_REASON WaitReason;
|
||||
public bool IsGuiThread;
|
||||
public bool JustResolved;
|
||||
|
||||
public Win32.ThreadHandle ThreadQueryLimitedHandle;
|
||||
}
|
||||
|
||||
public class ThreadProvider : Provider<int, ThreadItem>
|
||||
{
|
||||
private SymbolProvider _symbols = new SymbolProvider();
|
||||
public delegate void LoadingStateChangedDelegate(bool loading);
|
||||
private delegate void ResolveThreadStartAddressDelegate(int tid, long startAddress);
|
||||
|
||||
public event LoadingStateChangedDelegate LoadingStateChanged;
|
||||
|
||||
private Win32.ProcessHandle _processHandle;
|
||||
private Symbols _symbols;
|
||||
private int _pid;
|
||||
private int _loading = 0;
|
||||
private Queue<KeyValuePair<int, string>> _resolveResults = new Queue<KeyValuePair<int,string>>();
|
||||
|
||||
public ThreadProvider(int PID)
|
||||
: base()
|
||||
@@ -67,50 +76,67 @@ namespace ProcessHacker
|
||||
this.ProviderUpdate += new ProviderUpdateOnce(UpdateOnce);
|
||||
this.Killed += new MethodInvoker(ThreadProvider_Killed);
|
||||
|
||||
// start loading symbols
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(o =>
|
||||
try
|
||||
{
|
||||
try
|
||||
_processHandle = new Win32.ProcessHandle(_pid, Program.MinProcessQueryRights);
|
||||
_symbols = new Symbols(_processHandle);
|
||||
|
||||
Symbols.Options = Win32.SYMBOL_OPTIONS.DeferredLoads | Win32.SYMBOL_OPTIONS.NoPrompts |
|
||||
(Properties.Settings.Default.DbgHelpUndecorate ? Win32.SYMBOL_OPTIONS.UndName : 0);
|
||||
|
||||
if (Properties.Settings.Default.DbgHelpSearchPath != "")
|
||||
_symbols.SearchPath = Properties.Settings.Default.DbgHelpSearchPath;
|
||||
|
||||
// start loading symbols
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(o =>
|
||||
{
|
||||
if (_pid != 4)
|
||||
try
|
||||
{
|
||||
using (var phandle =
|
||||
new Win32.ProcessHandle(_pid, Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights))
|
||||
if (_pid != 4)
|
||||
{
|
||||
foreach (var module in phandle.GetModules())
|
||||
using (var phandle =
|
||||
new Win32.ProcessHandle(_pid, Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights))
|
||||
{
|
||||
foreach (var module in phandle.GetModules())
|
||||
{
|
||||
try
|
||||
{
|
||||
_symbols.LoadModule(module.FileName, module.BaseAddress.ToInt32(), module.Size);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// load driver symbols
|
||||
foreach (var module in Win32.EnumKernelModules())
|
||||
{
|
||||
try
|
||||
{
|
||||
_symbols.LoadSymbolsFromLibrary(module.FileName, (uint)module.BaseAddress.ToInt32());
|
||||
_symbols.LoadModule(module.FileName, module.BaseAddress);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// load driver symbols
|
||||
foreach (var module in Win32.EnumKernelModules())
|
||||
{
|
||||
try
|
||||
{
|
||||
_symbols.LoadSymbolsFromLibrary(module.FileName, module.BaseAddress);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
Program.CollectGarbage();
|
||||
}));
|
||||
catch
|
||||
{ }
|
||||
}));
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
private void ThreadProvider_Killed()
|
||||
{
|
||||
if (_symbols != null)
|
||||
_symbols.Dispose();
|
||||
if (_processHandle != null)
|
||||
_processHandle.Dispose();
|
||||
|
||||
if (Win32.ProcessesWithThreads.ContainsKey(_pid))
|
||||
Win32.ProcessesWithThreads.Remove(_pid);
|
||||
|
||||
@@ -123,6 +149,36 @@ namespace ProcessHacker
|
||||
}
|
||||
}
|
||||
|
||||
private void ResolveThreadStartAddress(int tid, long startAddress)
|
||||
{
|
||||
string name = null;
|
||||
|
||||
try
|
||||
{
|
||||
_loading++;
|
||||
|
||||
if (this.LoadingStateChanged != null)
|
||||
this.LoadingStateChanged(_loading > 0);
|
||||
|
||||
try
|
||||
{
|
||||
name = _symbols.GetSymbolFromAddress(startAddress);
|
||||
|
||||
lock (_resolveResults)
|
||||
_resolveResults.Enqueue(new KeyValuePair<int, string>(tid, name));
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
finally
|
||||
{
|
||||
_loading--;
|
||||
|
||||
if (this.LoadingStateChanged != null)
|
||||
this.LoadingStateChanged(_loading > 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateOnce()
|
||||
{
|
||||
Dictionary<int, Win32.SYSTEM_THREAD_INFORMATION> threads =
|
||||
@@ -147,6 +203,20 @@ namespace ProcessHacker
|
||||
}
|
||||
}
|
||||
|
||||
lock (_resolveResults)
|
||||
{
|
||||
while (_resolveResults.Count > 0)
|
||||
{
|
||||
var result = _resolveResults.Dequeue();
|
||||
|
||||
if (result.Value != null)
|
||||
{
|
||||
this.Dictionary[result.Key].StartAddress = result.Value;
|
||||
this.Dictionary[result.Key].JustResolved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look for new threads
|
||||
foreach (int tid in threads.Keys)
|
||||
{
|
||||
@@ -223,11 +293,21 @@ namespace ProcessHacker
|
||||
|
||||
try
|
||||
{
|
||||
item.StartAddress = _symbols.GetNameFromAddress(item.StartAddressI);
|
||||
long modBase;
|
||||
string fileName = _symbols.GetModuleFromAddress(item.StartAddressI, out modBase);
|
||||
|
||||
if (fileName == null)
|
||||
item.StartAddress = "0x" + item.StartAddressI.ToString("x");
|
||||
else
|
||||
item.StartAddress = (new System.IO.FileInfo(fileName)).Name + "+0x" +
|
||||
(item.StartAddressI - modBase).ToString("x");
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
(new ResolveThreadStartAddressDelegate(this.ResolveThreadStartAddress)).BeginInvoke(
|
||||
tid, item.StartAddressI, r => { }, null);
|
||||
|
||||
newdictionary.Add(tid, item);
|
||||
this.CallDictionaryAdded(item);
|
||||
}
|
||||
@@ -237,6 +317,7 @@ namespace ProcessHacker
|
||||
ThreadItem item = Dictionary[tid];
|
||||
ThreadItem newitem = item.Clone() as ThreadItem;
|
||||
|
||||
newitem.JustResolved = false;
|
||||
newitem.ContextSwitchesDelta = t.ContextSwitchCount - newitem.ContextSwitches;
|
||||
newitem.ContextSwitches = t.ContextSwitchCount;
|
||||
newitem.WaitReason = t.WaitReason;
|
||||
@@ -271,18 +352,7 @@ namespace ProcessHacker
|
||||
{ }
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SymbolProvider.FoundLevel level;
|
||||
|
||||
string symName = _symbols.GetNameFromAddress(newitem.StartAddressI, out level);
|
||||
|
||||
if (level != SymbolProvider.FoundLevel.Address)
|
||||
newitem.StartAddress = symName;
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (
|
||||
if (
|
||||
newitem.ContextSwitches != item.ContextSwitches ||
|
||||
newitem.ContextSwitchesDelta != item.ContextSwitchesDelta ||
|
||||
newitem.Cycles != item.Cycles ||
|
||||
@@ -290,7 +360,8 @@ namespace ProcessHacker
|
||||
newitem.IsGuiThread != item.IsGuiThread ||
|
||||
newitem.Priority != item.Priority ||
|
||||
newitem.StartAddress != item.StartAddress ||
|
||||
newitem.WaitReason != item.WaitReason
|
||||
newitem.WaitReason != item.WaitReason ||
|
||||
item.JustResolved
|
||||
)
|
||||
{
|
||||
newdictionary[tid] = newitem;
|
||||
@@ -302,7 +373,7 @@ namespace ProcessHacker
|
||||
Dictionary = newdictionary;
|
||||
}
|
||||
|
||||
public SymbolProvider Symbols
|
||||
public Symbols Symbols
|
||||
{
|
||||
get { return _symbols; }
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
public class Singleton<T>
|
||||
where T : class, new()
|
||||
{
|
||||
private object _instanceLock = new object();
|
||||
private T _instance = null;
|
||||
private static object _instanceLock = new object();
|
||||
private static T _instance = null;
|
||||
|
||||
/// <summary>
|
||||
/// The single instance of the type.
|
||||
/// </summary>
|
||||
public T Instance
|
||||
public static T Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
/*
|
||||
* Process Hacker -
|
||||
* symbol server
|
||||
*
|
||||
* Copyright (C) 2008-2009 wj32
|
||||
*
|
||||
* This file is part of Process Hacker.
|
||||
*
|
||||
* Process Hacker is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Process Hacker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using ProcessHacker.PE;
|
||||
|
||||
namespace ProcessHacker
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides services for retrieving symbol information.
|
||||
/// </summary>
|
||||
public class SymbolProvider
|
||||
{
|
||||
public static SymbolProvider BaseInstance { get; private set; }
|
||||
|
||||
static SymbolProvider()
|
||||
{
|
||||
SymbolProvider.BaseInstance = new SymbolProvider();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the detail with which the address's name was resolved.
|
||||
/// </summary>
|
||||
public enum FoundLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the address was resolved to a module, a function and possibly an offset.
|
||||
/// For example: mymodule.dll!MyExportedFunction+0x123
|
||||
/// </summary>
|
||||
Function,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the address was resolved to a module and an offset.
|
||||
/// For example: mymodule.dll+0x4321
|
||||
/// </summary>
|
||||
Module,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the address was not resolved.
|
||||
/// For example: 0x12345678
|
||||
/// </summary>
|
||||
Address,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the address was invalid (for example, 0x0).
|
||||
/// </summary>
|
||||
Invalid
|
||||
}
|
||||
|
||||
private List<KeyValuePair<uint, string>> _libraryLookup;
|
||||
private Dictionary<string, List<KeyValuePair<uint, string>>> _symbols;
|
||||
private Dictionary<string, uint> _librarySizes;
|
||||
|
||||
public SymbolProvider()
|
||||
{
|
||||
if (SymbolProvider.BaseInstance != null)
|
||||
{
|
||||
_libraryLookup = new List<KeyValuePair<uint, string>>(SymbolProvider.BaseInstance._libraryLookup);
|
||||
_symbols = new Dictionary<string, List<KeyValuePair<uint, string>>>(SymbolProvider.BaseInstance._symbols);
|
||||
_librarySizes = new Dictionary<string, uint>(SymbolProvider.BaseInstance._librarySizes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_libraryLookup = new List<KeyValuePair<uint, string>>();
|
||||
_symbols = new Dictionary<string, List<KeyValuePair<uint, string>>>();
|
||||
_librarySizes = new Dictionary<string, uint>();
|
||||
}
|
||||
}
|
||||
|
||||
//public void LoadSymbolsFromLibrary(string path)
|
||||
//{
|
||||
// LoadSymbolsFromLibrary(path, Process.GetCurrentProcess().Modules);
|
||||
//}
|
||||
|
||||
//public void LoadSymbolsFromLibrary(string path, ProcessModuleCollection modules)
|
||||
//{
|
||||
// string realPath = Misc.GetRealPath(path).ToLower();
|
||||
// uint imageBase = 0;
|
||||
|
||||
// foreach (ProcessModule module in modules)
|
||||
// {
|
||||
// string thisPath = Misc.GetRealPath(module.FileName).ToLower();
|
||||
|
||||
// if (thisPath == realPath)
|
||||
// {
|
||||
// imageBase = (uint)module.BaseAddress.ToInt32();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (imageBase == 0)
|
||||
// throw new Exception("Could not get image base of library.");
|
||||
|
||||
// LoadSymbolsFromLibrary(path, imageBase);
|
||||
//}
|
||||
|
||||
public void LoadSymbolsFromLibrary(string path, uint imageBase)
|
||||
{
|
||||
string realPath = Misc.GetRealPath(path).ToLower();
|
||||
|
||||
// check if it is already loaded
|
||||
if (_symbols.ContainsKey(realPath))
|
||||
return;
|
||||
|
||||
PEFile file = null;
|
||||
List<KeyValuePair<uint, string>> list = new List<KeyValuePair<uint, string>>();
|
||||
|
||||
try
|
||||
{
|
||||
file = new PEFile(realPath);
|
||||
|
||||
uint size = 0;
|
||||
|
||||
foreach (SectionHeader sh in file.Sections)
|
||||
size += sh.VirtualSize;
|
||||
|
||||
_librarySizes.Add(realPath, size);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
if (file == null || file.ExportData == null)
|
||||
{
|
||||
// no symbols (or error), but we can still display a module name in a lookup
|
||||
_libraryLookup.Add(new KeyValuePair<uint, string>(imageBase, realPath));
|
||||
_symbols.Add(realPath, new List<KeyValuePair<uint, string>>());
|
||||
|
||||
// if we didn't even get to load the PE file
|
||||
if (!_librarySizes.ContainsKey(realPath))
|
||||
_librarySizes.Add(realPath, 0xffffffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < file.ExportData.ExportOrdinalTable.Count; i++)
|
||||
{
|
||||
ushort ordinal = file.ExportData.ExportOrdinalTable[i];
|
||||
|
||||
if (ordinal >= file.ExportData.ExportAddressTable.Count)
|
||||
continue;
|
||||
|
||||
uint address = file.ExportData.ExportAddressTable[ordinal].ExportRVA;
|
||||
|
||||
string name;
|
||||
|
||||
if (i < file.ExportData.ExportNameTable.Count)
|
||||
name = file.ExportData.ExportNameTable[i];
|
||||
else
|
||||
name = ordinal.ToString();
|
||||
|
||||
list.Add(new KeyValuePair<uint, string>(imageBase + address, name));
|
||||
}
|
||||
|
||||
_libraryLookup.Add(new KeyValuePair<uint, string>(imageBase, realPath));
|
||||
_symbols.Add(realPath, list);
|
||||
}
|
||||
|
||||
// sort the list
|
||||
list.Sort(new Comparison<KeyValuePair<uint, string>>(
|
||||
delegate(KeyValuePair<uint, string> kvp1, KeyValuePair<uint, string> kvp2)
|
||||
{
|
||||
return (kvp2.Key).CompareTo(kvp1.Key);
|
||||
}));
|
||||
|
||||
_libraryLookup.Sort(new Comparison<KeyValuePair<uint, string>>(
|
||||
delegate(KeyValuePair<uint, string> kvp1, KeyValuePair<uint, string> kvp2)
|
||||
{
|
||||
return (kvp2.Key).CompareTo(kvp1.Key);
|
||||
}));
|
||||
}
|
||||
|
||||
public void UnloadSymbols(string path)
|
||||
{
|
||||
foreach (var kvp in _libraryLookup)
|
||||
{
|
||||
if (kvp.Value == path)
|
||||
{
|
||||
_libraryLookup.Remove(kvp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_librarySizes.Remove(path);
|
||||
_symbols.Remove(path);
|
||||
}
|
||||
|
||||
public string GetModuleFromAddress(uint address)
|
||||
{
|
||||
foreach (var kvp in _libraryLookup)
|
||||
{
|
||||
if (address >= kvp.Key)
|
||||
{
|
||||
var symbolList = _symbols[kvp.Value];
|
||||
FileInfo fi = new FileInfo(kvp.Value);
|
||||
|
||||
return fi.FullName;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public string GetNameFromAddress(uint address)
|
||||
{
|
||||
FoundLevel level;
|
||||
|
||||
return GetNameFromAddress(address, out level);
|
||||
}
|
||||
|
||||
public string GetNameFromAddress(uint address, out FoundLevel level)
|
||||
{
|
||||
if (address == 0)
|
||||
{
|
||||
level = FoundLevel.Invalid;
|
||||
return "0x0";
|
||||
}
|
||||
|
||||
// go through each loaded library
|
||||
foreach (var kvp in _libraryLookup)
|
||||
{
|
||||
uint size = _librarySizes[kvp.Value];
|
||||
|
||||
//if ((uint)address >= (uint)kvp.Key && (uint)address < ((uint)kvp.Key + size))
|
||||
if (address >= kvp.Key)
|
||||
{
|
||||
var symbolList = _symbols[kvp.Value];
|
||||
FileInfo fi = new FileInfo(kvp.Value);
|
||||
|
||||
// go through each symbol
|
||||
foreach (var kvps in symbolList)
|
||||
{
|
||||
if (address >= kvps.Key)
|
||||
{
|
||||
// we found a function name
|
||||
uint offset = address - kvps.Key;
|
||||
|
||||
level = FoundLevel.Function;
|
||||
|
||||
// don't need to put in the +
|
||||
if (offset == 0)
|
||||
return string.Format("{0}!{1}", fi.Name, kvps.Value);
|
||||
else
|
||||
return string.Format("{0}!{1}+0x{2:x}",
|
||||
fi.Name, kvps.Value, address - kvps.Key);
|
||||
}
|
||||
}
|
||||
|
||||
// no function name found, but we have a library name
|
||||
level = FoundLevel.Module;
|
||||
return string.Format("{0}+0x{1:x}", fi.Name, address - kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
// we didn't find anything
|
||||
level = FoundLevel.Address;
|
||||
return "0x" + address.ToString("x8");
|
||||
}
|
||||
|
||||
public int LibraryCount
|
||||
{
|
||||
get { return _libraryLookup.Count; }
|
||||
}
|
||||
|
||||
public int SymbolCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (var list in _symbols.Values)
|
||||
count += list.Count;
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
return _symbols.Keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Process Hacker -
|
||||
* dbghelp.dll wrapper code
|
||||
*
|
||||
* Copyright (C) 2009 wj32
|
||||
*
|
||||
* This file is part of Process Hacker.
|
||||
*
|
||||
* Process Hacker is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Process Hacker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace ProcessHacker
|
||||
{
|
||||
public class Symbols : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the detail with which the address's name was resolved.
|
||||
/// </summary>
|
||||
public enum FoundLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the address was resolved to a module, a function and possibly an offset.
|
||||
/// For example: mymodule.dll!MyExportedFunction+0x123
|
||||
/// </summary>
|
||||
Function,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the address was resolved to a module and an offset.
|
||||
/// For example: mymodule.dll+0x4321
|
||||
/// </summary>
|
||||
Module,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the address was not resolved.
|
||||
/// For example: 0x12345678
|
||||
/// </summary>
|
||||
Address,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the address was invalid (for example, 0x0).
|
||||
/// </summary>
|
||||
Invalid
|
||||
}
|
||||
|
||||
private static object _callLock = new object();
|
||||
private static IdGenerator _idGen = new IdGenerator();
|
||||
|
||||
public static Win32.SYMBOL_OPTIONS Options
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_callLock)
|
||||
return Win32.SymGetOptions();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
lock (_callLock)
|
||||
Win32.SymSetOptions(value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _disposed = false;
|
||||
private object _disposeLock = new object();
|
||||
private Win32.ProcessHandle _processHandle;
|
||||
private int _handle;
|
||||
private List<KeyValuePair<long, string>> _modules = new List<KeyValuePair<long, string>>();
|
||||
|
||||
public Symbols()
|
||||
{
|
||||
_handle = _idGen.Pop();
|
||||
|
||||
lock (_callLock)
|
||||
{
|
||||
if (!Win32.SymInitialize(_handle, null, false))
|
||||
Win32.ThrowLastWin32Error();
|
||||
}
|
||||
}
|
||||
|
||||
public Symbols(Win32.ProcessHandle processHandle)
|
||||
{
|
||||
_processHandle = processHandle;
|
||||
_handle = processHandle;
|
||||
|
||||
lock (_callLock)
|
||||
{
|
||||
if (!Win32.SymInitialize(_handle, null, false))
|
||||
Win32.ThrowLastWin32Error();
|
||||
}
|
||||
}
|
||||
|
||||
public int Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
public string SearchPath
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var data = new MemoryAlloc(0x1000))
|
||||
{
|
||||
lock (_callLock)
|
||||
{
|
||||
if (!Win32.SymGetSearchPath(_handle, data, data.Size))
|
||||
return "";
|
||||
}
|
||||
|
||||
return Marshal.PtrToStringAnsi(data);
|
||||
}
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
lock (_callLock)
|
||||
Win32.SymSetSearchPath(_handle, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadModule(string fileName, long baseAddress)
|
||||
{
|
||||
this.LoadModule(fileName, baseAddress, 0);
|
||||
}
|
||||
|
||||
public void LoadModule(string fileName, long baseAddress, int size)
|
||||
{
|
||||
lock (_callLock)
|
||||
{
|
||||
if (Win32.SymLoadModule64(_handle, 0, fileName, null, baseAddress, size) == 0)
|
||||
Win32.ThrowLastWin32Error();
|
||||
}
|
||||
|
||||
lock (_modules)
|
||||
{
|
||||
_modules.Add(new KeyValuePair<long, string>(baseAddress, fileName));
|
||||
_modules.Sort(new Comparison<KeyValuePair<long, string>>(
|
||||
(kvp1, kvp2) => kvp2.Key.CompareTo(kvp1.Key)));
|
||||
}
|
||||
}
|
||||
|
||||
public string GetModuleFromAddress(long address, out long baseAddress)
|
||||
{
|
||||
lock (_modules)
|
||||
{
|
||||
foreach (var kvp in _modules)
|
||||
{
|
||||
if (address >= kvp.Key)
|
||||
{
|
||||
baseAddress = kvp.Key;
|
||||
return kvp.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
baseAddress = 0;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetSymbolFromAddress(long address)
|
||||
{
|
||||
Win32.SYMBOL_FLAGS flags;
|
||||
|
||||
return this.GetSymbolFromAddress(address, out flags);
|
||||
}
|
||||
|
||||
public string GetSymbolFromAddress(long address, out FoundLevel level)
|
||||
{
|
||||
Win32.SYMBOL_FLAGS flags;
|
||||
string fileName;
|
||||
|
||||
return this.GetSymbolFromAddress(address, out level, out flags, out fileName);
|
||||
}
|
||||
|
||||
public string GetSymbolFromAddress(long address, out Win32.SYMBOL_FLAGS flags)
|
||||
{
|
||||
FoundLevel level;
|
||||
string fileName;
|
||||
|
||||
return this.GetSymbolFromAddress(address, out level, out flags, out fileName);
|
||||
}
|
||||
|
||||
public string GetSymbolFromAddress(long address, out string fileName)
|
||||
{
|
||||
FoundLevel level;
|
||||
Win32.SYMBOL_FLAGS flags;
|
||||
|
||||
return this.GetSymbolFromAddress(address, out level, out flags, out fileName);
|
||||
}
|
||||
|
||||
public string GetSymbolFromAddress(long address, out FoundLevel level, out Win32.SYMBOL_FLAGS flags, out string fileName)
|
||||
{
|
||||
const int maxNameLen = 0x400;
|
||||
long displacement;
|
||||
|
||||
if (address == 0)
|
||||
{
|
||||
level = FoundLevel.Invalid;
|
||||
flags = 0;
|
||||
fileName = null;
|
||||
}
|
||||
|
||||
using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(Win32.SYMBOL_INFO)) + maxNameLen))
|
||||
{
|
||||
Win32.SYMBOL_INFO info = new Win32.SYMBOL_INFO();
|
||||
|
||||
info.SizeOfStruct = Marshal.SizeOf(info);
|
||||
info.MaxNameLen = maxNameLen - 1;
|
||||
|
||||
Marshal.StructureToPtr(info, data, false);
|
||||
|
||||
lock (_callLock)
|
||||
{
|
||||
if (Win32.SymFromAddr(_handle, address, out displacement, data))
|
||||
{
|
||||
info = data.ReadStruct<Win32.SYMBOL_INFO>();
|
||||
}
|
||||
}
|
||||
|
||||
string modFileName;
|
||||
long modBase;
|
||||
|
||||
if (info.ModBase == 0)
|
||||
{
|
||||
modFileName = this.GetModuleFromAddress(address, out modBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
modBase = info.ModBase;
|
||||
modFileName = _modules.Find(
|
||||
new Predicate<KeyValuePair<long,string>>(kvp => kvp.Key == info.ModBase)).Value;
|
||||
}
|
||||
|
||||
if (modFileName == null)
|
||||
{
|
||||
level = FoundLevel.Address;
|
||||
flags = 0;
|
||||
fileName = null;
|
||||
|
||||
return "0x" + address.ToString("x8");
|
||||
}
|
||||
|
||||
System.IO.FileInfo fi = new System.IO.FileInfo(modFileName);
|
||||
|
||||
fileName = fi.FullName;
|
||||
|
||||
if (info.NameLen == 0)
|
||||
{
|
||||
level = FoundLevel.Module;
|
||||
flags = 0;
|
||||
|
||||
return fi.Name + "+0x" + (address - modBase).ToString("x");
|
||||
}
|
||||
|
||||
string name = Marshal.PtrToStringAnsi(
|
||||
new IntPtr(data + Marshal.OffsetOf(typeof(Win32.SYMBOL_INFO), "Name").ToInt32()), info.NameLen);
|
||||
|
||||
level = FoundLevel.Function;
|
||||
flags = info.Flags;
|
||||
|
||||
if (displacement == 0)
|
||||
return fi.Name + "!" + name;
|
||||
else
|
||||
return fi.Name + "!" + name + "+0x" + displacement.ToString("x");
|
||||
}
|
||||
}
|
||||
|
||||
~Symbols()
|
||||
{
|
||||
this.Dispose(false);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Monitor.Enter(_disposeLock);
|
||||
Monitor.Enter(_callLock);
|
||||
}
|
||||
|
||||
if (!_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
Win32.SymCleanup(_handle);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Monitor.Exit(_callLock);
|
||||
Monitor.Exit(_disposeLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -871,6 +871,37 @@ namespace ProcessHacker
|
||||
SYMFLAG_VIRTUAL = 0x00001000
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SYMBOL_OPTIONS : uint
|
||||
{
|
||||
AllowAbsoluteSymbols = 0x00000800,
|
||||
AllowZeroAddress = 0x01000000,
|
||||
AutoPublics = 0x00010000,
|
||||
CaseInsensitive = 0x00000001,
|
||||
Debug = 0x80000000,
|
||||
DeferredLoads = 0x00000004,
|
||||
DisableSymSrvAutodetect = 0x02000000,
|
||||
ExactSymbols = 0x00000400,
|
||||
FailCriticalErrors = 0x00000200,
|
||||
FavorCompressed = 0x00800000,
|
||||
FlatDirectory = 0x00400000,
|
||||
IgnoreCvRec = 0x00000080,
|
||||
IgnoreImageDir = 0x00200000,
|
||||
IgnoreNtSymPath = 0x00001000,
|
||||
Include32BitModules = 0x00002000,
|
||||
LoadAnything = 0x00000040,
|
||||
LoadLines = 0x00000010,
|
||||
NoCpp = 0x00000008,
|
||||
NoImageSearch = 0x00020000,
|
||||
NoPrompts = 0x00080000,
|
||||
NoPublics = 0x00008000,
|
||||
NoUnqualifiedLoads = 0x00000100,
|
||||
Overwrite = 0x00100000,
|
||||
PublicsOnly = 0x00004000,
|
||||
Secure = 0x00040000,
|
||||
UndName = 0x00000002
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SYNC_RIGHTS : int
|
||||
{
|
||||
|
||||
@@ -713,40 +713,74 @@ namespace ProcessHacker
|
||||
|
||||
#region Symbols/Stack Walking
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymCleanup(int ProcessHandle);
|
||||
[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Ansi)]
|
||||
public static extern bool SymInitialize(int ProcessHandle, string UserSearchPath, bool InvadeProcess);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymEnumSymbols(int ProcessHandle, int BaseOfDll, int Mask,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)] SymEnumSymbolsProc EnumSymbolsCallback, int UserContext);
|
||||
public static extern bool SymCleanup(int ProcessHandle);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymEnumSymbols(int ProcessHandle, int BaseOfDll, string Mask,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)] SymEnumSymbolsProc EnumSymbolsCallback, int UserContext);
|
||||
public static extern SYMBOL_OPTIONS SymGetOptions();
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymFromAddr(int ProcessHandle, long Address, ref long Displacement, ref SYMBOL_INFO Symbol);
|
||||
public static extern SYMBOL_OPTIONS SymSetOptions(SYMBOL_OPTIONS SymOptions);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Ansi)]
|
||||
public static extern bool SymGetSearchPath(int ProcessHandle, IntPtr SearchPath, int SearchPathLength);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Ansi)]
|
||||
public static extern bool SymSetSearchPath(int ProcessHandle, string SearchPath);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Ansi)]
|
||||
public static extern long SymLoadModule64(
|
||||
int ProcessHandle,
|
||||
int FileHandle,
|
||||
string ImageName,
|
||||
string ModuleName,
|
||||
long BaseOfDll,
|
||||
int SizeOfDll
|
||||
);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymFromIndex(int ProcessHandle, int BaseOfDll, int Index, ref SYMBOL_INFO Symbol);
|
||||
public static extern int SymFunctionTableAccess64(int ProcessHandle, long AddrBase);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymFunctionTableAccess64(int ProcessHandle, int AddrBase);
|
||||
public static extern long SymGetModuleBase64(int ProcessHandle, long Address);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymGetModuleBase64(int ProcessHandle, int dwAddr);
|
||||
public static extern int SymEnumSymbols(
|
||||
int ProcessHandle,
|
||||
int BaseOfDll,
|
||||
string Mask,
|
||||
SymEnumSymbolsProc EnumSymbolsCallback, int UserContext);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern int SymInitialize(int ProcessHandle, int UserSearchPath, int InvadeProcess);
|
||||
public static extern bool SymFromAddr(
|
||||
int ProcessHandle,
|
||||
long Address,
|
||||
out long Displacement,
|
||||
IntPtr Symbol);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern bool StackWalk64(MachineType MachineType, int ProcessHandle, int ThreadHandle,
|
||||
[MarshalAs(UnmanagedType.Struct)] ref STACKFRAME64 StackFrame,
|
||||
[MarshalAs(UnmanagedType.Struct)] ref CONTEXT ContextRecord,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)] ReadProcessMemoryProc64 ReadMemoryRoutine,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)] FunctionTableAccessProc64 FunctionTableAccessRoutine,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)] GetModuleBaseProc64 GetModuleBaseRoutine,
|
||||
int TranslateAddress);
|
||||
public static extern bool SymFromIndex(
|
||||
int ProcessHandle,
|
||||
int BaseOfDll,
|
||||
int Index,
|
||||
IntPtr Symbol
|
||||
);
|
||||
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
public static extern bool StackWalk64(
|
||||
MachineType MachineType,
|
||||
int ProcessHandle,
|
||||
int ThreadHandle,
|
||||
ref STACKFRAME64 StackFrame,
|
||||
ref CONTEXT ContextRecord,
|
||||
ReadProcessMemoryProc64 ReadMemoryRoutine,
|
||||
FunctionTableAccessProc64 FunctionTableAccessRoutine,
|
||||
GetModuleBaseProc64 GetModuleBaseRoutine,
|
||||
int TranslateAddress
|
||||
);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -841,10 +841,7 @@ namespace ProcessHacker
|
||||
{
|
||||
public int SizeOfStruct;
|
||||
public int TypeIndex;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public long[] Reserved;
|
||||
|
||||
public unsafe fixed long Reserved[2];
|
||||
public int Index;
|
||||
public int Size;
|
||||
public long ModBase;
|
||||
@@ -856,9 +853,7 @@ namespace ProcessHacker
|
||||
public int Tag;
|
||||
public int NameLen;
|
||||
public int MaxNameLen;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = SYMBOL_NAME_MAXSIZE)]
|
||||
public string Name;
|
||||
public char Name;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
||||
@@ -109,11 +109,12 @@ namespace ProcessHacker
|
||||
public delegate bool EnumChildProc(IntPtr hWnd, int param);
|
||||
public delegate bool EnumThreadWndProc(IntPtr hWnd, int param);
|
||||
public delegate IntPtr WndProcDelegate(IntPtr hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam);
|
||||
public delegate int SymEnumSymbolsProc(SYMBOL_INFO pSymInfo, int SymbolSize, int UserContext);
|
||||
|
||||
public delegate int SymEnumSymbolsProc(IntPtr pSymInfo, int SymbolSize, int UserContext);
|
||||
public delegate bool ReadProcessMemoryProc64(int ProcessHandle, ulong BaseAddress, byte[] Buffer,
|
||||
int Size, out int BytesRead);
|
||||
public delegate int FunctionTableAccessProc64(int ProcessHandle, long AddrBase);
|
||||
public delegate int GetModuleBaseProc64(int ProcessHandle, long Address);
|
||||
public delegate long GetModuleBaseProc64(int ProcessHandle, long Address);
|
||||
|
||||
/// <summary>
|
||||
/// A cache for type names; QuerySystemInformation with ALL_TYPES_INFORMATION fails for some
|
||||
@@ -140,7 +141,6 @@ namespace ProcessHacker
|
||||
public const int SID_SIZE = 0x1000;
|
||||
public const int SIZE_OF_80387_REGISTERS = 72;
|
||||
public const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004;
|
||||
public const int SYMBOL_NAME_MAXSIZE = 255;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -313,6 +313,15 @@
|
||||
<setting name="UseColorGuiThreads" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="DbgHelpPath" serializeAs="String">
|
||||
<value>dbghelp.dll</value>
|
||||
</setting>
|
||||
<setting name="DbgHelpSearchPath" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="DbgHelpUndecorate" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
</ProcessHacker.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user