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

lm command More...

#include "pch.h"

Functions

VOID CommandLmHelp ()
 help of the lm command
std::wstring CommandLmConvertWow64CompatibilityPaths (const WCHAR *LocalFilePath)
 Convert redirection of 32-bit compatibility path.
BOOLEAN CommandLmShowUserModeModule (UINT32 ProcessId, const CHAR *SearchModule)
 show modules for specified user mode process
BOOLEAN CommandLmShowKernelModeModule (const CHAR *SearchModule)
 show modules for kernel mode
VOID CommandLm (vector< CommandToken > CommandTokens, string Command)
 handle lm command

Variables

BOOLEAN g_IsKdModuleLoaded
 shows whether the kernel debugger (KD) module is loaded or not
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
 State of active debugging thread.

Detailed Description

lm command

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

Function Documentation

◆ CommandLm()

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

handle lm command

Parameters
CommandTokens
Command
Returns
VOID
359{
360 BOOLEAN SetPid = FALSE;
361 BOOLEAN SetSearchFilter = FALSE;
362 BOOLEAN SearchStringEntered = FALSE;
363 BOOLEAN OnlyShowKernelModules = FALSE;
364 BOOLEAN OnlyShowUserModules = FALSE;
365 UINT32 TargetPid = NULL;
366 CHAR Search[MAX_PATH] = {0};
367 CHAR * SearchString = NULL;
368
369 //
370 // Interpret command specific details (if any)
371 //
372 for (auto Section : CommandTokens)
373 {
374 if (CompareLowerCaseStrings(Section, "lm"))
375 {
376 continue;
377 }
378 else if (CompareLowerCaseStrings(Section, "pid") && !SetPid)
379 {
380 SetPid = TRUE;
381 }
382 else if (CompareLowerCaseStrings(Section, "m") && !SetSearchFilter)
383 {
384 SetSearchFilter = TRUE;
385 }
386 else if (SetPid)
387 {
388 if (!ConvertTokenToUInt32(Section, &TargetPid))
389 {
390 //
391 // couldn't resolve or unknown parameter
392 //
393 ShowMessages("err, couldn't resolve error at '%s'\n\n",
396 return;
397 }
398 SetPid = FALSE;
399 }
400 else if (SetSearchFilter)
401 {
402 if (GetCaseSensitiveStringFromCommandToken(Section).length() >= MAX_PATH)
403 {
404 ShowMessages("err, string is too large for search, please enter "
405 "smaller string\n");
406
407 return;
408 }
409
410 SearchStringEntered = TRUE;
411 strcpy(Search, GetLowerStringFromCommandToken(Section).c_str());
412
413 SetSearchFilter = FALSE;
414 }
415 else if (CompareLowerCaseStrings(Section, "km"))
416 {
417 if (OnlyShowUserModules)
418 {
419 ShowMessages("err, you cannot use both 'um', and 'km', by default "
420 "HyperDbg shows both user-mode and kernel-mode modules\n");
421 return;
422 }
423
424 OnlyShowKernelModules = TRUE;
425 }
426 else if (CompareLowerCaseStrings(Section, "um"))
427 {
428 if (OnlyShowKernelModules)
429 {
430 ShowMessages("err, you cannot use both 'um', and 'km', by default "
431 "HyperDbg shows both user-mode and kernel-mode modules\n");
432 return;
433 }
434
435 OnlyShowUserModules = TRUE;
436 }
437 else
438 {
439 //
440 // Unknown parameter
441 //
442 ShowMessages("err, couldn't resolve error at '%s'\n\n",
445 return;
446 }
447 }
448
449 if (SetPid)
450 {
451 ShowMessages("err, please enter a valid process id in hex format, "
452 "or if you want to use it in decimal format, add '0n' "
453 "prefix to the number\n");
454 return;
455 }
456
457 if (SetSearchFilter)
458 {
459 ShowMessages("err, please enter a valid string to search in modules\n");
460 return;
461 }
462
463 //
464 // Check if we have string to search
465 //
466 if (SearchStringEntered)
467 {
468 SearchString = Search;
469 }
470
471 //
472 // Show user mode modules
473 //
474 if (!OnlyShowKernelModules)
475 {
476 if (TargetPid != NULL)
477 {
478 CommandLmShowUserModeModule(TargetPid, SearchString);
479 }
480 else if (g_ActiveProcessDebuggingState.IsActive)
481 {
483 }
484 else
485 {
486 CommandLmShowUserModeModule(GetCurrentProcessId(), SearchString);
487 }
488 }
489
490 //
491 // Show kernel mode modules
492 //
493 if (!OnlyShowUserModules)
494 {
495 if (!OnlyShowKernelModules)
496 {
497 ShowMessages("\n==============================================================================\n\n");
498 }
499
500 CommandLmShowKernelModeModule(SearchString);
501 }
502}
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
char CHAR
Definition BasicTypes.h:33
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
VOID CommandLmHelp()
help of the lm command
Definition lm.cpp:28
BOOLEAN CommandLmShowUserModeModule(UINT32 ProcessId, const CHAR *SearchModule)
show modules for specified user mode process
Definition lm.cpp:84
BOOLEAN CommandLmShowKernelModeModule(const CHAR *SearchModule)
show modules for kernel mode
Definition lm.cpp:275
NULL()
Definition test-case-generator.py:530

◆ CommandLmConvertWow64CompatibilityPaths()

std::wstring CommandLmConvertWow64CompatibilityPaths ( const WCHAR * LocalFilePath)

Convert redirection of 32-bit compatibility path.

Parameters
LocalFilePath
Returns
wstring
53{
54 std::wstring filePath(LocalFilePath);
55
56 // Convert the path to lowercase
57 std::transform(filePath.begin(), filePath.end(), filePath.begin(), ::tolower);
58
59 // Replace "\windows\system32" with "\windows\syswow64"
60 SIZE_T pos = filePath.find(L":\\windows\\system32");
61 if (pos != std::string::npos)
62 {
63 filePath.replace(pos, 18, L":\\Windows\\SysWOW64");
64 }
65
66 // Replace "\program files" with "\program files (x86)"
67 pos = filePath.find(L":\\program files");
68 if (pos != std::string::npos)
69 {
70 filePath.replace(pos, 15, L":\\Program Files (x86)");
71 }
72
73 return filePath;
74}

◆ CommandLmHelp()

VOID CommandLmHelp ( )

help of the lm command

Returns
VOID
29{
30 ShowMessages("lm : lists user/kernel modules' base address, size, name and path.\n\n");
31
32 ShowMessages("syntax : \tlm [m Name (string)] [pid ProcessId (hex)] [Filter (string)]\n");
33
34 ShowMessages("\n");
35 ShowMessages("\t\te.g : lm\n");
36 ShowMessages("\t\te.g : lm km\n");
37 ShowMessages("\t\te.g : lm um\n");
38 ShowMessages("\t\te.g : lm m nt\n");
39 ShowMessages("\t\te.g : lm km m ntos\n");
40 ShowMessages("\t\te.g : lm um m kernel32\n");
41 ShowMessages("\t\te.g : lm um m kernel32 pid 1240\n");
42}

◆ CommandLmShowKernelModeModule()

BOOLEAN CommandLmShowKernelModeModule ( const CHAR * SearchModule)

show modules for kernel mode

Parameters
SearchModule
Returns
BOOLEAN
276{
277 PRTL_PROCESS_MODULES ModulesInfo = NULL;
278 string SearchModuleString;
279
281 {
282 ShowMessages("err, unable get modules information\n");
283 return FALSE;
284 }
285
286 if (SearchModule != NULL)
287 {
288 SearchModuleString.assign(SearchModule, strlen(SearchModule));
289 }
290
291 ShowMessages("kernel mode\n");
292 ShowMessages("start\t\t\tsize\tname\t\t\t\tpath\n\n");
293
294 for (ULONG i = 0; i < ModulesInfo->NumberOfModules; i++)
295 {
296 RTL_PROCESS_MODULE_INFORMATION * CurrentModule = &ModulesInfo->Modules[i];
297
298 //
299 // Check if we need to search for the module or not
300 //
301 if (SearchModule != NULL)
302 {
303 //
304 // Convert FullPathName to string
305 //
306 std::string FullPathName((CHAR *)CurrentModule->FullPathName);
307
308 if (FindCaseInsensitive(FullPathName, SearchModuleString, 0) == std::string::npos)
309 {
310 //
311 // not found
312 //
313 continue;
314 }
315 }
316
317 ShowMessages("%s\t", SeparateTo64BitValue((UINT64)CurrentModule->ImageBase).c_str());
318 ShowMessages("%x\t", CurrentModule->ImageSize);
319
320 auto PathName = CurrentModule->FullPathName + CurrentModule->OffsetToFileName;
321 UINT32 PathNameLen = (UINT32)strlen((const CHAR *)PathName);
322
323 ShowMessages("%s\t", PathName);
324
325 if (PathNameLen >= 24)
326 {
327 }
328 else if (PathNameLen >= 16)
329 {
330 ShowMessages("\t");
331 }
332 else if (PathNameLen >= 8)
333 {
334 ShowMessages("\t\t");
335 }
336 else
337 {
338 ShowMessages("\t\t\t");
339 }
340
341 ShowMessages("%s\n", CurrentModule->FullPathName);
342 }
343
344 free(ModulesInfo);
345
346 return TRUE;
347}
struct _RTL_PROCESS_MODULES * PRTL_PROCESS_MODULES
struct _RTL_PROCESS_MODULE_INFORMATION RTL_PROCESS_MODULE_INFORMATION
unsigned long ULONG
Definition BasicTypes.h:31
string SeparateTo64BitValue(UINT64 Value)
SIZE_T FindCaseInsensitive(std::string Input, std::string ToSearch, SIZE_T Pos)
Find case insensitive sub string in a given substring.
Definition common.cpp:866
PVOID ImageBase
Definition Windows.h:22
UCHAR FullPathName[256]
Definition Windows.h:29
USHORT OffsetToFileName
Definition Windows.h:28
ULONG ImageSize
Definition Windows.h:23
ULONG NumberOfModules
Definition Windows.h:34
BOOLEAN SymbolCheckAndAllocateModuleInformation(PRTL_PROCESS_MODULES *Modules)
Check and allocate module information.
Definition symbol.cpp:1303

◆ CommandLmShowUserModeModule()

BOOLEAN CommandLmShowUserModeModule ( UINT32 ProcessId,
const CHAR * SearchModule )

show modules for specified user mode process

Parameters
ProcessId
SearchModule
Returns
BOOLEAN
85{
86 BOOLEAN Status;
87 ULONG ReturnedLength;
88 UINT32 ModuleDetailsSize = 0;
89 UINT32 ModulesCount = 0;
90 PUSERMODE_LOADED_MODULE_DETAILS ModuleDetailsRequest = NULL;
92 USERMODE_LOADED_MODULE_DETAILS ModuleCountRequest = {0};
93 SIZE_T CharSize = 0;
94 WCHAR * WcharBuff = NULL;
95 wstring SearchModuleString;
96
97 //
98 // Check if debugger is loaded or not
99 //
101
102 //
103 // Set the module details to get the details
104 //
105 ModuleCountRequest.ProcessId = ProcessId;
106 ModuleCountRequest.OnlyCountModules = TRUE;
107
108 //
109 // Send the request to the kernel
110 //
111 Status = DeviceIoControl(
112 g_DeviceHandle, // Handle to device
114 // code
115 &ModuleCountRequest, // Input Buffer to driver.
116 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Input buffer length
117 &ModuleCountRequest, // Output Buffer from driver.
118 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Length of output
119 // buffer in bytes.
120 &ReturnedLength, // Bytes placed in buffer.
121 NULL // synchronous call
122 );
123
124 if (!Status)
125 {
126 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
127 return FALSE;
128 }
129
130 //
131 // Check if counting modules was successful or not
132 //
133 if (ModuleCountRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
134 {
135 ModulesCount = ModuleCountRequest.ModulesCount;
136
137 // ShowMessages("Count of modules : 0x%x\n", ModuleCountRequest.ModulesCount);
138
139 ModuleDetailsSize = sizeof(USERMODE_LOADED_MODULE_DETAILS) +
140 (ModuleCountRequest.ModulesCount * sizeof(USERMODE_LOADED_MODULE_SYMBOLS));
141
142 ModuleDetailsRequest = (PUSERMODE_LOADED_MODULE_DETAILS)malloc(ModuleDetailsSize);
143
144 if (ModuleDetailsRequest == NULL)
145 {
146 return FALSE;
147 }
148
149 RtlZeroMemory(ModuleDetailsRequest, ModuleDetailsSize);
150
151 //
152 // Set the module details to get the modules (not count)
153 //
154 ModuleDetailsRequest->ProcessId = ProcessId;
155 ModuleDetailsRequest->OnlyCountModules = FALSE;
156
157 //
158 // Send the request to the kernel
159 //
160 Status = DeviceIoControl(
161 g_DeviceHandle, // Handle to device
163 // code
164 ModuleDetailsRequest, // Input Buffer to driver.
165 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Input buffer length
166 ModuleDetailsRequest, // Output Buffer from driver.
167 ModuleDetailsSize, // Length of output
168 // buffer in bytes.
169 &ReturnedLength, // Bytes placed in buffer.
170 NULL // synchronous call
171 );
172
173 if (!Status)
174 {
175 free(ModuleDetailsRequest);
176 ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
177 return FALSE;
178 }
179
180 //
181 // Show modules list
182 //
183 if (ModuleCountRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
184 {
185 Modules = (PUSERMODE_LOADED_MODULE_SYMBOLS)((UINT64)ModuleDetailsRequest +
187 ShowMessages("user mode\n");
188 ShowMessages("start\t\t\tentrypoint\t\tpath\n\n");
189
190 if (SearchModule != NULL)
191 {
192 CharSize = strlen(SearchModule) + 1;
193 WcharBuff = (WCHAR *)malloc(CharSize * 2);
194
195 if (WcharBuff == NULL)
196 {
197 return FALSE;
198 }
199
200 RtlZeroMemory(WcharBuff, CharSize);
201
202 mbstowcs(WcharBuff, SearchModule, CharSize);
203
204 SearchModuleString.assign(WcharBuff, wcslen(WcharBuff));
205 }
206
207 for (SIZE_T i = 0; i < ModulesCount; i++)
208 {
209 //
210 // Check if we need to search for the module or not
211 //
212 if (SearchModule != NULL)
213 {
214 //
215 // Convert FullPathName to string
216 //
217 std::wstring FullPathName((WCHAR *)Modules[i].FilePath);
218
219 if (FindCaseInsensitiveW(FullPathName, SearchModuleString, 0) == std::wstring::npos)
220 {
221 //
222 // not found
223 //
224 continue;
225 }
226 }
227
228 //
229 // Check if module is 32-bit or not
230 //
231 if (ModuleDetailsRequest->Is32Bit)
232 {
233 ShowMessages("%016llx\t%016llx\t%ws\n",
234 Modules[i].BaseAddress,
235 Modules[i].Entrypoint,
236 CommandLmConvertWow64CompatibilityPaths(Modules[i].FilePath).c_str());
237 }
238 else
239 {
240 ShowMessages("%016llx\t%016llx\t%ws\n",
241 Modules[i].BaseAddress,
242 Modules[i].Entrypoint,
243 Modules[i].FilePath);
244 }
245 }
246
247 if (SearchModule != NULL)
248 {
249 free(WcharBuff);
250 }
251 }
252 else
253 {
254 ShowErrorMessage(ModuleCountRequest.Result);
255 return FALSE;
256 }
257
258 free(ModuleDetailsRequest);
259 return TRUE;
260 }
261 else
262 {
263 ShowErrorMessage(ModuleCountRequest.Result);
264 return FALSE;
265 }
266}
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
#define IOCTL_GET_USER_MODE_MODULE_DETAILS
ioctl, to get user mode modules details
Definition Ioctls.h:298
struct _USERMODE_LOADED_MODULE_SYMBOLS * PUSERMODE_LOADED_MODULE_SYMBOLS
struct _USERMODE_LOADED_MODULE_DETAILS USERMODE_LOADED_MODULE_DETAILS
struct _USERMODE_LOADED_MODULE_SYMBOLS USERMODE_LOADED_MODULE_SYMBOLS
struct _USERMODE_LOADED_MODULE_DETAILS * PUSERMODE_LOADED_MODULE_DETAILS
SIZE_T FindCaseInsensitiveW(std::wstring Input, std::wstring ToSearch, SIZE_T Pos)
Find case insensitive sub string in a given substring (unicode).
Definition common.cpp:885
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:40
#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
std::wstring CommandLmConvertWow64CompatibilityPaths(const WCHAR *LocalFilePath)
Convert redirection of 32-bit compatibility path.
Definition lm.cpp:52
UINT32 Result
Definition Symbols.h:52
UINT32 ModulesCount
Definition Symbols.h:51
UINT32 ProcessId
Definition Symbols.h:48
BOOLEAN Is32Bit
Definition Symbols.h:50
BOOLEAN OnlyCountModules
Definition Symbols.h:49

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