From af15d2caf2c20eafacb8a074d3ba1e9c24ea9651 Mon Sep 17 00:00:00 2001 From: wj32 Date: Sat, 22 Aug 2009 05:18:27 +0000 Subject: [PATCH] * vastly improved kernel module information * added KTM resource manager object information git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1731 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- trunk/CHANGELOG.txt | 3 + .../ProcessHacker.Common.csproj | 1 + .../Threading/FastResourceLock.cs | 99 ++++++++ .../Debugging/ModuleInformation.cs | 13 +- trunk/ProcessHacker.Native/ILoadedModule.cs | 16 ++ .../Objects/ProcessHandle.cs | 2 +- .../ProcessHacker.Native.csproj | 1 + trunk/ProcessHacker.Native/Windows.cs | 138 +++++------ trunk/ProcessHacker/Components/HandleList.cs | 7 + trunk/ProcessHacker/Components/ModuleList.cs | 2 +- .../Components/TmRmProperties.Designer.cs | 101 +++++++++ .../Components/TmRmProperties.cs | 40 ++++ .../Components/TmRmProperties.resx | 120 ++++++++++ trunk/ProcessHacker/ProcessHacker.csproj | 9 + .../ProcessHacker/Providers/ModuleProvider.cs | 214 +++++++----------- .../Symbols/SymbolProviderExtensions.cs | 2 +- 16 files changed, 554 insertions(+), 214 deletions(-) create mode 100644 trunk/ProcessHacker.Common/Threading/FastResourceLock.cs create mode 100644 trunk/ProcessHacker.Native/ILoadedModule.cs create mode 100644 trunk/ProcessHacker/Components/TmRmProperties.Designer.cs create mode 100644 trunk/ProcessHacker/Components/TmRmProperties.cs create mode 100644 trunk/ProcessHacker/Components/TmRmProperties.resx diff --git a/trunk/CHANGELOG.txt b/trunk/CHANGELOG.txt index 24960540a..dddfa88f7 100644 --- a/trunk/CHANGELOG.txt +++ b/trunk/CHANGELOG.txt @@ -2,6 +2,9 @@ Process Hacker 1.5 * NEW/IMPROVED: + * Improved kernel modules list + * Detects custom kernels + * KTM resource manager information * FIXED: * Windows XP BSODs * Linked token display on x64 diff --git a/trunk/ProcessHacker.Common/ProcessHacker.Common.csproj b/trunk/ProcessHacker.Common/ProcessHacker.Common.csproj index 8866cb027..ddaebb500 100644 --- a/trunk/ProcessHacker.Common/ProcessHacker.Common.csproj +++ b/trunk/ProcessHacker.Common/ProcessHacker.Common.csproj @@ -71,6 +71,7 @@ + diff --git a/trunk/ProcessHacker.Common/Threading/FastResourceLock.cs b/trunk/ProcessHacker.Common/Threading/FastResourceLock.cs new file mode 100644 index 000000000..f84ce94ba --- /dev/null +++ b/trunk/ProcessHacker.Common/Threading/FastResourceLock.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ProcessHacker.Common.Threading +{ + public unsafe class FastResourceLock + { + // Indicates that the lock is held. + private const int _locked = 0x1; + // Indicates that there are chained waiters. + private const int _waiters = 0x2; + // Flags mask. + private const int _flags = 0x3; + + private int _spinCount; + private void* _value; + + public struct FastResourceLockContext : IDisposable + { + private bool _disposed; + private FastResourceLock _lock; + private bool _shared; + + internal FastResourceLockContext(FastResourceLock loc, bool shared) + { + _disposed = false; + _lock = loc; + _shared = shared; + } + + public void Dispose() + { + if (!_disposed) + { + if (_shared) + _lock.ReleaseShared(); + else + _lock.ReleaseExclusive(); + + _disposed = true; + } + } + } + + public struct FastResourceWaitBlock + { + public FastResourceWaitBlock* Previous; + public FastResourceWaitBlock* Next; + public FastResourceWaitBlock* Last; + + public int SharedCount; + + public IntPtr WakeEventHandle; + } + + public FastResourceLock() + { + _value = null; + + if (Environment.ProcessorCount == 1) + _spinCount = 0; + else + _spinCount = 1024; + } + + public void AcquireExclusive() + { + + } + + public FastResourceLockContext AcquireExclusiveContext() + { + this.AcquireExclusive(); + return new FastResourceLockContext(this, false); + } + + public void AcquireShared() + { + + } + + public FastResourceLockContext AcquireSharedContext() + { + this.AcquireShared(); + return new FastResourceLockContext(this, true); + } + + public void ReleaseExclusive() + { + + } + + public void ReleaseShared() + { + + } + } +} diff --git a/trunk/ProcessHacker.Native/Debugging/ModuleInformation.cs b/trunk/ProcessHacker.Native/Debugging/ModuleInformation.cs index 571677db7..0beb03f84 100644 --- a/trunk/ProcessHacker.Native/Debugging/ModuleInformation.cs +++ b/trunk/ProcessHacker.Native/Debugging/ModuleInformation.cs @@ -25,12 +25,12 @@ using ProcessHacker.Native.Api; namespace ProcessHacker.Native.Debugging { - public class ModuleInformation + public class ModuleInformation : ILoadedModule { internal ModuleInformation(RtlProcessModuleInformation moduleInfo) { - this.ImageBase = moduleInfo.ImageBase; - this.ImageSize = moduleInfo.ImageSize; + this.BaseAddress = moduleInfo.ImageBase; + this.Size = moduleInfo.ImageSize; this.Flags = moduleInfo.Flags; this.LoadCount = moduleInfo.LoadCount; @@ -40,12 +40,15 @@ namespace ProcessHacker.Native.Debugging this.FileName = new string(moduleInfo.FullPathName, 0, nullIndex); else this.FileName = new string(moduleInfo.FullPathName); + + this.BaseName = this.FileName.Substring(moduleInfo.OffsetToFileName); } - public IntPtr ImageBase { get; private set; } - public int ImageSize { get; private set; } + public IntPtr BaseAddress { get; private set; } + public int Size { get; private set; } public LdrpDataTableEntryFlags Flags { get; private set; } public ushort LoadCount { get; private set; } + public string BaseName { get; private set; } public string FileName { get; private set; } } } diff --git a/trunk/ProcessHacker.Native/ILoadedModule.cs b/trunk/ProcessHacker.Native/ILoadedModule.cs new file mode 100644 index 000000000..5dd450ca2 --- /dev/null +++ b/trunk/ProcessHacker.Native/ILoadedModule.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ProcessHacker.Native.Api; + +namespace ProcessHacker.Native +{ + public interface ILoadedModule + { + IntPtr BaseAddress { get; } + int Size { get; } + LdrpDataTableEntryFlags Flags { get; } + string BaseName { get; } + string FileName { get; } + } +} diff --git a/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs b/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs index 4d3d398bc..bc5ed841d 100644 --- a/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs +++ b/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs @@ -2396,7 +2396,7 @@ namespace ProcessHacker.Native.Objects /// /// Represents a module loaded by a process. /// - public class ProcessModule + public class ProcessModule : ILoadedModule { public ProcessModule( IntPtr baseAddress, diff --git a/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj b/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj index fae22273d..086779f9d 100644 --- a/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj +++ b/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj @@ -62,6 +62,7 @@ + diff --git a/trunk/ProcessHacker.Native/Windows.cs b/trunk/ProcessHacker.Native/Windows.cs index 40b22cf93..ef7e933e7 100644 --- a/trunk/ProcessHacker.Native/Windows.cs +++ b/trunk/ProcessHacker.Native/Windows.cs @@ -47,8 +47,6 @@ namespace ProcessHacker.Native public static GetProcessNameCallback GetProcessName; - public static string[] KernelNames = { "ntoskrnl.exe", "ntkrnlpa.exe", "ntkrnlmp.exe", "ntkrpamp.exe" }; - /// /// A cache for type names; QuerySystemInformation with ALL_TYPES_INFORMATION fails for some /// reason. The dictionary relates object type numbers to their names. @@ -58,6 +56,8 @@ namespace ProcessHacker.Native [ThreadStatic] private static MemoryAlloc _handlesBuffer; [ThreadStatic] + private static MemoryAlloc _kernelModulesBuffer; + [ThreadStatic] private static MemoryAlloc _processesBuffer; [ThreadStatic] private static MemoryAlloc _servicesBuffer; @@ -66,6 +66,7 @@ namespace ProcessHacker.Native private static int _pageSize = 0; private static IntPtr _kernelBase = IntPtr.Zero; private static string _kernelFileName = null; + private static KernelModule _kernelModule; public static int NumberOfProcessors { @@ -118,30 +119,48 @@ namespace ProcessHacker.Native public static void EnumKernelModules(EnumKernelModulesDelegate enumCallback) { - int requiredSize = 0; - IntPtr[] imageBases; + NtStatus status; + int retLength; - Win32.EnumDeviceDrivers(null, 0, out requiredSize); - imageBases = new IntPtr[requiredSize / 4]; - Win32.EnumDeviceDrivers(imageBases, requiredSize, out requiredSize); + if (_kernelModulesBuffer == null) + _kernelModulesBuffer = new MemoryAlloc(0x1000); - for (int i = 0; i < imageBases.Length; i++) + status = Win32.NtQuerySystemInformation( + SystemInformationClass.SystemModuleInformation, + _kernelModulesBuffer, + _kernelModulesBuffer.Size, + out retLength + ); + + if (status == NtStatus.InfoLengthMismatch) { - if (imageBases[i] == IntPtr.Zero) - continue; + _kernelModulesBuffer.Resize(retLength); - StringBuilder name = new StringBuilder(0x400); - StringBuilder fileName = new StringBuilder(0x400); + status = Win32.NtQuerySystemInformation( + SystemInformationClass.SystemModuleInformation, + _kernelModulesBuffer, + _kernelModulesBuffer.Size, + out retLength + ); + } - Win32.GetDeviceDriverBaseName(imageBases[i], name, name.Capacity * 2); - Win32.GetDeviceDriverFileName(imageBases[i], fileName, name.Capacity * 2); + if (status >= NtStatus.Error) + Win32.ThrowLastError(status); - if (!enumCallback( - new KernelModule( - imageBases[i], - name.ToString(), - FileUtils.FixPath(fileName.ToString()) - ))) + RtlProcessModules modules = _kernelModulesBuffer.ReadStruct(); + + for (int i = 0; i < modules.NumberOfModules; i++) + { + var module = _kernelModulesBuffer.ReadStruct(RtlProcessModules.ModulesOffset, i); + var moduleInfo = new Debugging.ModuleInformation(module); + + if (!enumCallback(new KernelModule( + moduleInfo.BaseAddress, + moduleInfo.Size, + moduleInfo.Flags, + moduleInfo.BaseName, + FileUtils.FixPath(moduleInfo.FileName) + ))) break; } } @@ -223,29 +242,8 @@ namespace ProcessHacker.Native Windows.EnumKernelModules((module) => { - System.IO.FileInfo fi = new System.IO.FileInfo(FileUtils.FixPath(module.FileName)); - bool kernel = false; - string realName; - - realName = fi.FullName; - - foreach (string k in KernelNames) - { - if (realName.Equals(Environment.SystemDirectory + "\\" + k, StringComparison.InvariantCultureIgnoreCase)) - { - kernel = true; - - break; - } - } - - if (kernel) - { - kernelBase = module.BaseAddress; - return false; - } - - return true; + kernelBase = module.BaseAddress; + return false; }); return kernelBase; @@ -261,29 +259,8 @@ namespace ProcessHacker.Native EnumKernelModules((module) => { - System.IO.FileInfo fi = new System.IO.FileInfo(FileUtils.FixPath(module.FileName)); - bool kernel = false; - string realName; - - realName = fi.FullName; - - foreach (string k in KernelNames) - { - if (realName.Equals(Environment.SystemDirectory + "\\" + k, StringComparison.InvariantCultureIgnoreCase)) - { - kernel = true; - - break; - } - } - - if (kernel) - { - kernelFileName = realName; - return false; - } - - return true; + kernelFileName = module.FileName; + return false; }); return kernelFileName; @@ -672,17 +649,42 @@ namespace ProcessHacker.Native public Dictionary Threads; } - public class KernelModule + public class KernelModule : ILoadedModule { - public KernelModule(IntPtr baseAddress, string baseName, string fileName) + public KernelModule( + IntPtr baseAddress, + int size, + LdrpDataTableEntryFlags flags, + string baseName, + string fileName + ) { this.BaseAddress = baseAddress; + this.Size = size; + this.Flags = flags; this.BaseName = baseName; this.FileName = fileName; } + /// + /// The base address of the module. + /// public IntPtr BaseAddress { get; private set; } + /// + /// The size of the module. + /// + public int Size { get; private set; } + /// + /// The flags set by the loader for this module. + /// + public LdrpDataTableEntryFlags Flags { get; private set; } + /// + /// The base name of the module (e.g. module.dll). + /// public string BaseName { get; private set; } + /// + /// The file name of the module (e.g. C:\Windows\system32\module.dll). + /// public string FileName { get; private set; } } diff --git a/trunk/ProcessHacker/Components/HandleList.cs b/trunk/ProcessHacker/Components/HandleList.cs index dee2c193b..8cb909cf4 100644 --- a/trunk/ProcessHacker/Components/HandleList.cs +++ b/trunk/ProcessHacker/Components/HandleList.cs @@ -459,6 +459,13 @@ namespace ProcessHacker.Components control.Controls.Add(timerProps); } break; + case "tmrm": + { + dupHandle = new GenericHandle(phandle, handle, (int)ResourceManagerAccess.QueryInformation); + var tmRmProps = new TmRmProperties(ResourceManagerHandle.FromHandle(dupHandle)); + control.Controls.Add(tmRmProps); + } + break; case "tmtm": { dupHandle = new GenericHandle(phandle, handle, (int)TmAccess.QueryInformation); diff --git a/trunk/ProcessHacker/Components/ModuleList.cs b/trunk/ProcessHacker/Components/ModuleList.cs index 1c17e5aa5..cdb768d94 100644 --- a/trunk/ProcessHacker/Components/ModuleList.cs +++ b/trunk/ProcessHacker/Components/ModuleList.cs @@ -273,7 +273,7 @@ namespace ProcessHacker.Components litem.Name = item.BaseAddress.ToString(); litem.Text = item.Name; litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, Utils.FormatAddress(item.BaseAddress))); - litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, _pid != 4 ? Utils.FormatSize(item.Size) : "")); + litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, Utils.FormatSize(item.Size))); litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, item.FileDescription)); litem.ToolTipText = item.FileName; litem.Tag = item; diff --git a/trunk/ProcessHacker/Components/TmRmProperties.Designer.cs b/trunk/ProcessHacker/Components/TmRmProperties.Designer.cs new file mode 100644 index 000000000..e022334d4 --- /dev/null +++ b/trunk/ProcessHacker/Components/TmRmProperties.Designer.cs @@ -0,0 +1,101 @@ +namespace ProcessHacker.Components +{ + partial class TmRmProperties + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + + _rmHandle.Dispose(disposing); + + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.textDescription = new System.Windows.Forms.TextBox(); + this.textGuid = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(63, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Description:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(6, 35); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(37, 13); + this.label2.TabIndex = 0; + this.label2.Text = "GUID:"; + // + // textDescription + // + this.textDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textDescription.Location = new System.Drawing.Point(75, 6); + this.textDescription.Name = "textDescription"; + this.textDescription.ReadOnly = true; + this.textDescription.Size = new System.Drawing.Size(252, 20); + this.textDescription.TabIndex = 1; + // + // textGuid + // + this.textGuid.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textGuid.Location = new System.Drawing.Point(49, 32); + this.textGuid.Name = "textGuid"; + this.textGuid.ReadOnly = true; + this.textGuid.Size = new System.Drawing.Size(278, 20); + this.textGuid.TabIndex = 1; + // + // TmRmProperties + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.textGuid); + this.Controls.Add(this.textDescription); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Name = "TmRmProperties"; + this.Padding = new System.Windows.Forms.Padding(3); + this.Size = new System.Drawing.Size(333, 62); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textDescription; + private System.Windows.Forms.TextBox textGuid; + } +} diff --git a/trunk/ProcessHacker/Components/TmRmProperties.cs b/trunk/ProcessHacker/Components/TmRmProperties.cs new file mode 100644 index 000000000..20db152ad --- /dev/null +++ b/trunk/ProcessHacker/Components/TmRmProperties.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using ProcessHacker.Native.Objects; + +namespace ProcessHacker.Components +{ + public partial class TmRmProperties : UserControl + { + private ResourceManagerHandle _rmHandle; + + public TmRmProperties(ResourceManagerHandle rmHandle) + { + InitializeComponent(); + + _rmHandle = rmHandle; + _rmHandle.Reference(); + + this.UpdateInfo(); + } + + private void UpdateInfo() + { + try + { + textDescription.Text = _rmHandle.GetDescription(); + textGuid.Text = _rmHandle.GetGuid().ToString("B"); + } + catch (Exception ex) + { + textDescription.Text = "(" + ex.Message + ")"; + textGuid.Text = "(" + ex.Message + ")"; + } + } + } +} diff --git a/trunk/ProcessHacker/Components/TmRmProperties.resx b/trunk/ProcessHacker/Components/TmRmProperties.resx new file mode 100644 index 000000000..ff31a6db5 --- /dev/null +++ b/trunk/ProcessHacker/Components/TmRmProperties.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/trunk/ProcessHacker/ProcessHacker.csproj b/trunk/ProcessHacker/ProcessHacker.csproj index a66c5de9e..72fc5d21b 100644 --- a/trunk/ProcessHacker/ProcessHacker.csproj +++ b/trunk/ProcessHacker/ProcessHacker.csproj @@ -195,6 +195,9 @@ TimerProperties.cs + + TmRmProperties.cs + TmTmProperties.cs @@ -410,6 +413,12 @@ TimerProperties.cs + + UserControl + + + TmRmProperties.cs + UserControl diff --git a/trunk/ProcessHacker/Providers/ModuleProvider.cs b/trunk/ProcessHacker/Providers/ModuleProvider.cs index b85d22f20..f5fcbf938 100644 --- a/trunk/ProcessHacker/Providers/ModuleProvider.cs +++ b/trunk/ProcessHacker/Providers/ModuleProvider.cs @@ -93,161 +93,99 @@ namespace ProcessHacker private void UpdateOnce() { - if (_pid == 4) - this.UpdateDrivers(); - else - this.UpdateModules(); - } - - private void UpdateDrivers() - { - int requiredSize = 0; - IntPtr[] imageBases; - List done = new List(); - Dictionary bases = new Dictionary(); - Dictionary newdictionary = new Dictionary(this.Dictionary); - - Win32.EnumDeviceDrivers(null, 0, out requiredSize); - imageBases = new IntPtr[requiredSize]; - Win32.EnumDeviceDrivers(imageBases, requiredSize * sizeof(int), out requiredSize); - - for (int i = 0; i < requiredSize; i++) - { - if (bases.ContainsKey(imageBases[i]) || imageBases[i] == IntPtr.Zero) - continue; - - bases.Add(imageBases[i], null); - } - - // look for unloaded drivers - foreach (IntPtr b in Dictionary.Keys) - { - if (!bases.ContainsKey(b)) - { - this.OnDictionaryRemoved(this.Dictionary[b]); - newdictionary.Remove(b); - } - } - - // look for new drivers - foreach (IntPtr b in bases.Keys) - { - if (!Dictionary.ContainsKey(b)) - { - ModuleItem item = new ModuleItem(); - StringBuilder name = new StringBuilder(0x400); - StringBuilder filename = new StringBuilder(0x400); - - Win32.GetDeviceDriverBaseName(b, name, name.Capacity * 2); - Win32.GetDeviceDriverFileName(b, filename, filename.Capacity * 2); - - item.RunId = this.RunCount; - item.BaseAddress = b; - item.Name = name.ToString(); - item.FileName = FileUtils.FixPath(filename.ToString()); - - try - { - System.IO.FileInfo fi = new System.IO.FileInfo(item.FileName); - item.FileName = fi.FullName; - - var info = System.Diagnostics.FileVersionInfo.GetVersionInfo(item.FileName); - - item.FileDescription = info.FileDescription; - item.FileVersion = info.FileVersion; - } - catch - { } - - newdictionary.Add(b, item); - this.OnDictionaryAdded(item); - } - } - - this.Dictionary = newdictionary; - } - - private void UpdateModules() - { - if (_processHandle == null) + if (_pid != 4 && _processHandle == null) { Logging.Log(Logging.Importance.Warning, "ModuleProvider: Process Handle is null, exiting..."); return; } - var modules = new Dictionary(); + var modules = new Dictionary(); var newdictionary = new Dictionary(this.Dictionary); - // Is this a WOW64 process? If it is, get the 32-bit modules. - if (!_isWow64) + if (_pid != 4) { - var processModules = _processHandle.GetModules(); - - foreach (var m in processModules) + // Is this a WOW64 process? If it is, get the 32-bit modules. + if (!_isWow64) { - if (!modules.ContainsKey(m.BaseAddress)) - modules.Add(m.BaseAddress, m); + _processHandle.EnumModules((module) => + { + if (!modules.ContainsKey(module.BaseAddress)) + modules.Add(module.BaseAddress, module); + + return true; + }); } + else + { + using (DebugBuffer buffer = new DebugBuffer()) + { + buffer.Query(_pid, RtlQueryProcessDebugFlags.Modules32); + + var processModules = buffer.GetModules(); + + foreach (var m in processModules) + { + // Most of the time we will get a duplicate entry - + // the main executable image. Guard against that. + if (!modules.ContainsKey(m.BaseAddress)) + { + modules.Add( + m.BaseAddress, + new ProcessModule( + m.BaseAddress, + m.Size, + IntPtr.Zero, + m.Flags, + (new System.IO.FileInfo(m.FileName)).Name, + m.FileName + ) + ); + } + } + } + } + + // add mapped files + _processHandle.EnumMemory((info) => + { + if (info.Type == MemoryType.Mapped) + { + try + { + string fileName = _processHandle.GetMappedFileName(info.BaseAddress); + + if (fileName != null) + { + var fi = new System.IO.FileInfo(fileName); + + modules.Add(info.BaseAddress, + new ProcessModule( + info.BaseAddress, + info.RegionSize.ToInt32(), + IntPtr.Zero, + 0, + fi.Name, fi.FullName)); + } + } + catch + { } + } + + return true; + }); } else { - using (DebugBuffer buffer = new DebugBuffer()) + // Add loaded kernel modules. + Windows.EnumKernelModules((module) => { - buffer.Query(_pid, RtlQueryProcessDebugFlags.Modules32); + if (!modules.ContainsKey(module.BaseAddress)) + modules.Add(module.BaseAddress, module); - var processModules = buffer.GetModules(); - - foreach (var m in processModules) - { - // Most of the time we will get a duplicate entry - - // the main executable image. Guard against that. - if (!modules.ContainsKey(m.ImageBase)) - { - modules.Add( - m.ImageBase, - new ProcessModule( - m.ImageBase, - m.ImageSize, - IntPtr.Zero, - m.Flags, - (new System.IO.FileInfo(m.FileName)).Name, - m.FileName - ) - ); - } - } - } + return true; + }); } - // add mapped files - _processHandle.EnumMemory((info) => - { - if (info.Type == MemoryType.Mapped) - { - try - { - string fileName = _processHandle.GetMappedFileName(info.BaseAddress); - - if (fileName != null) - { - var fi = new System.IO.FileInfo(fileName); - - modules.Add(info.BaseAddress, - new ProcessModule( - info.BaseAddress, - info.RegionSize.ToInt32(), - IntPtr.Zero, - 0, - fi.Name, fi.FullName)); - } - } - catch - { } - } - - return true; - }); - // look for unloaded modules foreach (IntPtr b in Dictionary.Keys) { diff --git a/trunk/ProcessHacker/Symbols/SymbolProviderExtensions.cs b/trunk/ProcessHacker/Symbols/SymbolProviderExtensions.cs index 9296de58f..aa238524a 100644 --- a/trunk/ProcessHacker/Symbols/SymbolProviderExtensions.cs +++ b/trunk/ProcessHacker/Symbols/SymbolProviderExtensions.cs @@ -160,7 +160,7 @@ namespace ProcessHacker.Native.Symbols { try { - symbols.LoadModule(module.FileName, module.ImageBase, module.ImageSize); + symbols.LoadModule(module.FileName, module.BaseAddress, module.Size); } catch (Exception ex) {