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

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

.pagein command handler

Parameters
SplitCommand
Command
Returns
VOID
265{
266 UINT32 Pid = 0;
267 UINT64 Length = 0;
268 UINT64 TargetAddressFrom = NULL;
269 UINT64 TargetAddressTo = NULL;
270 BOOLEAN IsNextProcessId = FALSE;
271 BOOLEAN IsFirstCommand = TRUE;
272 BOOLEAN IsNextLength = FALSE;
273 vector<string> SplitCommandCaseSensitive {Split(Command, ' ')};
274 UINT32 IndexInCommandCaseSensitive = 0;
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 {
284 }
285
286 if (SplitCommand.size() == 1)
287 {
288 //
289 // Means that user entered one command without any parameter
290 //
291 ShowMessages("incorrect use of the '.pagein' command\n\n");
293 return;
294 }
295
296 for (auto Section : SplitCommand)
297 {
298 IndexInCommandCaseSensitive++;
299
300 if (IsFirstCommand)
301 {
302 IsFirstCommand = FALSE;
303 continue;
304 }
305 if (IsNextProcessId == TRUE)
306 {
307 if (!ConvertStringToUInt32(Section, &Pid))
308 {
309 ShowMessages("err, you should enter a valid process id\n\n");
310 return;
311 }
312 IsNextProcessId = FALSE;
313 continue;
314 }
315
316 if (IsNextLength == TRUE)
317 {
318 if (!SymbolConvertNameOrExprToAddress(Section, &Length))
319 {
320 ShowMessages("err, you should enter a valid length\n\n");
321 return;
322 }
323 IsNextLength = FALSE;
324 continue;
325 }
326
327 if (!Section.compare("l"))
328 {
329 IsNextLength = TRUE;
330 continue;
331 }
332
333 // if (!Section.compare("pid"))
334 // {
335 // IsNextProcessId = TRUE;
336 // continue;
337 // }
338
339 //
340 // Probably it's address or mode string
341 //
342
343 if (CommandPageinCheckAndInterpretModeString(Section, &PageFaultErrorCode))
344 {
345 continue;
346 }
347 else if (TargetAddressFrom == 0)
348 {
349 if (!SymbolConvertNameOrExprToAddress(SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1),
350 &TargetAddressFrom))
351 {
352 //
353 // Couldn't resolve or unknown parameter
354 //
355 ShowMessages("err, couldn't resolve error at '%s'\n",
356 SplitCommandCaseSensitive.at(IndexInCommandCaseSensitive - 1).c_str());
357 return;
358 }
359 }
360 else
361 {
362 //
363 // User inserts two address
364 //
365 ShowMessages("err, incorrect use of the '.pagein' command\n\n");
367
368 return;
369 }
370 }
371
372 if (!TargetAddressFrom)
373 {
374 //
375 // User inserts two address
376 //
377 ShowMessages("err, please enter a valid address\n\n");
378
379 return;
380 }
381
382 if (IsNextLength || IsNextProcessId)
383 {
384 ShowMessages("incorrect use of the '.pagein' command\n\n");
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}
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
const vector< string > Split(const string &s, const char &c)
general split command
Definition common.cpp:117
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 ShowMessages(const char *Fmt,...)
Show messages.
Definition libhyperdbg.cpp:96
NULL()
Definition test-case-generator.py:530
VOID CommandPageinHelp()
help of the .pagein command
Definition pagein.cpp:26
BOOLEAN CommandPageinCheckAndInterpretModeString(const std::string &ModeString, PAGE_FAULT_EXCEPTION *PageFaultErrorCode)
Check whether the mode string is valid or not.
Definition pagein.cpp:81
VOID CommandPageinRequest(UINT64 TargetVirtualAddrFrom, UINT64 TargetVirtualAddrTo, PAGE_FAULT_EXCEPTION PageFaultErrorCode, UINT32 Pid)
request to bring the page(s) in
Definition pagein.cpp:171
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
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

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

◆ CommandPageinHelp()

VOID CommandPageinHelp ( )

help of the .pagein command

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

◆ 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
175{
176 BOOL Status;
177 ULONG ReturnedLength;
178 DEBUGGER_PAGE_IN_REQUEST PageFaultRequest = {0};
179
180 //
181 // Prepare the buffer
182 // We use same buffer for input and output
183 //
184 PageFaultRequest.VirtualAddressFrom = TargetVirtualAddrFrom;
185 PageFaultRequest.VirtualAddressTo = TargetVirtualAddrTo;
186 PageFaultRequest.ProcessId = Pid; // null in debugger mode
187
189 {
190 //
191 // Check to prevent using process id in the .pagein command
192 //
193 if (PageFaultRequest.ProcessId != 0)
194 {
196 return;
197 }
198
199 //
200 // Send the request over serial kernel debugger
201 //
202 KdSendPageinPacketToDebuggee(&PageFaultRequest);
203 }
204 else
205 {
207
208 //
209 // For know, the support for the '.pagein' command is excluded from
210 // the VMI mode
211 //
212 ShowMessages("the '.pagein' command can be used ONLY in the debugger mode, "
213 "it is not yet supported in VMI mode\n");
214 return;
215
216 if (Pid == 0)
217 {
218 Pid = GetCurrentProcessId();
219 PageFaultRequest.ProcessId = Pid;
220 }
221
222 //
223 // Send IOCTL
224 //
225 Status = DeviceIoControl(
226 g_DeviceHandle, // Handle to device
227 IOCTL_DEBUGGER_BRING_PAGES_IN, // IO Control Code (IOCTL)
228 &PageFaultRequest, // Input Buffer to driver.
229 SIZEOF_DEBUGGER_PAGE_IN_REQUEST, // Input buffer length
230 &PageFaultRequest, // Output Buffer from driver.
231 SIZEOF_DEBUGGER_PAGE_IN_REQUEST, // Length of output
232 // buffer in bytes.
233 &ReturnedLength, // Bytes placed in buffer.
234 NULL // synchronous call
235 );
236
237 if (!Status)
238 {
239 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
240 return;
241 }
242
243 if (PageFaultRequest.KernelStatus != DEBUGGER_OPERATION_WAS_SUCCESSFUL)
244 {
245 ShowErrorMessage(PageFaultRequest.KernelStatus);
246 return;
247 }
248
249 //
250 // Show the results
251 //
252 ShowMessages("page-fault is delivered\n");
253 }
254}
int BOOL
Definition BasicTypes.h:23
unsigned long ULONG
Definition BasicTypes.h:37
#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:282
#define SIZEOF_DEBUGGER_PAGE_IN_REQUEST
Definition RequestStructures.h:65
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:38
BOOLEAN KdSendPageinPacketToDebuggee(PDEBUGGER_PAGE_IN_REQUEST PageinPacket)
Sends a page-in or '.pagein' command packet to the debuggee.
Definition kd.cpp:936
#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
BOOLEAN g_IsSerialConnectedToRemoteDebuggee
Shows if the debugger was connected to remote debuggee over (A remote guest)
Definition globals.h:231
requests for the '.pagein' command
Definition RequestStructures.h:73
UINT64 VirtualAddressFrom
Definition RequestStructures.h:74
UINT32 KernelStatus
Definition RequestStructures.h:78
UINT32 ProcessId
Definition RequestStructures.h:76
UINT64 VirtualAddressTo
Definition RequestStructures.h:75

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)