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

e* command More...

#include "pch.h"

Functions

VOID CommandEditMemoryHelp ()
 help of !e* and e* commands
BOOLEAN WriteMemoryContent (UINT64 AddressToEdit, DEBUGGER_EDIT_MEMORY_TYPE MemoryType, DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize, UINT32 Pid, UINT32 CountOf64Chunks, UINT64 *BufferToEdit)
 Perform writing the memory content.
BOOLEAN HyperDbgWriteMemory (PVOID DestinationAddress, DEBUGGER_EDIT_MEMORY_TYPE MemoryType, UINT32 ProcessId, PVOID SourceAddress, UINT32 NumberOfBytes)
 API function for writing the memory content.
VOID CommandEditMemory (vector< CommandToken > CommandTokens, string Command)
 !e* and e* commands handler

Variables

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
 Shows if the debugger was connected to remote debuggee over (A remote guest).
BOOLEAN g_IsKdModuleLoaded
 shows whether the kernel debugger (KD) module is loaded or not
BOOLEAN g_IsVmmModuleLoaded
 shows whether the VMM module is loaded or not
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
 State of active debugging thread.

Detailed Description

e* command

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

Function Documentation

◆ CommandEditMemory()

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

!e* and e* commands handler

Parameters
CommandTokens
Command
Returns
VOID
270{
271 UINT64 Address;
272 UINT64 * FinalBuffer;
273 vector<UINT64> ValuesToEdit;
274 DEBUGGER_EDIT_MEMORY_TYPE MemoryType;
276 BOOL SetAddress = FALSE;
278 BOOL SetProcId = FALSE;
279 BOOL NextIsProcId = FALSE;
280 UINT64 Value = 0;
281 UINT32 ProcId = 0;
282 UINT32 CountOfValues = 0;
283 UINT32 FinalSize = 0;
284 BOOLEAN IsFirstCommand = TRUE;
285
286 //
287 // By default if the user-debugger is active, we use these commands
288 // on the memory layout of the debuggee process
289 //
291 {
292 ProcId = g_ActiveProcessDebuggingState.ProcessId;
293 }
294
295 if (CommandTokens.size() <= 2)
296 {
297 ShowMessages("incorrect use of the '%s'\n\n",
298 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
300 return;
301 }
302
303 for (auto Section : CommandTokens)
304 {
305 if (IsFirstCommand)
306 {
307 if (CompareLowerCaseStrings(Section, "!eb"))
308 {
309 MemoryType = EDIT_PHYSICAL_MEMORY;
310 ByteSize = EDIT_BYTE;
311 }
312 else if (CompareLowerCaseStrings(Section, "!ed"))
313 {
314 MemoryType = EDIT_PHYSICAL_MEMORY;
315 ByteSize = EDIT_DWORD;
316 }
317 else if (CompareLowerCaseStrings(Section, "!eq"))
318 {
319 MemoryType = EDIT_PHYSICAL_MEMORY;
320 ByteSize = EDIT_QWORD;
321 }
322 else if (CompareLowerCaseStrings(Section, "eb"))
323 {
324 MemoryType = EDIT_VIRTUAL_MEMORY;
325 ByteSize = EDIT_BYTE;
326 }
327 else if (CompareLowerCaseStrings(Section, "ed"))
328 {
329 MemoryType = EDIT_VIRTUAL_MEMORY;
330 ByteSize = EDIT_DWORD;
331 }
332 else if (CompareLowerCaseStrings(Section, "eq"))
333 {
334 MemoryType = EDIT_VIRTUAL_MEMORY;
335 ByteSize = EDIT_QWORD;
336 }
337 else
338 {
339 //
340 // What's this? :(
341 //
342 ShowMessages("unknown error happened !\n\n");
344 return;
345 }
346
347 IsFirstCommand = FALSE;
348
349 continue;
350 }
351
352 if (NextIsProcId)
353 {
354 //
355 // It's a process id
356 //
357 NextIsProcId = FALSE;
358
359 if (!ConvertTokenToUInt32(Section, &ProcId))
360 {
361 ShowMessages("please specify a correct hex process id\n\n");
363 return;
364 }
365 else
366 {
367 //
368 // Means that the proc id is set, next we should read value
369 //
370 continue;
371 }
372 }
373
374 //
375 // Check if it's a process id or not
376 //
377 if (!SetProcId && CompareLowerCaseStrings(Section, "pid"))
378 {
379 NextIsProcId = TRUE;
380 continue;
381 }
382
383 if (!SetAddress)
384 {
386 {
387 ShowMessages("err, couldn't resolve error at '%s'\n\n",
390 return;
391 }
392 else
393 {
394 //
395 // Means that the address is set, next we should read value
396 //
397 SetAddress = TRUE;
398 continue;
399 }
400 }
401
402 if (SetAddress)
403 {
404 //
405 // Remove the hex notations
406 //
407 std::string TargetVal = GetCaseSensitiveStringFromCommandToken(Section);
408
409 if (TargetVal.rfind("0x", 0) == 0 || TargetVal.rfind("0X", 0) == 0 ||
410 TargetVal.rfind("\\x", 0) == 0 || TargetVal.rfind("\\X", 0) == 0)
411 {
412 TargetVal = TargetVal.erase(0, 2);
413 }
414 else if (TargetVal.rfind('x', 0) == 0 || TargetVal.rfind('X', 0) == 0)
415 {
416 TargetVal = TargetVal.erase(0, 1);
417 }
418
419 TargetVal.erase(remove(TargetVal.begin(), TargetVal.end(), '`'), TargetVal.end());
420
421 //
422 // Check if the value is valid based on byte counts
423 //
424 if (ByteSize == EDIT_BYTE && TargetVal.size() >= 3)
425 {
426 ShowMessages("please specify a byte (hex) value for 'eb' or '!eb'\n\n");
427 return;
428 }
429 if (ByteSize == EDIT_DWORD && TargetVal.size() >= 9)
430 {
431 ShowMessages(
432 "please specify a dword (hex) value for 'ed' or '!ed'\n\n");
433 return;
434 }
435 if (ByteSize == EDIT_QWORD && TargetVal.size() >= 17)
436 {
437 ShowMessages(
438 "please specify a qword (hex) value for 'eq' or '!eq'\n\n");
439 return;
440 }
441
442 //
443 // Qword is checked by the following function, no need to double
444 // check it above.
445 //
446
447 if (!ConvertStringToUInt64(TargetVal, &Value))
448 {
449 ShowMessages("please specify a correct hex value to change the memory "
450 "content\n\n");
452 return;
453 }
454 else
455 {
456 //
457 // Add it to the list
458 //
459
460 ValuesToEdit.push_back(Value);
461
462 //
463 // Keep track of values to modify
464 //
465 CountOfValues++;
466
467 if (!SetValue)
468 {
469 //
470 // At least on value is there
471 //
472 SetValue = TRUE;
473 }
474 continue;
475 }
476 }
477 }
478
479 //
480 // Check to prevent using process id in e* commands
481 //
482 if (g_IsSerialConnectedToRemoteDebuggee && ProcId != 0)
483 {
485 return;
486 }
487
488 //
489 // Only valid for VMI Mode
490 //
491 if (ProcId == 0)
492 {
493 ProcId = GetCurrentProcessId();
494 }
495
496 //
497 // Check if address and value are set or not
498 //
499 if (!SetAddress)
500 {
501 ShowMessages("please specify a correct hex address\n\n");
503 return;
504 }
505 if (!SetValue)
506 {
507 ShowMessages(
508 "please specify a correct hex value as the content to edit\n\n");
510 return;
511 }
512 if (NextIsProcId)
513 {
514 ShowMessages("please specify a correct hex value as the process id\n\n");
516 return;
517 }
518
519 //
520 // Make the chunks for editing
521 //
522 FinalSize = (CountOfValues * sizeof(UINT64));
523
524 //
525 // Allocate structure + buffer
526 //
527 FinalBuffer = (UINT64 *)malloc(FinalSize);
528
529 if (!FinalBuffer)
530 {
531 ShowMessages("unable to allocate memory\n\n");
532 return;
533 }
534
535 //
536 // Zero the buffer
537 //
538 ZeroMemory(FinalBuffer, FinalSize);
539
540 //
541 // Put the values in 64 bit structures
542 //
543 std::copy(ValuesToEdit.begin(), ValuesToEdit.end(), FinalBuffer);
544
545 //
546 // Perform the write operation
547 //
548 WriteMemoryContent(Address,
549 MemoryType,
550 ByteSize,
551 ProcId,
552 CountOfValues,
553 FinalBuffer);
554
555 //
556 // Free the malloc buffer
557 //
558 free(FinalBuffer);
559}
VOID SetValue(PGUEST_REGS GuestRegs, SCRIPT_ENGINE_GENERAL_REGISTERS *ScriptGeneralRegisters, PSYMBOL Symbol, UINT64 Value)
Set the value.
Definition ScriptEngineEval.c:185
BOOLEAN g_IsSerialConnectedToRemoteDebuggee
Shows if the debugger was connected to remote debuggee over (A remote guest).
Definition globals.h:253
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
State of active debugging thread.
Definition globals.h:372
int BOOL
Definition BasicTypes.h:25
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
@ EDIT_PHYSICAL_MEMORY
Definition RequestStructures.h:483
@ EDIT_VIRTUAL_MEMORY
Definition RequestStructures.h:482
enum _DEBUGGER_EDIT_MEMORY_TYPE DEBUGGER_EDIT_MEMORY_TYPE
different type of addresses for editing memory
@ EDIT_QWORD
Definition RequestStructures.h:494
@ EDIT_DWORD
Definition RequestStructures.h:493
@ EDIT_BYTE
Definition RequestStructures.h:492
enum _DEBUGGER_EDIT_MEMORY_BYTE_SIZE DEBUGGER_EDIT_MEMORY_BYTE_SIZE
size of editing memory
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
VOID CommandEditMemoryHelp()
help of !e* and e* commands
Definition e.cpp:28
BOOLEAN WriteMemoryContent(UINT64 AddressToEdit, DEBUGGER_EDIT_MEMORY_TYPE MemoryType, DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize, UINT32 Pid, UINT32 CountOf64Chunks, UINT64 *BufferToEdit)
Perform writing the memory content.
Definition e.cpp:66
RequestedActionOfThePacket Value(0x1) 00000000
#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID
Definition common.h:39
BOOLEAN ConvertStringToUInt64(string TextToConvert, PUINT64 Result)
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

◆ CommandEditMemoryHelp()

VOID CommandEditMemoryHelp ( )

help of !e* and e* commands

Returns
VOID
29{
30 ShowMessages("eb !eb ed !ed eq !eq : edits the memory at specific address \n");
31 ShowMessages("eb Byte and ASCII characters\n");
32 ShowMessages("ed Double-word values (4 bytes)\n");
33 ShowMessages("eq Quad-word values (8 bytes). \n");
34
35 ShowMessages("\n If you want to edit physical (address) memory then add '!' "
36 "at the start of the command\n");
37
38 ShowMessages("syntax : \teb [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
39 ShowMessages("syntax : \ted [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
40 ShowMessages("syntax : \teq [Address (hex)] [Contents (hex)] [pid ProcessId (hex)]\n");
41
42 ShowMessages("\n");
43 ShowMessages("\t\te.g : eb fffff8077356f010 90 \n");
44 ShowMessages("\t\te.g : eb nt!Kd_DEFAULT_Mask ff ff ff ff \n");
45 ShowMessages("\t\te.g : eb nt!Kd_DEFAULT_Mask+10+@rcx ff ff ff ff \n");
46 ShowMessages("\t\te.g : eb fffff8077356f010 90 90 90 90 \n");
47 ShowMessages("\t\te.g : !eq 100000 9090909090909090\n");
48 ShowMessages("\t\te.g : !eq nt!ExAllocatePoolWithTag+55 9090909090909090\n");
49 ShowMessages("\t\te.g : !eq 100000 9090909090909090 9090909090909090 "
50 "9090909090909090 9090909090909090 9090909090909090\n");
51}

◆ HyperDbgWriteMemory()

BOOLEAN HyperDbgWriteMemory ( PVOID DestinationAddress,
DEBUGGER_EDIT_MEMORY_TYPE MemoryType,
UINT32 ProcessId,
PVOID SourceAddress,
UINT32 NumberOfBytes )

API function for writing the memory content.

Parameters
AddressToEdit
MemoryType
ProcessId
SourceAddress
NumberOfBytes
Returns
BOOLEAN
201{
202 UINT32 RequiredBytes = 0;
204 UINT64 * TargetBuffer;
205 UINT32 FinalSize = 0;
206 BOOLEAN Result = FALSE;
207 BYTE * BufferToEdit = (BYTE *)SourceAddress;
208
209 //
210 // Set the byte size to byte granularity
211 //
212 ByteSize = EDIT_BYTE;
213
214 //
215 // Calculate the count of 64 chunks
216 //
217 RequiredBytes = NumberOfBytes * sizeof(UINT64);
218
219 //
220 // Allocate structure + buffer
221 //
222 TargetBuffer = (UINT64 *)malloc(RequiredBytes);
223
224 if (!TargetBuffer)
225 {
226 return FALSE;
227 }
228
229 //
230 // Zero the buffer
231 //
232 ZeroMemory(TargetBuffer, FinalSize);
233
234 //
235 // Copy requested memory in 64bit chunks
236 //
237 for (SIZE_T i = 0; i < NumberOfBytes; i++)
238 {
239 TargetBuffer[i] = BufferToEdit[i];
240 }
241
242 //
243 // Perform the write operation
244 //
245 Result = WriteMemoryContent((UINT64)DestinationAddress,
246 MemoryType,
247 ByteSize,
248 ProcessId,
250 TargetBuffer);
251
252 //
253 // Free the malloc buffer
254 //
255 free(TargetBuffer);
256
257 return Result;
258}
POOL_TYPE SIZE_T NumberOfBytes
Definition Hooks.h:88
unsigned char BYTE
Definition BasicTypes.h:40

◆ WriteMemoryContent()

BOOLEAN WriteMemoryContent ( UINT64 AddressToEdit,
DEBUGGER_EDIT_MEMORY_TYPE MemoryType,
DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize,
UINT32 Pid,
UINT32 CountOf64Chunks,
UINT64 * BufferToEdit )

Perform writing the memory content.

Parameters
AddressToEdit
MemoryType
ByteSize
Pid
CountOf64Chunks
BufferToEdit
Returns
BOOLEAN
72{
73 BOOL Status;
74 DWORD BytesReturned;
75 BOOLEAN StatusReturn = FALSE;
76 DEBUGGER_EDIT_MEMORY * FinalBuffer;
77 DEBUGGER_EDIT_MEMORY EditMemoryRequest = {0};
78 UINT32 FinalSize = 0;
79
80 //
81 // Check if driver is loaded if it's in VMI mode
82 //
84 {
86 }
87
88 //
89 // Fill the structure
90 //
91 EditMemoryRequest.ProcessId = Pid;
92 EditMemoryRequest.Address = AddressToEdit;
93 EditMemoryRequest.CountOf64Chunks = CountOf64Chunks;
94 EditMemoryRequest.MemoryType = MemoryType;
95 EditMemoryRequest.ByteSize = ByteSize;
96
97 //
98 // Now it's time to put everything together in one structure
99 //
100 FinalSize = (CountOf64Chunks * sizeof(UINT64)) + SIZEOF_DEBUGGER_EDIT_MEMORY;
101
102 //
103 // Set the size
104 //
105 EditMemoryRequest.FinalStructureSize = FinalSize;
106
107 //
108 // Allocate structure + buffer
109 //
110 FinalBuffer = (DEBUGGER_EDIT_MEMORY *)malloc(FinalSize);
111
112 if (!FinalBuffer)
113 {
114 ShowMessages("unable to allocate memory\n\n");
115 return FALSE;
116 }
117
118 //
119 // Zero the buffer
120 //
121 ZeroMemory(FinalBuffer, FinalSize);
122
123 //
124 // Copy the structure on top of the allocated buffer
125 //
126 memcpy((PVOID)FinalBuffer, &EditMemoryRequest, SIZEOF_DEBUGGER_EDIT_MEMORY);
127
128 //
129 // Copy the values to the buffer
130 //
131 memcpy((UINT64 *)((UINT64)FinalBuffer + SIZEOF_DEBUGGER_EDIT_MEMORY), BufferToEdit, (CountOf64Chunks * sizeof(UINT64)));
132
133 //
134 // send the request
135 //
137 {
138 if (!KdSendEditMemoryPacketToDebuggee(FinalBuffer, FinalSize))
139 {
140 free(FinalBuffer);
141 return FALSE;
142 }
143 }
144 else
145 {
146 Status = DeviceIoControl(
147 g_DeviceHandle, // Handle to device
148 IOCTL_DEBUGGER_EDIT_MEMORY, // IO Control Code (IOCTL)
149 FinalBuffer, // Input Buffer to driver.
150 FinalSize, // Input buffer length
151 FinalBuffer, // Output Buffer from driver.
152 SIZEOF_DEBUGGER_EDIT_MEMORY, // Length of output buffer in bytes.
153 &BytesReturned, // Bytes placed in buffer.
154 NULL // synchronous call
155 );
156
157 if (!Status)
158 {
159 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
160 free(FinalBuffer);
161 return FALSE;
162 }
163 }
164
165 //
166 // Check the result
167 //
168 if (FinalBuffer->Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
169 {
170 //
171 // Was successful, nothing to do
172 //
173 free(FinalBuffer);
174 return TRUE;
175 }
176 else
177 {
178 ShowErrorMessage(FinalBuffer->Result);
179 free(FinalBuffer);
180 return FALSE;
181 }
182}
void * PVOID
Definition BasicTypes.h:56
unsigned long DWORD
Definition BasicTypes.h:38
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
#define IOCTL_DEBUGGER_EDIT_MEMORY
ioctl, request to edit virtual and physical memory
Definition Ioctls.h:192
#define SIZEOF_DEBUGGER_EDIT_MEMORY
Definition RequestStructures.h:474
struct _DEBUGGER_EDIT_MEMORY DEBUGGER_EDIT_MEMORY
request for edit virtual and physical memory
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:40
BOOLEAN KdSendEditMemoryPacketToDebuggee(PDEBUGGER_EDIT_MEMORY EditMem, UINT32 Size)
Send an Edit memory packet to the debuggee.
Definition kd.cpp:633
#define ASSERT_MESSAGE_KD_NOT_LOADED
Definition common.h:29
#define AssertShowMessageReturnStmt(expr1, expr2, message1, message2, rc)
Definition common.h:59
#define ASSERT_MESSAGE_DRIVER_NOT_LOADED
Definition common.h:27
#define AssertReturnFalse
Definition common.h:21
HANDLE g_DeviceHandle
Holds the global handle of device which is used to send the request to the kernel by IOCTL,...
Definition globals.h:481
BOOLEAN g_IsKdModuleLoaded
shows whether the kernel debugger (KD) module is loaded or not
Definition globals.h:22
UINT32 Result
Definition RequestStructures.h:503
UINT64 Address
Definition RequestStructures.h:504
DEBUGGER_EDIT_MEMORY_TYPE MemoryType
Definition RequestStructures.h:506
UINT32 CountOf64Chunks
Definition RequestStructures.h:508
UINT32 ProcessId
Definition RequestStructures.h:505
UINT32 FinalStructureSize
Definition RequestStructures.h:509
DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize
Definition RequestStructures.h:507

Variable Documentation

◆ g_ActiveProcessDebuggingState

ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
extern

State of active debugging thread.

372{0};

◆ g_IsKdModuleLoaded

BOOLEAN g_IsKdModuleLoaded
extern

shows whether the kernel debugger (KD) module is loaded or not

◆ g_IsSerialConnectedToRemoteDebuggee

BOOLEAN g_IsSerialConnectedToRemoteDebuggee
extern

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

◆ g_IsVmmModuleLoaded

BOOLEAN g_IsVmmModuleLoaded
extern

shows whether the VMM module is loaded or not