11#include " hider.h"
22#include " log.h"
33#include " threadhidefromdbg.h"
4+ #include " hooks.h"
45
56struct HIDE_ENTRY
67{
@@ -12,6 +13,7 @@ struct HIDE_ENTRY
1213
1314static HIDE_ENTRY HideEntries[MAX_HIDE_ENTRIES ];
1415static LONG TotalHideEntries = 0 ;
16+ static KSPIN_LOCK HideEntriesLock;
1517
1618// entry management
1719static void EntryAdd (HIDE_ENTRY * NewEntry)
@@ -38,12 +40,9 @@ static void EntryDel(int EntryIndex)
3840 EntryClear ();
3941 return ;
4042 }
41- if (!EntryIndex)
42- RtlCopyMemory (&HideEntries[0 ], &HideEntries[1 ], NewTotalHideEntries * sizeof (HIDE_ENTRY ));
43- else
44- {
45- RtlCopyMemory (&HideEntries[EntryIndex], &HideEntries[EntryIndex + 1 ], (NewTotalHideEntries - EntryIndex)*sizeof (HIDE_ENTRY ));
46- }
43+ // Entry order is irrelevant; replace the removed slot with the last
44+ // entry so updates remain bounded while the spin lock is held.
45+ HideEntries[EntryIndex] = HideEntries[NewTotalHideEntries];
4746 InterlockedExchange (&TotalHideEntries, NewTotalHideEntries);
4847 }
4948}
@@ -87,6 +86,12 @@ static void EntryUnset(int EntryIndex, ULONG Type)
8786}
8887
8988// usable functions
89+ void Hider::Initialize ()
90+ {
91+ KeInitializeSpinLock (&HideEntriesLock);
92+ TotalHideEntries = 0 ;
93+ }
94+
9095bool Hider::ProcessData (PVOID Buffer, ULONG Size)
9196{
9297 if (Size % sizeof (HIDE_INFO ))
@@ -99,6 +104,8 @@ bool Hider::ProcessData(PVOID Buffer, ULONG Size)
99104 {
100105 case HidePid:
101106 {
107+ KIRQL Irql;
108+ KeAcquireSpinLock (&HideEntriesLock, &Irql);
102109 int FoundEntry = EntryFind (HideInfo[i].Pid );
103110 if (FoundEntry == -1 )
104111 {
@@ -111,6 +118,7 @@ bool Hider::ProcessData(PVOID Buffer, ULONG Size)
111118 {
112119 EntrySet (FoundEntry, HideInfo[i].Type );
113120 }
121+ KeReleaseSpinLock (&HideEntriesLock, Irql);
114122
115123 // Use DKOM to disable HideThreadHideFromDebugger in any threads in the target process that already have this flag set
116124 if ((HideInfo[i].Type & (ULONG )HideThreadHideFromDebugger) != 0 && CrossThreadFlagsOffset != 0 )
@@ -126,19 +134,28 @@ bool Hider::ProcessData(PVOID Buffer, ULONG Size)
126134
127135 case UnhidePid:
128136 {
137+ KIRQL Irql;
138+ KeAcquireSpinLock (&HideEntriesLock, &Irql);
129139 int FoundEntry = EntryFind (HideInfo[i].Pid );
130140 if (FoundEntry != -1 )
131141 {
132142 EntryUnset (FoundEntry, HideInfo[i].Type );
133143 if (!EntryGet (FoundEntry)) // nothing left to hide for PID
134144 EntryDel (FoundEntry);
135145 }
146+ KeReleaseSpinLock (&HideEntriesLock, Irql);
147+ if ((HideInfo[i].Type & (ULONG )HideThreadHideFromDebugger) != 0 )
148+ Hooks::RestoreVirtualThreadHides (HideInfo[i].Pid , false );
136149 }
137150 break ;
138151
139152 case UnhideAll:
140153 {
154+ KIRQL Irql;
155+ KeAcquireSpinLock (&HideEntriesLock, &Irql);
141156 EntryClear ();
157+ KeReleaseSpinLock (&HideEntriesLock, Irql);
158+ Hooks::RestoreVirtualThreadHides (0 , true );
142159 }
143160 break ;
144161 }
@@ -148,11 +165,15 @@ bool Hider::ProcessData(PVOID Buffer, ULONG Size)
148165
149166bool Hider::IsHidden (ULONG Pid, HIDE_TYPE Type)
150167{
168+ bool Hidden = false ;
169+ KIRQL Irql;
170+ KeAcquireSpinLock (&HideEntriesLock, &Irql);
151171 int FoundEntry = EntryFind (Pid);
152- if (FoundEntry == -1 )
153- return false ;
154- ULONG uType = (ULONG )Type;
155- if ((EntryGet (FoundEntry)&uType) == uType)
156- return true ;
157- return false ;
172+ if (FoundEntry != -1 )
173+ {
174+ ULONG uType = (ULONG )Type;
175+ Hidden = (EntryGet (FoundEntry) & uType) == uType;
176+ }
177+ KeReleaseSpinLock (&HideEntriesLock, Irql);
178+ return Hidden;
158179}
0 commit comments