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

.pagein command More...

#include "pch.h"

Functions

VOID CommandPageinHelp ()
 help of the .pagein command
BOOLEAN CommandPageinCheckAndInterpretModeString (const std::string &ModeString, PAGE_FAULT_EXCEPTION *PageFaultErrorCode)
 Check whether the mode string is valid or not.
VOID CommandPageinRequest (UINT64 TargetVirtualAddrFrom, UINT64 TargetVirtualAddrTo, PAGE_FAULT_EXCEPTION PageFaultErrorCode, UINT32 Pid)
 request to bring the page(s) in
VOID CommandPagein (vector< CommandToken > CommandTokens, string Command)
 .pagein command handler

Variables

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

Detailed Description

.pagein command

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.4
Date
2023-07-11

Function Documentation

◆ CommandPagein()

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

.pagein command handler

Parameters
CommandTokens
Command
Returns
VOID
267{
268 UINT32 Pid = 0;
269 UINT64 Length = 0;
270 UINT64 TargetAddressFrom = NULL;
271 UINT64 TargetAddressTo = NULL;
272 BOOLEAN IsNextProcessId = FALSE;
273 BOOLEAN IsFirstCommand = TRUE;
274 BOOLEAN IsNextLength = FALSE;
275 PAGE_FAULT_EXCEPTION PageFaultErrorCode = {0};
276
277 //
278 // By default if the user-debugger is active, we use these commands
279 // on the memory layout of the debuggee process
280 //
282 {
283 Pid = g_ActiveProcessDebuggingState.ProcessId;
284 }
285
286 if (CommandTokens.size() == 1)
287 {
288 //
289 // Means that user entered one command without any parameter
290 //
291 ShowMessages("incorrect use of the '%s'\n\n",
292 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
294 return;
295 }
296
297 for (auto Section : CommandTokens)
298 {
299 if (IsFirstCommand)
300 {
301 IsFirstCommand = FALSE;
302 continue;
303 }
304 if (IsNextProcessId == TRUE)
305 {
306 if (!ConvertTokenToUInt32(Section, &Pid))
307 {
308 ShowMessages("err, you should enter a valid process id\n\n");
309 return;
310 }
311 IsNextProcessId = FALSE;
312 continue;
313 }
314
315 if (IsNextLength == TRUE)
316 {
318 {
319 ShowMessages("err, you should enter a valid length\n\n");
320 return;
321 }
322 IsNextLength = FALSE;
323 continue;
324 }
325
326 if (CompareLowerCaseStrings(Section, "l"))
327 {
328 IsNextLength = TRUE;
329 continue;
330 }
331
332 // if (CompareLowerCaseStrings(Section, "pid"))
333 // {
334 // IsNextProcessId = TRUE;
335 // continue;
336 // }
337
338 //
339 // Probably it's address or mode string
340 //
341
343 {
344 continue;
345 }
346 else if (TargetAddressFrom == 0)
347 {
349 &TargetAddressFrom))
350 {
351 //
352 // Couldn't resolve or unknown parameter
353 //
354 ShowMessages("err, couldn't resolve error at '%s'\n",
356 return;
357 }
358 }
359 else
360 {
361 //
362 // User inserts two address
363 //
364 ShowMessages("err, incorrect use of the '.pagein' command\n\n");
366
367 return;
368 }
369 }
370
371 if (!TargetAddressFrom)
372 {
373 //
374 // User inserts two address
375 //
376 ShowMessages("err, please enter a valid address\n\n");
377
378 return;
379 }
380
381 if (IsNextLength || IsNextProcessId)
382 {
383 ShowMessages("incorrect use of the '%s'\n\n",
384 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
386 return;
387 }
388
389 //
390 // If the user didn't specified a range, then only one page will be
391 // paged-in; so we use the same AddressFrom and AddressTo
392 //
393 if (Length == 0)
394 {
395 TargetAddressTo = TargetAddressFrom;
396 }
397 else
398 {
399 TargetAddressTo = TargetAddressFrom + Length;
400 }
401
402 //
403 // Send the request
404 //
405 // ShowMessages(".pagin address from: %llx -> to %llx, page-fault code: 0x%x, pid: %x, length: 0x%llx",
406 // TargetAddressFrom,
407 // TargetAddressTo,
408 // PageFaultErrorCode.AsUInt,
409 // Pid,
410 // Length);
411
412 //
413 // Request the page-in
414 //
415 CommandPageinRequest(TargetAddressFrom,
416 TargetAddressTo,
417 PageFaultErrorCode,
418 Pid);
419}
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
State of active debugging thread.
Definition globals.h:372
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
std::string GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken)
Get case sensitive string from command token.
Definition common.cpp:467
std::string GetLowerStringFromCommandToken(CommandToken TargetToken)
Get lower case string from command token.
Definition common.cpp:484
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
NULL()
Definition test-case-generator.py:530
VOID CommandPageinHelp()
help of the .pagein command
Definition pagein.cpp:27
BOOLEAN CommandPageinCheckAndInterpretModeString(const std::string &ModeString, PAGE_FAULT_EXCEPTION *PageFaultErrorCode)
Check whether the mode string is valid or not.
Definition pagein.cpp:82
VOID CommandPageinRequest(UINT64 TargetVirtualAddrFrom, UINT64 TargetVirtualAddrTo, PAGE_FAULT_EXCEPTION PageFaultErrorCode, UINT32 Pid)
request to bring the page(s) in
Definition pagein.cpp:172
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

◆ CommandPageinCheckAndInterpretModeString()

BOOLEAN CommandPageinCheckAndInterpretModeString ( const std::string & ModeString,
PAGE_FAULT_EXCEPTION * PageFaultErrorCode )

Check whether the mode string is valid or not.

Parameters
ModeString
PageFaultErrorCode
Returns
BOOLEAN
84{
85 std::unordered_set<CHAR> AllowedChars = {'p', 'w', 'u', 'f', 'k', 's', 'h', 'g'};
86 std::unordered_set<CHAR> FoundChars;
87
88 for (CHAR c : ModeString)
89 {
90 if (AllowedChars.count(c) == 0)
91 {
92 //
93 // Found a character that is not allowed
94 //
95 return FALSE;
96 }
97
98 if (FoundChars.count(c) > 0)
99 {
100 //
101 // Found a character more than once
102 //
103 return FALSE;
104 }
105
106 FoundChars.insert(c);
107 }
108
109 //
110 // All checks passed, let's interpret the page-fault code
111 //
112 for (CHAR c : ModeString)
113 {
114 if (c == 'p')
115 {
116 PageFaultErrorCode->Present = TRUE;
117 }
118 else if (c == 'w')
119 {
120 PageFaultErrorCode->Write = TRUE;
121 }
122 else if (c == 'u')
123 {
124 PageFaultErrorCode->UserModeAccess = TRUE;
125 }
126 else if (c == 'f')
127 {
128 PageFaultErrorCode->Execute = TRUE;
129 }
130 else if (c == 'k')
131 {
132 PageFaultErrorCode->ProtectionKeyViolation = TRUE;
133 }
134 else if (c == 's')
135 {
136 PageFaultErrorCode->ShadowStack = TRUE;
137 }
138 else if (c == 'h')
139 {
140 PageFaultErrorCode->Hlat = TRUE;
141 }
142 else if (c == 'g')
143 {
144 PageFaultErrorCode->Sgx = TRUE;
145 }
146 else
147 {
148 //
149 // Something went wrong, generally we shouldn't reach here
150 //
151 return FALSE;
152 }
153 }
154
155 //
156 // All checks passed, and the page-fault code is interpreted
157 //
158 return TRUE;
159}
char CHAR
Definition BasicTypes.h:33

◆ CommandPageinHelp()

VOID CommandPageinHelp ( )

help of the .pagein command

Returns
VOID
28{
29 ShowMessages(".pagein : brings the page in, making it available in the RAM.\n\n");
30
31 ShowMessages("syntax : \t.pagein [Mode (string)] [l Length (hex)]\n");
32 ShowMessages("syntax : \t.pagein [Mode (string)] [VirtualAddress (hex)] [l Length (hex)]\n");
33
34 ShowMessages("\n");
35 ShowMessages("\t\te.g : .pagein fffff801deadbeef\n");
36 ShowMessages("\t\te.g : .pagein 00007ff8349f2224 l 1a000\n");
37 ShowMessages("\t\te.g : .pagein u 00007ff8349f2224\n");
38 ShowMessages("\t\te.g : .pagein w 00007ff8349f2224\n");
39 ShowMessages("\t\te.g : .pagein f 00007ff8349f2224\n");
40 ShowMessages("\t\te.g : .pagein pw 00007ff8349f2224\n");
41 ShowMessages("\t\te.g : .pagein wu 00007ff8349f2224\n");
42 ShowMessages("\t\te.g : .pagein wu 00007ff8349f2224 l 6000\n");
43 ShowMessages("\t\te.g : .pagein pf @rax\n");
44 ShowMessages("\t\te.g : .pagein uf @rip+@rcx\n");
45 ShowMessages("\t\te.g : .pagein pwu @rax+5\n");
46 ShowMessages("\t\te.g : .pagein pwu @rax l 2000\n");
47
48 ShowMessages("\n");
49 ShowMessages("valid mode formats: \n");
50
51 ShowMessages("\tp : present\n");
52 ShowMessages("\tw : write\n");
53 ShowMessages("\tu : user\n");
54 ShowMessages("\tf : fetch\n");
55 ShowMessages("\tk : protection key\n");
56 ShowMessages("\ts : shadow stack\n");
57 ShowMessages("\th : hlat\n");
58 ShowMessages("\tg : sgx\n");
59
60 ShowMessages("\n");
61 ShowMessages("common page-fault codes: \n");
62
63 ShowMessages("\t0x0: (default)\n");
64 ShowMessages("\t0x2: w (write access fault)\n");
65 ShowMessages("\t0x3: pw (present, write access fault)\n");
66 ShowMessages("\t0x4: u (user access fault)\n");
67 ShowMessages("\t0x6: wu (write, user access fault)\n");
68 ShowMessages("\t0x7: pwu (present, write, user access fault)\n");
69 ShowMessages("\t0x10: f (fetch instruction fault)\n");
70 ShowMessages("\t0x11: pf (present, fetch instruction fault)\n");
71 ShowMessages("\t0x14: uf (user, fetch instruction fault)\n");
72}

◆ CommandPageinRequest()

VOID CommandPageinRequest ( UINT64 TargetVirtualAddrFrom,
UINT64 TargetVirtualAddrTo,
PAGE_FAULT_EXCEPTION PageFaultErrorCode,
UINT32 Pid )

request to bring the page(s) in

Parameters
TargetVirtualAddrFrom
TargetVirtualAddrTo
PageFaultErrorCode
Pid
Returns
VOID
176{
177 BOOL Status;
178 ULONG ReturnedLength;
179 DEBUGGER_PAGE_IN_REQUEST PageFaultRequest = {0};
180
181 //
182 // Prepare the buffer
183 // We use same buffer for input and output
184 //
185 PageFaultRequest.VirtualAddressFrom = TargetVirtualAddrFrom;
186 PageFaultRequest.VirtualAddressTo = TargetVirtualAddrTo;
187 PageFaultRequest.ProcessId = Pid; // null in debugger mode
188
190 {
191 //
192 // Check to prevent using process id in the .pagein command
193 //
194 if (PageFaultRequest.ProcessId != 0)
195 {
197 return;
198 }
199
200 //
201 // Send the request over serial kernel debugger
202 //
203 KdSendPageinPacketToDebuggee(&PageFaultRequest);
204 }
205 else
206 {
208
209 //
210 // For know, the support for the '.pagein' command is excluded from
211 // the VMI mode
212 //
213 ShowMessages("the '.pagein' command can be used ONLY in the debugger mode, "
214 "it is not yet supported in VMI mode\n");
215 return;
216
217 if (Pid == 0)
218 {
220 PageFaultRequest.ProcessId = Pid;
221 }
222
223 //
224 // Send IOCTL
225 //
227 g_DeviceHandle, // Handle to device
228 IOCTL_DEBUGGER_BRING_PAGES_IN, // IO Control Code (IOCTL)
229 &PageFaultRequest, // Input Buffer to driver.
230 SIZEOF_DEBUGGER_PAGE_IN_REQUEST, // Input buffer length
231 &PageFaultRequest, // Output Buffer from driver.
232 SIZEOF_DEBUGGER_PAGE_IN_REQUEST, // Length of output
233 // buffer in bytes.
234 &ReturnedLength, // Bytes placed in buffer.
235 NULL // synchronous call
236 );
237
238 if (!Status)
239 {
240 ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
241 return;
242 }
243
244 if (PageFaultRequest.KernelStatus != DEBUGGER_OPERATION_WAS_SUCCESSFUL)
245 {
246 ShowErrorMessage(PageFaultRequest.KernelStatus);
247 return;
248 }
249
250 //
251 // Show the results
252 //
253 ShowMessages("page-fault is delivered\n");
254 }
255}
BOOLEAN g_IsSerialConnectedToRemoteDebuggee
Shows if the debugger was connected to remote debuggee over (A remote guest).
Definition globals.h:253
int BOOL
Definition BasicTypes.h:25
unsigned long ULONG
Definition BasicTypes.h:31
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
#define IOCTL_DEBUGGER_BRING_PAGES_IN
ioctl, request to bring pages in
Definition Ioctls.h:340
#define SIZEOF_DEBUGGER_PAGE_IN_REQUEST
Definition RequestStructures.h:96
struct _DEBUGGER_PAGE_IN_REQUEST DEBUGGER_PAGE_IN_REQUEST
requests for the '.pagein' command
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:40
BOOLEAN KdSendPageinPacketToDebuggee(PDEBUGGER_PAGE_IN_REQUEST PageinPacket)
Sends a page-in or '.pagein' command packet to the debuggee.
Definition kd.cpp:936
#define ASSERT_MESSAGE_CANNOT_SPECIFY_PID
Definition common.h:39
#define AssertShowMessageReturnStmt(expr1, expr2, message1, message2, rc)
Definition common.h:59
#define ASSERT_MESSAGE_VMM_NOT_LOADED
Definition common.h:31
#define AssertReturn
Definition common.h:19
#define ASSERT_MESSAGE_DRIVER_NOT_LOADED
Definition common.h:27
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_IsVmmModuleLoaded
shows whether the VMM module is loaded or not
Definition globals.h:28
BOOL PlatformDeviceIoControl(HANDLE Device, DWORD IoControlCode, LPVOID InBuffer, DWORD InBufferSize, LPVOID OutBuffer, DWORD OutBufferSize, LPDWORD BytesReturned, LPVOID Overlapped)
DWORD PlatformGetLastError(VOID)
Platform independent wrapper for GetLastError.
Definition platform-lib-calls.c:350
UINT32 PlatformGetCurrentProcessId(VOID)
Platform independent wrapper for GetCurrentProcessId / getpid.
Definition platform-lib-calls.c:185
UINT64 VirtualAddressFrom
Definition RequestStructures.h:105
UINT32 KernelStatus
Definition RequestStructures.h:109
UINT32 ProcessId
Definition RequestStructures.h:107
UINT64 VirtualAddressTo
Definition RequestStructures.h:106

Variable Documentation

◆ g_ActiveProcessDebuggingState

ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
extern

State of active debugging thread.

372{0};

◆ 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