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< string > SplitCommand, string Command)
 !e* and e* 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

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< string > SplitCommand,
string Command )

!e* and e* commands handler

Parameters
SplitCommand
Command
Returns
VOID
266{
268 UINT64 * FinalBuffer;
269 vector<UINT64> ValuesToEdit;
270 DEBUGGER_EDIT_MEMORY_TYPE MemoryType;
272 BOOL SetAddress = FALSE;
274 BOOL SetProcId = FALSE;
275 BOOL NextIsProcId = FALSE;
276 UINT64 Value = 0;
277 UINT32 ProcId = 0;
278 UINT32 CountOfValues = 0;
279 UINT32 FinalSize = 0;
280 vector<string> SplitCommandCaseSensitive {Split(Command, ' ')};
281 UINT32 IndexInCommandCaseSensitive = 0;
282 BOOLEAN IsFirstCommand = TRUE;
283
284 //
285 // By default if the user-debugger is active, we use these commands
286 // on the memory layout of the debuggee process
287 //
289 {
291 }
292
293 if (SplitCommand.size() <= 2)
294 {
295 ShowMessages("incorrect use of the 'e*'\n\n");
297 return;
298 }
299
300 for (auto Section : SplitCommand)
301 {
302 IndexInCommandCaseSensitive++;
303
304 if (IsFirstCommand)
305 {
306 if (!Section.compare("!eb"))
307 {
308 MemoryType = EDIT_PHYSICAL_MEMORY;
309 ByteSize = EDIT_BYTE;
310 }
311 else if (!Section.compare("!ed"))
312 {
313 MemoryType = EDIT_PHYSICAL_MEMORY;
314 ByteSize = EDIT_DWORD;
315 }
316 else if (!Section.compare("!eq"))
317 {
318 MemoryType = EDIT_PHYSICAL_MEMORY;
319 ByteSize = EDIT_QWORD;
320 }
321 else if (!Section.compare("eb"))
322 {
323 MemoryType = EDIT_VIRTUAL_MEMORY;
324 ByteSize = EDIT_BYTE;
325 }
326 else if (!Section.compare("ed"))
327 {
328 MemoryType = EDIT_VIRTUAL_MEMORY;
329 ByteSize = EDIT_DWORD;
330 }
331 else if (!Section.compare("eq"))
332 {
333 MemoryType = EDIT_VIRTUAL_MEMORY;
334 ByteSize = EDIT_QWORD;
335 }
336 else
337 {
338 //
339 // What's this? :(
340 //
341 ShowMessages("unknown error happened !\n\n");
343 return;
344 }
345
346 IsFirstCommand = FALSE;
347
348 continue;
349 }
350
351 if (NextIsProcId)
352 {
353 //
354 // It's a process id
355 //
356 NextIsProcId = FALSE;
357
358 if (!ConvertStringToUInt32(Section, &ProcId))
359 {
360 ShowMessages("please specify a correct hex process id\n\n");
362 return;
363 }
364 else
365 {
366 //
367 // Means that the proc id is set, next we should read value
368 //
369 continue;
370 }
371 }
372
373 //
374 // Check if it's a process id or not
375 //
376 if (!SetProcId && !Section.compare("pid"))
377 {
378 NextIsProcId = TRUE;
379 continue;
380 }
381
382 if (!SetAddress)
383 {
384 if (!SymbolConvertNameOrExprToAddress(SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1),
385 &Address))
386 {
387 ShowMessages("err, couldn't resolve error at '%s'\n\n",
388 SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1).c_str());
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 if (Section.rfind("0x", 0) == 0 || Section.rfind("0X", 0) == 0 ||
408 Section.rfind("\\x", 0) == 0 || Section.rfind("\\X", 0) == 0)
409 {
410 Section = Section.erase(0, 2);
411 }
412 else if (Section.rfind('x', 0) == 0 || Section.rfind('X', 0) == 0)
413 {
414 Section = Section.erase(0, 1);
415 }
416 Section.erase(remove(Section.begin(), Section.end(), '`'), Section.end());
417
418 //
419 // Check if the value is valid based on byte counts
420 //
421 if (ByteSize == EDIT_BYTE && Section.size() >= 3)
422 {
423 ShowMessages("please specify a byte (hex) value for 'eb' or '!eb'\n\n");
424 return;
425 }
426 if (ByteSize == EDIT_DWORD && Section.size() >= 9)
427 {
429 "please specify a dword (hex) value for 'ed' or '!ed'\n\n");
430 return;
431 }
432 if (ByteSize == EDIT_QWORD && Section.size() >= 17)
433 {
435 "please specify a qword (hex) value for 'eq' or '!eq'\n\n");
436 return;
437 }
438
439 //
440 // Qword is checked by the following function, no need to double
441 // check it above.
442 //
443
444 if (!ConvertStringToUInt64(Section, &Value))
445 {
446 ShowMessages("please specify a correct hex value to change the memory "
447 "content\n\n");
449 return;
450 }
451 else
452 {
453 //
454 // Add it to the list
455 //
456
457 ValuesToEdit.push_back(Value);
458
459 //
460 // Keep track of values to modify
461 //
462 CountOfValues++;
463
464 if (!SetValue)
465 {
466 //
467 // At least on value is there
468 //
469 SetValue = TRUE;
470 }
471 continue;
472 }
473 }
474 }
475
476 //
477 // Check to prevent using process id in e* commands
478 //
479 if (g_IsSerialConnectedToRemoteDebuggee && ProcId != 0)
480 {
482 return;
483 }
484
485 //
486 // Only valid for VMI Mode
487 //
488 if (ProcId == 0)
489 {
490 ProcId = GetCurrentProcessId();
491 }
492
493 //
494 // Check if address and value are set or not
495 //
496 if (!SetAddress)
497 {
498 ShowMessages("please specify a correct hex address\n\n");
500 return;
501 }
502 if (!SetValue)
503 {
505 "please specify a correct hex value as the content to edit\n\n");
507 return;
508 }
509 if (NextIsProcId)
510 {
511 ShowMessages("please specify a correct hex value as the process id\n\n");
513 return;
514 }
515
516 //
517 // Make the chunks for editing
518 //
519 FinalSize = (CountOfValues * sizeof(UINT64));
520
521 //
522 // Allocate structure + buffer
523 //
524 FinalBuffer = (UINT64 *)malloc(FinalSize);
525
526 if (!FinalBuffer)
527 {
528 ShowMessages("unable to allocate memory\n\n");
529 return;
530 }
531
532 //
533 // Zero the buffer
534 //
535 ZeroMemory(FinalBuffer, FinalSize);
536
537 //
538 // Put the values in 64 bit structures
539 //
540 std::copy(ValuesToEdit.begin(), ValuesToEdit.end(), FinalBuffer);
541
542 //
543 // Perform the write operation
544 //
546 MemoryType,
547 ByteSize,
548 ProcId,
549 CountOfValues,
550 FinalBuffer);
551
552 //
553 // Free the malloc buffer
554 //
555 free(FinalBuffer);
556}
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
@ EDIT_PHYSICAL_MEMORY
Definition RequestStructures.h:463
@ EDIT_VIRTUAL_MEMORY
Definition RequestStructures.h:462
enum _DEBUGGER_EDIT_MEMORY_TYPE DEBUGGER_EDIT_MEMORY_TYPE
different type of addresses for editing memory
@ EDIT_QWORD
Definition RequestStructures.h:474
@ EDIT_DWORD
Definition RequestStructures.h:473
@ EDIT_BYTE
Definition RequestStructures.h:472
enum _DEBUGGER_EDIT_MEMORY_BYTE_SIZE DEBUGGER_EDIT_MEMORY_BYTE_SIZE
size of editing memory
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
VOID CommandEditMemoryHelp()
help of !e* and e* commands
Definition e.cpp:26
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:64
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
RequestedActionOfThePacket Value(0x1) 00000000
#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID
Definition common.h:31
VOID ShowMessages(const char *Fmt,...)
Show messages.
Definition libhyperdbg.cpp:96
UINT32 ProcessId
Definition ud.h:51
BOOLEAN IsActive
Definition ud.h:49
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

◆ CommandEditMemoryHelp()

VOID CommandEditMemoryHelp ( )

help of !e* and e* commands

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

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

◆ 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
70{
71 BOOL Status;
72 BOOLEAN StatusReturn = FALSE;
73 DEBUGGER_EDIT_MEMORY * FinalBuffer;
74 DEBUGGER_EDIT_MEMORY EditMemoryRequest = {0};
75 UINT32 FinalSize = 0;
76
77 //
78 // Check if driver is loaded if it's in VMI mode
79 //
81 {
83 }
84
85 //
86 // Fill the structure
87 //
88 EditMemoryRequest.ProcessId = Pid;
89 EditMemoryRequest.Address = AddressToEdit;
90 EditMemoryRequest.CountOf64Chunks = CountOf64Chunks;
91 EditMemoryRequest.MemoryType = MemoryType;
92 EditMemoryRequest.ByteSize = ByteSize;
93
94 //
95 // Now it's time to put everything together in one structure
96 //
97 FinalSize = (CountOf64Chunks * sizeof(UINT64)) + SIZEOF_DEBUGGER_EDIT_MEMORY;
98
99 //
100 // Set the size
101 //
102 EditMemoryRequest.FinalStructureSize = FinalSize;
103
104 //
105 // Allocate structure + buffer
106 //
107 FinalBuffer = (DEBUGGER_EDIT_MEMORY *)malloc(FinalSize);
108
109 if (!FinalBuffer)
110 {
111 ShowMessages("unable to allocate memory\n\n");
112 return FALSE;
113 }
114
115 //
116 // Zero the buffer
117 //
118 ZeroMemory(FinalBuffer, FinalSize);
119
120 //
121 // Copy the structure on top of the allocated buffer
122 //
123 memcpy((PVOID)FinalBuffer, &EditMemoryRequest, SIZEOF_DEBUGGER_EDIT_MEMORY);
124
125 //
126 // Copy the values to the buffer
127 //
128 memcpy((UINT64 *)((UINT64)FinalBuffer + SIZEOF_DEBUGGER_EDIT_MEMORY), BufferToEdit, (CountOf64Chunks * sizeof(UINT64)));
129
130 //
131 // send the request
132 //
134 {
135 if (!KdSendEditMemoryPacketToDebuggee(FinalBuffer, FinalSize))
136 {
137 free(FinalBuffer);
138 return FALSE;
139 }
140 }
141 else
142 {
143 Status = DeviceIoControl(
144 g_DeviceHandle, // Handle to device
145 IOCTL_DEBUGGER_EDIT_MEMORY, // IO Control Code (IOCTL)
146 FinalBuffer, // Input Buffer to driver.
147 FinalSize, // Input buffer length
148 FinalBuffer, // Output Buffer from driver.
149 SIZEOF_DEBUGGER_EDIT_MEMORY, // Length of output buffer in bytes.
150 NULL, // Bytes placed in buffer.
151 NULL // synchronous call
152 );
153
154 if (!Status)
155 {
156 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
157 free(FinalBuffer);
158 return FALSE;
159 }
160 }
161
162 //
163 // Check the result
164 //
165 if (FinalBuffer->Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
166 {
167 //
168 // Was successful, nothing to do
169 //
170 free(FinalBuffer);
171 return TRUE;
172 }
173 else
174 {
175 ShowErrorMessage(FinalBuffer->Result);
176 free(FinalBuffer);
177 return FALSE;
178 }
179}
#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:134
#define SIZEOF_DEBUGGER_EDIT_MEMORY
Definition RequestStructures.h:454
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:38
BOOLEAN KdSendEditMemoryPacketToDebuggee(PDEBUGGER_EDIT_MEMORY EditMem, UINT32 Size)
Send an Edit memory packet to the debuggee.
Definition kd.cpp:633
#define AssertShowMessageReturnStmt(expr, message, rc)
Definition common.h:51
#define ASSERT_MESSAGE_DRIVER_NOT_LOADED
Definition common.h:25
#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:471
request for edit virtual and physical memory
Definition RequestStructures.h:482
UINT32 Result
Definition RequestStructures.h:483
UINT64 Address
Definition RequestStructures.h:484
DEBUGGER_EDIT_MEMORY_TYPE MemoryType
Definition RequestStructures.h:486
UINT32 CountOf64Chunks
Definition RequestStructures.h:488
UINT32 ProcessId
Definition RequestStructures.h:485
UINT32 FinalStructureSize
Definition RequestStructures.h:489
DEBUGGER_EDIT_MEMORY_BYTE_SIZE ByteSize
Definition RequestStructures.h:487

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)