HyperDbg Debugger
Loading...
Searching...
No Matches
thread.cpp File Reference

show and change threads More...

#include "pch.h"

Functions

VOID CommandThreadHelp ()
 help of the .thread command
BOOLEAN CommandThreadListThreads (UINT64 Eprocess)
VOID CommandThread (vector< CommandToken > CommandTokens, string Command)
 .thread command handler

Variables

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
 Shows if the debugger was connected to remote debuggee over (A remote guest).

Detailed Description

show and change threads

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2021-11-23

Function Documentation

◆ CommandThread()

VOID CommandThread ( vector< CommandToken > CommandTokens,
string Command )

.thread command handler

Parameters
CommandTokens
Command
Returns
VOID
121{
122 UINT32 TargetThreadId = 0;
123 UINT64 TargetThread = 0;
124 UINT64 TargetProcess = 0;
125 BOOLEAN CheckByClkIntr = FALSE;
126
127 if (CommandTokens.size() >= 5)
128 {
129 ShowMessages("incorrect use of the '%s'\n\n",
130 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
132 return;
133 }
134
135 if (CommandTokens.size() == 1)
136 {
137 //
138 // Check if it's connected to a remote debuggee or not
139 //
141 {
143 }
144 else
145 {
146 //
147 // Send the packet to get current thread
148 //
150 NULL,
151 NULL,
152 FALSE,
153 NULL);
154 }
155 }
156 else if (CommandTokens.size() == 2)
157 {
158 if (CompareLowerCaseStrings(CommandTokens.at(1), "list"))
159 {
160 //
161 // Sending null as the nt!_EPROCESS indicates that the target process is
162 // the current process (Current nt!_EPROCESS)
163 //
164 if (!CommandThreadListThreads(NULL))
165 {
166 ShowMessages("err, the need offset to iterate over threads not found, "
167 "make sure to load ntoskrnl.exe's PDB file. use '.help .sym' for "
168 "more information\n");
169 return;
170 }
171 }
172 else
173 {
174 ShowMessages(
175 "err, unknown parameter at '%s'\n\n",
176 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(1)).c_str());
178 return;
179 }
180 }
181 else if (CommandTokens.size() == 3)
182 {
183 //
184 // Check if it's connected to a remote debuggee or not
185 //
187 {
188 ShowMessages("err, you're not connected to any debuggee in Debugger Mode, "
189 "you can use the '.attach', or the '.detach' commands if you're "
190 "operating in VMI Mode\n");
191 return;
192 }
193
194 if (CompareLowerCaseStrings(CommandTokens.at(1), "tid"))
195 {
196 if (!ConvertTokenToUInt32(CommandTokens.at(2), &TargetThreadId))
197 {
198 ShowMessages(
199 "please specify a correct hex value for the thread id that you "
200 "want to operate on it\n\n");
202 return;
203 }
204 }
205 else if (CompareLowerCaseStrings(CommandTokens.at(1), "thread"))
206 {
207 if (!SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)), &TargetThread))
208 {
209 ShowMessages(
210 "please specify a correct hex value for the thread (nt!_ETHREAD) that you "
211 "want to operate on it\n\n");
213 return;
214 }
215 }
216 else if (CompareLowerCaseStrings(CommandTokens.at(1), "list") && CompareLowerCaseStrings(CommandTokens.at(2), "process"))
217 {
218 ShowMessages(
219 "please specify a hex value for the process\n\n");
221 return;
222 }
223 else
224 {
225 ShowMessages(
226 "err, unknown parameter at '%s'\n\n",
227 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str());
229 return;
230 }
231
232 if (CompareLowerCaseStrings(CommandTokens.at(0), ".thread2"))
233 {
234 //
235 // Check by changes to gs:[188]
236 //
237 CheckByClkIntr = FALSE;
238 }
239 else
240 {
241 //
242 // Check on clock interrupt changes
243 //
244 CheckByClkIntr = TRUE;
245 }
246
247 //
248 // Send the packet to change the thread
249 //
251 TargetThreadId,
252 TargetThread,
253 CheckByClkIntr,
254 NULL);
255 }
256 else if (CommandTokens.size() == 4)
257 {
258 if (CompareLowerCaseStrings(CommandTokens.at(1), "list"))
259 {
260 if (CompareLowerCaseStrings(CommandTokens.at(2), "process"))
261 {
262 if (!SymbolConvertNameOrExprToAddress(GetCaseSensitiveStringFromCommandToken(CommandTokens.at(3)), &TargetProcess))
263 {
264 ShowMessages(
265 "please specify a correct hex value for the process (nt!_EPROCESS) that you "
266 "want to see its threads\n\n");
268 return;
269 }
270
271 //
272 // List the target process's threads
273 //
274 if (!CommandThreadListThreads(TargetProcess))
275 {
276 ShowMessages("err, the need offset to iterate over threads not found, "
277 "make sure to load ntoskrnl.exe's PDB file. use '.help .sym' for "
278 "more information\n");
279 return;
280 }
281 }
282 else
283 {
284 ShowMessages(
285 "err, unknown parameter at '%s'\n\n",
286 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str());
288 return;
289 }
290 }
291 else
292 {
293 ShowMessages(
294 "err, unknown parameter at '%s'\n\n",
295 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(1)).c_str());
297 return;
298 }
299 }
300 else
301 {
302 ShowMessages("invalid parameter\n\n");
304 return;
305 }
306}
BOOLEAN g_IsSerialConnectedToRemoteDebuggee
Shows if the debugger was connected to remote debuggee over (A remote guest).
Definition globals.h:253
UCHAR BOOLEAN
Definition BasicTypes.h:35
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
unsigned int UINT32
Definition BasicTypes.h:54
@ DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PERFORM_SWITCH
Definition RequestStructures.h:1007
@ DEBUGGEE_DETAILS_AND_SWITCH_THREAD_GET_THREAD_DETAILS
Definition RequestStructures.h:1008
std::string GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken)
Get case sensitive string from command token.
Definition common.cpp:467
BOOLEAN CompareLowerCaseStrings(CommandToken TargetToken, const CHAR *StringToCompare)
Compare lower case strings.
Definition common.cpp:503
BOOLEAN ConvertTokenToUInt32(CommandToken TargetToken, PUINT32 Result)
check and convert command token to a 32 bit unsigned integer
Definition common.cpp:546
BOOLEAN KdSendSwitchThreadPacketToDebuggee(DEBUGGEE_DETAILS_AND_SWITCH_THREAD_TYPE ActionType, UINT32 NewTid, UINT64 NewThread, BOOLEAN CheckByClockInterrupt, PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS SymDetailsForThreadList)
Sends a change thread or show threads detail packet to the debuggee.
Definition kd.cpp:858
BOOLEAN ObjectShowProcessesOrThreadDetails(BOOLEAN IsProcess)
Get details about processes or threads.
Definition objects.cpp:26
BOOLEAN SymbolConvertNameOrExprToAddress(const string &TextToConvert, PUINT64 Result)
check and convert string to a 64 bit unsigned integer and also check for symbol object names and eval...
Definition symbol.cpp:359
VOID CommandThreadHelp()
help of the .thread command
Definition thread.cpp:25
BOOLEAN CommandThreadListThreads(UINT64 Eprocess)
Definition thread.cpp:50

◆ CommandThreadHelp()

VOID CommandThreadHelp ( )

help of the .thread command

Returns
VOID
26{
27 ShowMessages(".thread, .thread2 : shows and changes the threads. "
28 "This command needs public symbols for 'ntoskrnl.exe' if "
29 "you want to see the threads list. Please visit the "
30 "documentation to know about the difference between '.thread' "
31 "and '.thread2'.\n\n");
32
33 ShowMessages("syntax : \t.thread\n");
34 ShowMessages("syntax : \t.thread [list] [process Eprocess (hex)]\n");
35 ShowMessages("syntax : \t.thread [tid ThreadId (hex)]\n");
36 ShowMessages("syntax : \t.thread [thread Ethread (hex)]\n");
37 ShowMessages("syntax : \t.thread2 [tid ThreadId (hex)]\n");
38 ShowMessages("syntax : \t.thread2 [thread Ethread (hex)]\n");
39
40 ShowMessages("\n");
41 ShowMessages("\t\te.g : .thread\n");
42 ShowMessages("\t\te.g : .thread tid 48a4\n");
43 ShowMessages("\t\te.g : .thread2 tid 48a4\n");
44 ShowMessages("\t\te.g : .thread thread ffff948c`c8970200\n");
45 ShowMessages("\t\te.g : .thread list\n");
46 ShowMessages("\t\te.g : .thread list process ffff948c`a1279880\n");
47}

◆ CommandThreadListThreads()

BOOLEAN CommandThreadListThreads ( UINT64 Eprocess)
51{
52 UINT32 ThreadListHeadOffset = 0; // nt!_EPROCESS.ThreadListHead
53 UINT32 ThreadListEntryOffset = 0; // nt!_ETHREAD.ThreadListEntry
54 UINT32 CidOffset = 0; // nt!_ETHREAD.Cid
55 UINT32 OffsetOfActiveProcessLinks = 0; // nt!_EPROCESS.ActiveProcessLinks
56 UINT64 AddressOfActiveProcessHead = 0; // nt!PsActiveProcessHead
57 DEBUGGEE_THREAD_LIST_NEEDED_DETAILS ThreadListNeededItems = {0};
58
59 //
60 // Query for nt!_EPROCESS.ThreadListHead, nt!_ETHREAD.ThreadListEntry,
61 // from the top of nt!_EPROCESS, and nt!_ETHREAD address and check if
62 // we find them or not, otherwise, it means that the PDB for ntoskrnl.exe
63 // is not available
64 //
65 if (ScriptEngineGetFieldOffsetWrapper((CHAR *)"nt!_EPROCESS", (CHAR *)"ThreadListHead", &ThreadListHeadOffset) &&
66 ScriptEngineGetFieldOffsetWrapper((CHAR *)"nt!_ETHREAD", (CHAR *)"ThreadListEntry", &ThreadListEntryOffset) &&
67 ScriptEngineGetFieldOffsetWrapper((CHAR *)"nt!_ETHREAD", (CHAR *)"Cid", &CidOffset) &&
68 ScriptEngineGetFieldOffsetWrapper((CHAR *)"nt!_EPROCESS", (CHAR *)"ActiveProcessLinks", &OffsetOfActiveProcessLinks) &&
69 SymbolConvertNameOrExprToAddress("nt!PsActiveProcessHead", &AddressOfActiveProcessHead))
70 {
71 ThreadListNeededItems.ThreadListHeadOffset = ThreadListHeadOffset;
72 ThreadListNeededItems.ThreadListEntryOffset = ThreadListEntryOffset;
73 ThreadListNeededItems.CidOffset = CidOffset;
74 ThreadListNeededItems.ActiveProcessLinksOffset = OffsetOfActiveProcessLinks;
75 ThreadListNeededItems.PsActiveProcessHead = AddressOfActiveProcessHead;
76 ThreadListNeededItems.Process = Eprocess;
77
78 //
79 // Check if it's connected to a remote debuggee or not
80 //
82 {
83 //
84 // Get the thread details in VMI mode
85 //
87 NULL,
88 NULL,
89 &ThreadListNeededItems);
90 }
91 else
92 {
93 //
94 // Send the packet to list threads
95 //
97 NULL,
98 NULL,
99 FALSE,
100 &ThreadListNeededItems);
101 }
102
103 return TRUE;
104 }
105 else
106 {
107 return FALSE;
108 }
109}
char CHAR
Definition BasicTypes.h:33
@ DEBUGGEE_DETAILS_AND_SWITCH_THREAD_GET_THREAD_LIST
Definition RequestStructures.h:1009
struct _DEBUGGEE_THREAD_LIST_NEEDED_DETAILS DEBUGGEE_THREAD_LIST_NEEDED_DETAILS
The structure of needed information to get the details of the thread from nt!_ETHREAD and location of...
BOOLEAN ObjectShowProcessesOrThreadList(BOOLEAN IsProcess, PDEBUGGEE_PROCESS_LIST_NEEDED_DETAILS SymDetailsForProcessList, UINT64 Eprocess, PDEBUGGEE_THREAD_LIST_NEEDED_DETAILS SymDetailsForThreadList)
Get details about processes or threads.
Definition objects.cpp:138
BOOLEAN ScriptEngineGetFieldOffsetWrapper(CHAR *TypeName, CHAR *FieldName, UINT32 *FieldOffset)
ScriptEngineGetFieldOffset wrapper.
Definition script-engine-wrapper.cpp:132
UINT32 ThreadListHeadOffset
Definition RequestStructures.h:751
UINT32 CidOffset
Definition RequestStructures.h:753
UINT32 ThreadListEntryOffset
Definition RequestStructures.h:752
UINT64 PsActiveProcessHead
Definition RequestStructures.h:754
UINT64 Process
Definition RequestStructures.h:756
ULONG ActiveProcessLinksOffset
Definition RequestStructures.h:755

Variable Documentation

◆ g_IsSerialConnectedToRemoteDebuggee

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
extern

Shows if the debugger was connected to remote debuggee over (A remote guest).