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:
wj32
2009-04-12 10:53:57 +00:00
parent ce60e5149c
commit 4fa98825df
21 changed files with 809 additions and 579 deletions
+1
View File
@@ -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
+33 -17
View File
@@ -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
{ }
+7 -35
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+8 -19
View File
@@ -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
+1 -1
View File
@@ -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" />
-67
View File
@@ -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
View File
@@ -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++;
}
+114 -43
View File
@@ -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; }
}
+3 -3
View File
@@ -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;
}
}
}
}
+322
View File
@@ -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);
}
}
}
+31
View File
@@ -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
{
+52 -18
View File
@@ -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
+2 -7
View File
@@ -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)]
+3 -3
View File
@@ -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
+9
View File
@@ -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>