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

s* command More...

#include "pch.h"

Functions

VOID CommandSearchMemoryHelp ()
 help of !s* s* commands
 
VOID CommandSearchSendRequest (UINT64 *BufferToSendAsIoctl, UINT32 BufferToSendAsIoctlSize)
 Send the request of search to the kernel.
 
VOID CommandSearchMemory (vector< string > SplitCommand, string Command)
 !s* s* commands handler
 

Variables

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
 Shows if the debugger was connected to remote debuggee over (A remote guest)
 
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
 State of active debugging thread.
 

Detailed Description

s* command

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-07-29

Function Documentation

◆ CommandSearchMemory()

VOID CommandSearchMemory ( vector< string > SplitCommand,
string Command )

!s* s* commands handler

Parameters
SplitCommand
Command
Returns
VOID
139{
141 vector<UINT64> ValuesToEdit;
142 BOOL SetAddress = FALSE;
144 BOOL SetProcId = FALSE;
145 BOOL NextIsProcId = FALSE;
146 BOOL SetLength = FALSE;
147 BOOL NextIsLength = FALSE;
148 DEBUGGER_SEARCH_MEMORY SearchMemoryRequest = {0};
149 UINT64 Value = 0;
150 UINT64 Length = 0;
151 UINT32 ProcId = 0;
152 UINT32 CountOfValues = 0;
153 UINT32 FinalSize = 0;
154 UINT64 * FinalBuffer = NULL;
155 vector<string> SplitCommandCaseSensitive {Split(Command, ' ')};
156 UINT32 IndexInCommandCaseSensitive = 0;
157 BOOLEAN IsFirstCommand = TRUE;
158
159 //
160 // By default if the user-debugger is active, we use these commands
161 // on the memory layout of the debuggee process
162 //
164 {
166 }
167
168 if (SplitCommand.size() <= 4)
169 {
170 ShowMessages("incorrect use of the 's*'\n\n");
172 return;
173 }
174
175 for (auto Section : SplitCommand)
176 {
177 IndexInCommandCaseSensitive++;
178
179 if (IsFirstCommand == TRUE)
180 {
181 if (!Section.compare("!sb"))
182 {
183 SearchMemoryRequest.MemoryType = SEARCH_PHYSICAL_MEMORY;
184 SearchMemoryRequest.ByteSize = SEARCH_BYTE;
185 }
186 else if (!Section.compare("!sd"))
187 {
188 SearchMemoryRequest.MemoryType = SEARCH_PHYSICAL_MEMORY;
189 SearchMemoryRequest.ByteSize = SEARCH_DWORD;
190 }
191 else if (!Section.compare("!sq"))
192 {
193 SearchMemoryRequest.MemoryType = SEARCH_PHYSICAL_MEMORY;
194 SearchMemoryRequest.ByteSize = SEARCH_QWORD;
195 }
196 else if (!Section.compare("sb"))
197 {
198 SearchMemoryRequest.MemoryType = SEARCH_VIRTUAL_MEMORY;
199 SearchMemoryRequest.ByteSize = SEARCH_BYTE;
200 }
201 else if (!Section.compare("sd"))
202 {
203 SearchMemoryRequest.MemoryType = SEARCH_VIRTUAL_MEMORY;
204 SearchMemoryRequest.ByteSize = SEARCH_DWORD;
205 }
206 else if (!Section.compare("sq"))
207 {
208 SearchMemoryRequest.MemoryType = SEARCH_VIRTUAL_MEMORY;
209 SearchMemoryRequest.ByteSize = SEARCH_QWORD;
210 }
211 else
212 {
213 //
214 // What's this? :(
215 //
216 ShowMessages("unknown error happened !\n\n");
218 return;
219 }
220
221 IsFirstCommand = FALSE;
222
223 continue;
224 }
225
226 if (NextIsProcId)
227 {
228 //
229 // It's a process id
230 //
231 NextIsProcId = FALSE;
232
233 if (!ConvertStringToUInt32(Section, &ProcId))
234 {
235 ShowMessages("please specify a correct hex process id\n\n");
237 return;
238 }
239 else
240 {
241 //
242 // Means that the proc id is set, next we should read value
243 //
244 continue;
245 }
246 }
247
248 if (NextIsLength)
249 {
250 //
251 // It's a length
252 //
253 NextIsLength = FALSE;
254
255 if (!ConvertStringToUInt64(Section, &Length))
256 {
257 ShowMessages("please specify a correct hex length\n\n");
259 return;
260 }
261 else
262 {
263 //
264 // Means that the proc id is set, next we should read value
265 //
266 SetLength = TRUE;
267 continue;
268 }
269 }
270
271 //
272 // Check if it's a process id or not
273 //
274 if (!SetProcId && !Section.compare("pid"))
275 {
276 NextIsProcId = TRUE;
277 continue;
278 }
279
280 //
281 // Check if it's a length or not
282 //
283 if (!SetLength && !Section.compare("l"))
284 {
285 NextIsLength = TRUE;
286 continue;
287 }
288
289 if (!SetAddress)
290 {
291 if (!SymbolConvertNameOrExprToAddress(SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1), &Address))
292 {
293 ShowMessages("err, couldn't resolve error at '%s'\n\n",
294 SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1).c_str());
296 return;
297 }
298 else
299 {
300 //
301 // Means that the address is set, next we should read value
302 //
303 SetAddress = TRUE;
304 continue;
305 }
306 }
307
308 if (SetAddress)
309 {
310 //
311 // Remove the hex notations
312 //
313 if (Section.rfind("0x", 0) == 0 || Section.rfind("0X", 0) == 0 ||
314 Section.rfind("\\x", 0) == 0 || Section.rfind("\\X", 0) == 0)
315 {
316 Section = Section.erase(0, 2);
317 }
318 else if (Section.rfind('x', 0) == 0 || Section.rfind('X', 0) == 0)
319 {
320 Section = Section.erase(0, 1);
321 }
322 Section.erase(remove(Section.begin(), Section.end(), '`'), Section.end());
323
324 //
325 // Check if the value is valid based on byte counts
326 //
327 if (SearchMemoryRequest.ByteSize == SEARCH_BYTE && Section.size() >= 3)
328 {
329 ShowMessages("please specify a byte (hex) value for 'sb' or '!sb'\n\n");
330 return;
331 }
332 if (SearchMemoryRequest.ByteSize == SEARCH_DWORD && Section.size() >= 9)
333 {
335 "please specify a dword (hex) value for 'sd' or '!sd'\n\n");
336 return;
337 }
338 if (SearchMemoryRequest.ByteSize == SEARCH_QWORD &&
339 Section.size() >= 17)
340 {
342 "please specify a qword (hex) value for 'sq' or '!sq'\n\n");
343 return;
344 }
345
346 //
347 // Qword is checked by the following function, no need to double
348 // check it above.
349 //
350 if (!ConvertStringToUInt64(Section, &Value))
351 {
352 ShowMessages("please specify a correct hex value to search in the "
353 "memory content\n\n");
355 return;
356 }
357 else
358 {
359 //
360 // Add it to the list
361 //
362 ValuesToEdit.push_back(Value);
363
364 //
365 // Keep track of values to modify
366 //
367 CountOfValues++;
368
369 if (!SetValue)
370 {
371 //
372 // At least on walue is there
373 //
374 SetValue = TRUE;
375 }
376 continue;
377 }
378 }
379 }
380
381 //
382 // Check to prevent using process id in s* commands
383 //
384 if (g_IsSerialConnectedToRemoteDebuggee && ProcId != 0)
385 {
387 return;
388 }
389
390 if (ProcId == 0)
391 {
392 ProcId = GetCurrentProcessId();
393 }
394
395 //
396 // Fill the structure
397 //
398 SearchMemoryRequest.ProcessId = ProcId;
399 SearchMemoryRequest.Address = Address;
400 SearchMemoryRequest.CountOf64Chunks = CountOfValues;
401
402 //
403 // Check if address and value are set or not
404 //
405 if (!SetAddress)
406 {
407 ShowMessages("please specify a correct hex address\n\n");
409 return;
410 }
411 if (!SetValue)
412 {
414 "please specify a correct hex value as the content to search\n\n");
416 return;
417 }
418 if (!SetLength)
419 {
420 ShowMessages("please specify a correct hex value as the length\n\n");
422 return;
423 }
424 if (NextIsProcId)
425 {
426 ShowMessages("please specify a correct hex value as the process id\n\n");
428 return;
429 }
430 if (NextIsLength)
431 {
432 ShowMessages("please specify a correct hex length\n\n");
434 return;
435 }
436
437 //
438 // Now it's time to put everything together in one structure
439 //
440 FinalSize = (CountOfValues * sizeof(UINT64)) + SIZEOF_DEBUGGER_SEARCH_MEMORY;
441
442 //
443 // Set the size
444 //
445 SearchMemoryRequest.FinalStructureSize = FinalSize;
446
447 //
448 // Set the length
449 //
450 SearchMemoryRequest.Length = Length;
451
453 {
455 }
456
457 //
458 // Allocate structure + buffer
459 //
460 FinalBuffer = (UINT64 *)malloc(FinalSize);
461
462 if (!FinalBuffer)
463 {
464 ShowMessages("unable to allocate memory\n\n");
465 return;
466 }
467
468 //
469 // Zero the buffer
470 //
471 ZeroMemory(FinalBuffer, FinalSize);
472
473 //
474 // Copy the structure on top of the allocated buffer
475 //
476 memcpy(FinalBuffer, &SearchMemoryRequest, SIZEOF_DEBUGGER_SEARCH_MEMORY);
477
478 //
479 // Put the values in 64 bit structures
480 //
481 std::copy(ValuesToEdit.begin(), ValuesToEdit.end(), (UINT64 *)((UINT64)FinalBuffer + SIZEOF_DEBUGGER_SEARCH_MEMORY));
482
483 //
484 // Check if it's a connection in debugger mode
485 //
487 {
488 //
489 // The buffer should be sent to the debugger
490 //
491 KdSendSearchRequestPacketToDebuggee(FinalBuffer, FinalSize);
492 }
493 else
494 {
495 //
496 // it's a local connection, send the buffer directly
497 //
498 CommandSearchSendRequest(FinalBuffer, FinalSize);
499 }
500
501 //
502 // Free the buffers
503 //
504 free(FinalBuffer);
505}
int BOOL
Definition BasicTypes.h:23
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21
unsigned int UINT32
Definition BasicTypes.h:48
UINT64 Address
Definition HyperDbgScriptImports.h:67
@ SEARCH_QWORD
Definition RequestStructures.h:518
@ SEARCH_BYTE
Definition RequestStructures.h:516
@ SEARCH_DWORD
Definition RequestStructures.h:517
@ SEARCH_PHYSICAL_MEMORY
Definition RequestStructures.h:504
@ SEARCH_VIRTUAL_MEMORY
Definition RequestStructures.h:505
#define SIZEOF_DEBUGGER_SEARCH_MEMORY
Definition RequestStructures.h:496
VOID SetValue(PGUEST_REGS GuestRegs, SCRIPT_ENGINE_VARIABLES_LIST *VariablesList, PSYMBOL Symbol, UINT64 Value, SYMBOL_BUFFER *StackBuffer, UINT64 *StackIndx, UINT64 *StackBaseIndx, UINT64 *ReturnValue)
Set the value.
Definition ScriptEngineEval.c:184
const vector< string > Split(const string &s, const char &c)
general split command
Definition common.cpp:117
BOOLEAN ConvertStringToUInt64(string TextToConvert, PUINT64 Result)
check and convert string to a 64 bit unsigned integer and also check for special notations like 0x,...
Definition common.cpp:240
BOOLEAN ConvertStringToUInt32(string TextToConvert, PUINT32 Result)
check and convert string to a 32 bit unsigned it and also check for special notations like 0x etc.
Definition common.cpp:347
RequestedActionOfThePacket Value(0x1) 00000000
BOOLEAN KdSendSearchRequestPacketToDebuggee(UINT64 *SearchRequestBuffer, UINT32 SearchRequestBufferSize)
Sends search query request packet to the debuggee.
Definition kd.cpp:1178
#define AssertShowMessageReturnStmt(expr, message, rc)
Definition common.h:51
#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID
Definition common.h:31
#define AssertReturn
Definition common.h:19
#define ASSERT_MESSAGE_DRIVER_NOT_LOADED
Definition common.h:25
HANDLE g_DeviceHandle
Holds the global handle of device which is used to send the request to the kernel by IOCTL,...
Definition globals.h:471
VOID ShowMessages(const char *Fmt,...)
Show messages.
Definition libhyperdbg.cpp:96
NULL()
Definition test-case-generator.py:530
VOID CommandSearchSendRequest(UINT64 *BufferToSendAsIoctl, UINT32 BufferToSendAsIoctlSize)
Send the request of search to the kernel.
Definition s.cpp:62
VOID CommandSearchMemoryHelp()
help of !s* s* commands
Definition s.cpp:26
BOOLEAN g_IsSerialConnectedToRemoteDebuggee
Shows if the debugger was connected to remote debuggee over (A remote guest)
Definition globals.h:231
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
State of active debugging thread.
Definition globals.h:362
UINT32 ProcessId
Definition ud.h:51
BOOLEAN IsActive
Definition ud.h:49
request for searching memory
Definition RequestStructures.h:527
UINT64 Length
Definition RequestStructures.h:529
UINT32 ProcessId
Definition RequestStructures.h:530
UINT32 CountOf64Chunks
Definition RequestStructures.h:533
UINT32 FinalStructureSize
Definition RequestStructures.h:534
UINT64 Address
Definition RequestStructures.h:528
DEBUGGER_SEARCH_MEMORY_BYTE_SIZE ByteSize
Definition RequestStructures.h:532
DEBUGGER_SEARCH_MEMORY_TYPE MemoryType
Definition RequestStructures.h:531
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:360

◆ CommandSearchMemoryHelp()

VOID CommandSearchMemoryHelp ( )

help of !s* s* commands

Returns
VOID
27{
28 ShowMessages("sb !sb sd !sd sq !sq : searches a contiguous memory for a "
29 "special byte pattern\n");
30 ShowMessages("sb Byte and ASCII characters\n");
31 ShowMessages("sd Double-word values (4 bytes)\n");
32 ShowMessages("sq Quad-word values (8 bytes). \n");
33
35 "\n If you want to search in physical (address) memory then add '!' "
36 "at the start of the command\n");
37
38 ShowMessages("syntax : \tsb [StartAddress (hex)] [l Length (hex)] [BytePattern (hex)] [pid ProcessId (hex)]\n");
39 ShowMessages("syntax : \tsd [StartAddress (hex)] [l Length (hex)] [BytePattern (hex)] [pid ProcessId (hex)]\n");
40 ShowMessages("syntax : \tsq [StartAddress (hex)] [l Length (hex)] [BytePattern (hex)] [pid ProcessId (hex)]\n");
41
42 ShowMessages("\n");
43 ShowMessages("\t\te.g : sb nt!ExAllocatePoolWithTag 90 85 95 l ffff \n");
44 ShowMessages("\t\te.g : sb nt!ExAllocatePoolWithTag+5 90 85 95 l ffff \n");
45 ShowMessages("\t\te.g : sb @rcx+5 90 85 95 l ffff \n");
46 ShowMessages("\t\te.g : sb fffff8077356f010 90 85 95 l ffff \n");
47 ShowMessages("\t\te.g : sd fffff8077356f010 90423580 l ffff pid 1c0 \n");
48 ShowMessages("\t\te.g : !sq 100000 9090909090909090 l ffff\n");
49 ShowMessages("\t\te.g : !sq @rdx+r12 9090909090909090 l ffff\n");
50 ShowMessages("\t\te.g : !sq 100000 9090909090909090 9090909090909090 "
51 "9090909090909090 l ffffff\n");
52}

◆ CommandSearchSendRequest()

VOID CommandSearchSendRequest ( UINT64 * BufferToSendAsIoctl,
UINT32 BufferToSendAsIoctlSize )

Send the request of search to the kernel.

Parameters
BufferToSendAsIoctl
BufferToSendAsIoctlSize
Returns
VOID
63{
64 BOOL Status;
65 UINT64 CurrentValue;
66 PUINT64 ResultsBuffer = NULL;
67
68 //
69 // Allocate a buffer to store the results
70 //
71 ResultsBuffer = (PUINT64)malloc(MaximumSearchResults * sizeof(UINT64));
72
73 //
74 // Also it's better to Zero the memory; however it's not necessary
75 // as we zero the buffer in the search routines
76 //
77 ZeroMemory(ResultsBuffer, MaximumSearchResults * sizeof(UINT64));
78
79 //
80 // Fire the IOCTL
81 //
82 Status =
83 DeviceIoControl(g_DeviceHandle, // Handle to device
84 IOCTL_DEBUGGER_SEARCH_MEMORY, // IO Control Code (IOCTL)
85 BufferToSendAsIoctl, // Input Buffer to driver.
86 BufferToSendAsIoctlSize, // Input buffer length
87 ResultsBuffer, // Output Buffer from driver.
89 sizeof(UINT64), // Length of output buffer in bytes.
90 NULL, // Bytes placed in buffer.
91 NULL // synchronous call
92 );
93
94 if (!Status)
95 {
96 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
97
98 free(ResultsBuffer);
99 return;
100 }
101
102 //
103 // Show the results (if any)
104 //
105 for (size_t i = 0; i < MaximumSearchResults; i++)
106 {
107 CurrentValue = ResultsBuffer[i];
108
109 if (CurrentValue == NULL)
110 {
111 //
112 // We ended up the buffer, nothing else to show,
113 // just check whether we found anything or not
114 //
115 if (i == 0)
116 {
117 ShowMessages("not found\n");
118 }
119 break;
120 }
121 ShowMessages("%llx\n", CurrentValue);
122 }
123
124 //
125 // Free buffer
126 //
127 free(ResultsBuffer);
128}
unsigned __int64 * PUINT64
Definition BasicTypes.h:21
#define MaximumSearchResults
maximum results that will be returned by !s* s* command
Definition Constants.h:514
#define IOCTL_DEBUGGER_SEARCH_MEMORY
ioctl, request to search virtual and physical memory
Definition Ioctls.h:141

Variable Documentation

◆ g_ActiveProcessDebuggingState

ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
extern

State of active debugging thread.

362{0};

◆ g_IsSerialConnectedToRemoteDebuggee

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
extern

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