mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
added highlighting for GUI threads
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1009 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -23,6 +23,8 @@ Process Hacker
|
||||
* Custom module information querying; can now display the modules for protected processes
|
||||
* Displays service DLL paths
|
||||
* Thread list displays cycles instead of context switches on Windows Vista
|
||||
* GUI threads are highlighted (with KProcessHacker)
|
||||
* Suspended and GUI thread highlighting can be configured
|
||||
* FIXED:
|
||||
* #2642442 - "System Information label text gets clipped"
|
||||
* #2694437 - "Crash when sorting the process list"
|
||||
|
||||
Binary file not shown.
@@ -100,6 +100,48 @@ NTSTATUS KphGetContextThread(
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS KphGetThreadWin32Thread(
|
||||
HANDLE ThreadHandle,
|
||||
PVOID *Win32Thread,
|
||||
KPROCESSOR_MODE AccessMode
|
||||
)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
PETHREAD threadObject;
|
||||
PVOID win32Thread;
|
||||
|
||||
if (AccessMode == UserMode)
|
||||
{
|
||||
__try
|
||||
{
|
||||
ProbeForWrite(Win32Thread, sizeof(PVOID), 1);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
return STATUS_ACCESS_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
status = ObReferenceObjectByHandle(ThreadHandle, 0, *PsThreadType, KernelMode, &threadObject, NULL);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
win32Thread = PsGetThreadWin32Thread(threadObject);
|
||||
ObDereferenceObject(threadObject);
|
||||
|
||||
__try
|
||||
{
|
||||
*Win32Thread = win32Thread;
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
return STATUS_ACCESS_VIOLATION;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS KphOpenProcess(
|
||||
PHANDLE ProcessHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
|
||||
@@ -36,19 +36,23 @@ NTSTATUS NTAPI ObOpenObjectByName(
|
||||
PHANDLE Handle
|
||||
);
|
||||
|
||||
NTSTATUS PsGetContextThread(
|
||||
NTSTATUS NTAPI PsGetContextThread(
|
||||
PETHREAD Thread,
|
||||
PCONTEXT ThreadContext,
|
||||
KPROCESSOR_MODE PreviousMode
|
||||
);
|
||||
|
||||
PVOID NTAPI PsGetThreadWin32Thread(
|
||||
PETHREAD Thread
|
||||
);
|
||||
|
||||
NTSTATUS NTAPI PsLookupProcessThreadByCid(
|
||||
PCLIENT_ID ClientId,
|
||||
PEPROCESS *Process,
|
||||
PETHREAD *Thread
|
||||
);
|
||||
|
||||
NTSTATUS PsSetContextThread(
|
||||
NTSTATUS NTAPI PsSetContextThread(
|
||||
PETHREAD Thread,
|
||||
PCONTEXT ThreadContext,
|
||||
KPROCESSOR_MODE PreviousMode
|
||||
@@ -104,6 +108,12 @@ NTSTATUS KphGetContextThread(
|
||||
KPROCESSOR_MODE AccessMode
|
||||
);
|
||||
|
||||
NTSTATUS KphGetThreadWin32Thread(
|
||||
HANDLE ThreadHandle,
|
||||
PVOID *Win32Thread,
|
||||
KPROCESSOR_MODE AccessMode
|
||||
);
|
||||
|
||||
NTSTATUS KphOpenProcess(
|
||||
PHANDLE ProcessHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
|
||||
@@ -294,6 +294,8 @@ char *GetIoControlName(ULONG ControlCode)
|
||||
return "KphGetContextThread";
|
||||
else if (ControlCode == KPH_SETCONTEXTTHREAD)
|
||||
return "KphSetContextThread";
|
||||
else if (ControlCode == KPH_GETTHREADWIN32THREAD)
|
||||
return "KphGetThreadWin32Thread";
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -853,6 +855,26 @@ NTSTATUS KphIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
}
|
||||
break;
|
||||
|
||||
case KPH_GETTHREADWIN32THREAD:
|
||||
{
|
||||
HANDLE threadHandle;
|
||||
|
||||
if (inLength < 4 || outLength < 4)
|
||||
{
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
goto IoControlEnd;
|
||||
}
|
||||
|
||||
threadHandle = *(HANDLE *)dataBuffer;
|
||||
status = KphGetThreadWin32Thread(threadHandle, (PVOID *)dataBuffer, KernelMode);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
goto IoControlEnd;
|
||||
|
||||
retLength = 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
dprintf("KProcessHacker: unrecognized IOCTL code 0x%08x\n", controlCode);
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef struct _SYSTEM_HANDLE_INFORMATION
|
||||
#define KPH_OPENPROCESSJOB KPH_CTL_CODE(17)
|
||||
#define KPH_GETCONTEXTTHREAD KPH_CTL_CODE(18)
|
||||
#define KPH_SETCONTEXTTHREAD KPH_CTL_CODE(19)
|
||||
#define KPH_GETTHREADWIN32THREAD KPH_CTL_CODE(20)
|
||||
|
||||
NTSTATUS KphCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS KphClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
||||
@@ -260,8 +260,10 @@ namespace ProcessHacker
|
||||
|
||||
private System.Drawing.Color GetThreadColor(ThreadItem titem)
|
||||
{
|
||||
if (titem.WaitReason == Win32.KWAIT_REASON.Suspended)
|
||||
return System.Drawing.Color.LightGray;
|
||||
if (Properties.Settings.Default.UseColorSuspended && titem.WaitReason == Win32.KWAIT_REASON.Suspended)
|
||||
return Properties.Settings.Default.ColorSuspended;
|
||||
else if (Properties.Settings.Default.UseColorGuiThreads && titem.IsGuiThread)
|
||||
return Properties.Settings.Default.ColorGuiThreads;
|
||||
|
||||
return System.Drawing.SystemColors.Window;
|
||||
}
|
||||
|
||||
@@ -1799,10 +1799,10 @@ namespace ProcessHacker
|
||||
ColumnSettings.LoadSettings(Properties.Settings.Default.ServiceListViewColumns, listServices.List);
|
||||
ColumnSettings.LoadSettings(Properties.Settings.Default.NetworkListViewColumns, listNetwork.List);
|
||||
|
||||
HighlightingContext.Colors[ListViewItemState.New] = Properties.Settings.Default.ColorNewProcesses;
|
||||
HighlightingContext.Colors[ListViewItemState.Removed] = Properties.Settings.Default.ColorRemovedProcesses;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.New] = Properties.Settings.Default.ColorNewProcesses;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.Removed] = Properties.Settings.Default.ColorRemovedProcesses;
|
||||
HighlightingContext.Colors[ListViewItemState.New] = Properties.Settings.Default.ColorNew;
|
||||
HighlightingContext.Colors[ListViewItemState.Removed] = Properties.Settings.Default.ColorRemoved;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.New] = Properties.Settings.Default.ColorNew;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.Removed] = Properties.Settings.Default.ColorRemoved;
|
||||
|
||||
Program.ImposterNames = new System.Collections.Specialized.StringCollection();
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ namespace ProcessHacker
|
||||
textImposterNames.Text = Properties.Settings.Default.ImposterNames;
|
||||
|
||||
textHighlightingDuration.Value = Properties.Settings.Default.HighlightingDuration;
|
||||
colorNewProcesses.Color = Properties.Settings.Default.ColorNewProcesses;
|
||||
colorRemovedProcesses.Color = Properties.Settings.Default.ColorRemovedProcesses;
|
||||
colorNewProcesses.Color = Properties.Settings.Default.ColorNew;
|
||||
colorRemovedProcesses.Color = Properties.Settings.Default.ColorRemoved;
|
||||
this.InitializeHighlightingColors();
|
||||
|
||||
checkPlotterAntialias.Checked = Properties.Settings.Default.PlotterAntialias;
|
||||
@@ -193,6 +193,10 @@ namespace ProcessHacker
|
||||
"Executables are sometimes \"packed\" to reduce their size.\n" +
|
||||
"\"Dangerous processes\" includes processes with invalid signatures and unverified " +
|
||||
"processes with the name of a system process.");
|
||||
AddToList("ColorSuspended", "Suspended Threads",
|
||||
"Threads that are suspended from execution.");
|
||||
AddToList("ColorGuiThreads", "GUI Threads",
|
||||
"Threads that have made at least one GUI-related system call.");
|
||||
|
||||
foreach (ListViewItem item in listHighlightingColors.Items)
|
||||
{
|
||||
@@ -280,8 +284,8 @@ namespace ProcessHacker
|
||||
Program.HackerWindow.NetworkProvider.Interval = Properties.Settings.Default.RefreshInterval;
|
||||
|
||||
Properties.Settings.Default.HighlightingDuration = (int)textHighlightingDuration.Value;
|
||||
Properties.Settings.Default.ColorNewProcesses = colorNewProcesses.Color;
|
||||
Properties.Settings.Default.ColorRemovedProcesses = colorRemovedProcesses.Color;
|
||||
Properties.Settings.Default.ColorNew = colorNewProcesses.Color;
|
||||
Properties.Settings.Default.ColorRemoved = colorRemovedProcesses.Color;
|
||||
|
||||
foreach (ListViewItem item in listHighlightingColors.Items)
|
||||
{
|
||||
@@ -299,10 +303,10 @@ namespace ProcessHacker
|
||||
|
||||
// apply the settings immediately if we can
|
||||
HighlightingContext.HighlightingDuration = Properties.Settings.Default.HighlightingDuration;
|
||||
HighlightingContext.Colors[ListViewItemState.New] = Properties.Settings.Default.ColorNewProcesses;
|
||||
HighlightingContext.Colors[ListViewItemState.Removed] = Properties.Settings.Default.ColorRemovedProcesses;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.New] = Properties.Settings.Default.ColorNewProcesses;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.Removed] = Properties.Settings.Default.ColorRemovedProcesses;
|
||||
HighlightingContext.Colors[ListViewItemState.New] = Properties.Settings.Default.ColorNew;
|
||||
HighlightingContext.Colors[ListViewItemState.Removed] = Properties.Settings.Default.ColorRemoved;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.New] = Properties.Settings.Default.ColorNew;
|
||||
TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.Removed] = Properties.Settings.Default.ColorRemoved;
|
||||
|
||||
if (checkReplaceTaskManager.Enabled)
|
||||
{
|
||||
|
||||
@@ -60,7 +60,8 @@ namespace ProcessHacker
|
||||
GetHandleObjectName,
|
||||
KphOpenProcessJob,
|
||||
KphGetContextThread,
|
||||
KphSetContextThread
|
||||
KphSetContextThread,
|
||||
KphGetThreadWin32Thread
|
||||
}
|
||||
|
||||
private string _deviceName;
|
||||
@@ -224,6 +225,16 @@ namespace ProcessHacker
|
||||
_fileHandle.IoControl(CtlCode(Control.KphGetContextThread), data, null);
|
||||
}
|
||||
|
||||
public int KphGetThreadWin32Thread(Win32.ThreadHandle threadHandle)
|
||||
{
|
||||
byte[] inData = Misc.IntToBytes(threadHandle, Misc.Endianness.Little);
|
||||
byte[] outData = new byte[4];
|
||||
|
||||
_fileHandle.IoControl(CtlCode(Control.KphGetThreadWin32Thread), inData, outData);
|
||||
|
||||
return Misc.BytesToInt(outData, Misc.Endianness.Little);
|
||||
}
|
||||
|
||||
public int KphOpenProcess(int pid, Win32.PROCESS_RIGHTS desiredAccess)
|
||||
{
|
||||
byte[] inData = new byte[8];
|
||||
|
||||
+54
-6
@@ -362,24 +362,24 @@ namespace ProcessHacker.Properties {
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("Chartreuse")]
|
||||
public global::System.Drawing.Color ColorNewProcesses {
|
||||
public global::System.Drawing.Color ColorNew {
|
||||
get {
|
||||
return ((global::System.Drawing.Color)(this["ColorNewProcesses"]));
|
||||
return ((global::System.Drawing.Color)(this["ColorNew"]));
|
||||
}
|
||||
set {
|
||||
this["ColorNewProcesses"] = value;
|
||||
this["ColorNew"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("255, 60, 40")]
|
||||
public global::System.Drawing.Color ColorRemovedProcesses {
|
||||
public global::System.Drawing.Color ColorRemoved {
|
||||
get {
|
||||
return ((global::System.Drawing.Color)(this["ColorRemovedProcesses"]));
|
||||
return ((global::System.Drawing.Color)(this["ColorRemoved"]));
|
||||
}
|
||||
set {
|
||||
this["ColorRemovedProcesses"] = value;
|
||||
this["ColorRemoved"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1200,5 +1200,53 @@ namespace ProcessHacker.Properties {
|
||||
this["ServiceMiniListColumns"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("Silver")]
|
||||
public global::System.Drawing.Color ColorSuspended {
|
||||
get {
|
||||
return ((global::System.Drawing.Color)(this["ColorSuspended"]));
|
||||
}
|
||||
set {
|
||||
this["ColorSuspended"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool UseColorSuspended {
|
||||
get {
|
||||
return ((bool)(this["UseColorSuspended"]));
|
||||
}
|
||||
set {
|
||||
this["UseColorSuspended"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("255, 255, 128")]
|
||||
public global::System.Drawing.Color ColorGuiThreads {
|
||||
get {
|
||||
return ((global::System.Drawing.Color)(this["ColorGuiThreads"]));
|
||||
}
|
||||
set {
|
||||
this["ColorGuiThreads"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool UseColorGuiThreads {
|
||||
get {
|
||||
return ((bool)(this["UseColorGuiThreads"]));
|
||||
}
|
||||
set {
|
||||
this["UseColorGuiThreads"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +86,10 @@
|
||||
<Setting Name="SearchEngine" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">http://www.google.com/search?q=%s</Value>
|
||||
</Setting>
|
||||
<Setting Name="ColorNewProcesses" Type="System.Drawing.Color" Scope="User">
|
||||
<Setting Name="ColorNew" Type="System.Drawing.Color" Scope="User">
|
||||
<Value Profile="(Default)">Chartreuse</Value>
|
||||
</Setting>
|
||||
<Setting Name="ColorRemovedProcesses" Type="System.Drawing.Color" Scope="User">
|
||||
<Setting Name="ColorRemoved" Type="System.Drawing.Color" Scope="User">
|
||||
<Value Profile="(Default)">255, 60, 40</Value>
|
||||
</Setting>
|
||||
<Setting Name="ColorOwnProcesses" Type="System.Drawing.Color" Scope="User">
|
||||
@@ -296,5 +296,17 @@
|
||||
<Setting Name="ServiceMiniListColumns" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="ColorSuspended" Type="System.Drawing.Color" Scope="User">
|
||||
<Value Profile="(Default)">Silver</Value>
|
||||
</Setting>
|
||||
<Setting Name="UseColorSuspended" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="ColorGuiThreads" Type="System.Drawing.Color" Scope="User">
|
||||
<Value Profile="(Default)">255, 255, 128</Value>
|
||||
</Setting>
|
||||
<Setting Name="UseColorGuiThreads" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -46,6 +46,7 @@ namespace ProcessHacker
|
||||
public uint StartAddressI;
|
||||
public string StartAddress;
|
||||
public Win32.KWAIT_REASON WaitReason;
|
||||
public bool IsGuiThread;
|
||||
|
||||
public Win32.ThreadHandle ThreadQueryLimitedHandle;
|
||||
}
|
||||
@@ -170,6 +171,16 @@ namespace ProcessHacker
|
||||
catch
|
||||
{ }
|
||||
|
||||
if (Program.KPH != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.IsGuiThread = Program.KPH.KphGetThreadWin32Thread(item.ThreadQueryLimitedHandle) != 0;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
if (Program.WindowsVersion != WindowsVersion.XP)
|
||||
{
|
||||
try
|
||||
@@ -237,6 +248,16 @@ namespace ProcessHacker
|
||||
catch
|
||||
{ }
|
||||
|
||||
if (Program.KPH != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
newitem.IsGuiThread = Program.KPH.KphGetThreadWin32Thread(newitem.ThreadQueryLimitedHandle) != 0;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
if (Program.WindowsVersion != WindowsVersion.XP)
|
||||
{
|
||||
try
|
||||
@@ -266,6 +287,7 @@ namespace ProcessHacker
|
||||
newitem.ContextSwitchesDelta != item.ContextSwitchesDelta ||
|
||||
newitem.Cycles != item.Cycles ||
|
||||
newitem.CyclesDelta != item.CyclesDelta ||
|
||||
newitem.IsGuiThread != item.IsGuiThread ||
|
||||
newitem.Priority != item.Priority ||
|
||||
newitem.StartAddress != item.StartAddress ||
|
||||
newitem.WaitReason != item.WaitReason
|
||||
|
||||
@@ -91,10 +91,10 @@
|
||||
<setting name="SearchEngine" serializeAs="String">
|
||||
<value>http://www.google.com/search?q=%s</value>
|
||||
</setting>
|
||||
<setting name="ColorNewProcesses" serializeAs="String">
|
||||
<setting name="ColorNew" serializeAs="String">
|
||||
<value>Chartreuse</value>
|
||||
</setting>
|
||||
<setting name="ColorRemovedProcesses" serializeAs="String">
|
||||
<setting name="ColorRemoved" serializeAs="String">
|
||||
<value>255, 60, 40</value>
|
||||
</setting>
|
||||
<setting name="ColorOwnProcesses" serializeAs="String">
|
||||
@@ -301,6 +301,18 @@
|
||||
<setting name="ServiceMiniListColumns" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="ColorSuspended" serializeAs="String">
|
||||
<value>Silver</value>
|
||||
</setting>
|
||||
<setting name="UseColorSuspended" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="ColorGuiThreads" serializeAs="String">
|
||||
<value>255, 255, 128</value>
|
||||
</setting>
|
||||
<setting name="UseColorGuiThreads" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
</ProcessHacker.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user