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_t *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< string > SplitCommand, string Command)
 handle lm command
 

Variables

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

handle lm command

Parameters
SplitCommand
Command
Returns
VOID
386{
387 BOOLEAN SetPid = FALSE;
388 BOOLEAN SetSearchFilter = FALSE;
389 BOOLEAN SearchStringEntered = FALSE;
390 BOOLEAN OnlyShowKernelModules = FALSE;
391 BOOLEAN OnlyShowUserModules = FALSE;
392 UINT32 TargetPid = NULL;
393 char Search[MAX_PATH] = {0};
394 char * SearchString = NULL;
395
396 //
397 // Interpret command specific details (if any)
398 //
399 for (auto Section : SplitCommand)
400 {
401 if (!Section.compare("lm"))
402 {
403 continue;
404 }
405 else if (!Section.compare("pid") && !SetPid)
406 {
407 SetPid = TRUE;
408 }
409 else if (!Section.compare("m") && !SetSearchFilter)
410 {
411 SetSearchFilter = TRUE;
412 }
413 else if (SetPid)
414 {
415 if (!ConvertStringToUInt32(Section, &TargetPid))
416 {
417 //
418 // couldn't resolve or unknown parameter
419 //
420 ShowMessages("err, couldn't resolve error at '%s'\n\n",
421 Section.c_str());
423 return;
424 }
425 SetPid = FALSE;
426 }
427 else if (SetSearchFilter)
428 {
429 if (Section.length() >= MAX_PATH)
430 {
431 ShowMessages("err, string is too large for search, please enter "
432 "smaller string\n");
433
434 return;
435 }
436
437 SearchStringEntered = TRUE;
438 strcpy(Search, Section.c_str());
439
440 SetSearchFilter = FALSE;
441 }
442 else if (!Section.compare("km"))
443 {
444 if (OnlyShowUserModules)
445 {
446 ShowMessages("err, you cannot use both 'um', and 'km', by default "
447 "HyperDbg shows both user-mode and kernel-mode modules\n");
448 return;
449 }
450
451 OnlyShowKernelModules = TRUE;
452 }
453 else if (!Section.compare("um"))
454 {
455 if (OnlyShowKernelModules)
456 {
457 ShowMessages("err, you cannot use both 'um', and 'km', by default "
458 "HyperDbg shows both user-mode and kernel-mode modules\n");
459 return;
460 }
461
462 OnlyShowUserModules = TRUE;
463 }
464 else
465 {
466 //
467 // Unknown parameter
468 //
469 ShowMessages("err, couldn't resolve error at '%s'\n\n",
470 Section.c_str());
472 return;
473 }
474 }
475
476 if (SetPid)
477 {
478 ShowMessages("err, please enter a valid process id in hex format, "
479 "or if you want to use it in decimal format, add '0n' "
480 "prefix to the number\n");
481 return;
482 }
483
484 if (SetSearchFilter)
485 {
486 ShowMessages("err, please enter a valid string to search in modules\n");
487 return;
488 }
489
490 //
491 // Check if we have string to search
492 //
493 if (SearchStringEntered)
494 {
495 SearchString = Search;
496 }
497
498 //
499 // Show user mode modules
500 //
501 if (!OnlyShowKernelModules)
502 {
503 if (TargetPid != NULL)
504 {
505 CommandLmShowUserModeModule(TargetPid, SearchString);
506 }
508 {
510 }
511 else
512 {
513 CommandLmShowUserModeModule(GetCurrentProcessId(), SearchString);
514 }
515 }
516
517 //
518 // Show kernel mode modules
519 //
520 if (!OnlyShowUserModules)
521 {
522 if (!OnlyShowKernelModules)
523 {
524 ShowMessages("\n==============================================================================\n\n");
525 }
526
527 CommandLmShowKernelModeModule(SearchString);
528 }
529}
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned int UINT32
Definition BasicTypes.h:48
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
VOID CommandLmHelp()
help of the lm command
Definition lm.cpp:27
BOOLEAN CommandLmShowKernelModeModule(const char *SearchModule)
show modules for kernel mode
Definition lm.cpp:274
ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
State of active debugging thread.
Definition globals.h:362
BOOLEAN CommandLmShowUserModeModule(UINT32 ProcessId, const char *SearchModule)
show modules for specified user mode process
Definition lm.cpp:83
NULL()
Definition test-case-generator.py:530
UINT32 ProcessId
Definition ud.h:51
BOOLEAN IsActive
Definition ud.h:49

◆ CommandLmConvertWow64CompatibilityPaths()

std::wstring CommandLmConvertWow64CompatibilityPaths ( const wchar_t * LocalFilePath)

Convert redirection of 32-bit compatibility path.

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

◆ CommandLmHelp()

VOID CommandLmHelp ( )

help of the lm command

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

◆ CommandLmShowKernelModeModule()

BOOLEAN CommandLmShowKernelModeModule ( const char * SearchModule)

show modules for kernel mode

Parameters
SearchModule
Returns
BOOLEAN
275{
276 NTSTATUS Status = STATUS_UNSUCCESSFUL;
277 PRTL_PROCESS_MODULES ModulesInfo;
278 ULONG SysModuleInfoBufferSize = 0;
279 string SearchModuleString;
280
281 //
282 // Get required size of "RTL_PROCESS_MODULES" buffer
283 //
284 Status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, NULL, NULL, &SysModuleInfoBufferSize);
285
286 //
287 // Allocate memory for the module list
288 //
289 ModulesInfo = (PRTL_PROCESS_MODULES)VirtualAlloc(
290 NULL,
291 SysModuleInfoBufferSize,
292 MEM_COMMIT | MEM_RESERVE,
293 PAGE_READWRITE);
294
295 if (!ModulesInfo)
296 {
297 ShowMessages("err, unable to allocate memory for module list (%x)\n",
298 GetLastError());
299 return FALSE;
300 }
301
302 Status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation,
303 ModulesInfo,
304 SysModuleInfoBufferSize,
305 NULL);
306 if (!NT_SUCCESS(Status))
307 {
308 ShowMessages("err, unable to query module list (%x)\n", Status);
309
310 VirtualFree(ModulesInfo, 0, MEM_RELEASE);
311 return FALSE;
312 }
313
314 if (SearchModule != NULL)
315 {
316 SearchModuleString.assign(SearchModule, strlen(SearchModule));
317 }
318
319 ShowMessages("kernel mode\n");
320 ShowMessages("start\t\t\tsize\tname\t\t\t\tpath\n\n");
321
322 for (ULONG i = 0; i < ModulesInfo->NumberOfModules; i++)
323 {
324 RTL_PROCESS_MODULE_INFORMATION * CurrentModule = &ModulesInfo->Modules[i];
325
326 //
327 // Check if we need to search for the module or not
328 //
329 if (SearchModule != NULL)
330 {
331 //
332 // Convert FullPathName to string
333 //
334 std::string FullPathName((char *)CurrentModule->FullPathName);
335
336 if (FindCaseInsensitive(FullPathName, SearchModuleString, 0) == std::string::npos)
337 {
338 //
339 // not found
340 //
341 continue;
342 }
343 }
344
345 ShowMessages("%s\t", SeparateTo64BitValue((UINT64)CurrentModule->ImageBase).c_str());
346 ShowMessages("%x\t", CurrentModule->ImageSize);
347
348 auto PathName = CurrentModule->FullPathName + CurrentModule->OffsetToFileName;
349 UINT32 PathNameLen = (UINT32)strlen((const char *)PathName);
350
351 ShowMessages("%s\t", PathName);
352
353 if (PathNameLen >= 24)
354 {
355 }
356 else if (PathNameLen >= 16)
357 {
358 ShowMessages("\t");
359 }
360 else if (PathNameLen >= 8)
361 {
362 ShowMessages("\t\t");
363 }
364 else
365 {
366 ShowMessages("\t\t\t");
367 }
368
369 ShowMessages("%s\n", CurrentModule->FullPathName);
370 }
371
372 VirtualFree(ModulesInfo, 0, MEM_RELEASE);
373
374 return TRUE;
375}
unsigned __int64 UINT64
Definition BasicTypes.h:21
unsigned long ULONG
Definition BasicTypes.h:37
@ SystemModuleInformation
Definition Hooks.h:116
enum _SYSTEM_INFORMATION_CLASS SYSTEM_INFORMATION_CLASS
System information class.
struct _RTL_PROCESS_MODULES * PRTL_PROCESS_MODULES
#define STATUS_UNSUCCESSFUL
Definition Windows.h:172
string SeparateTo64BitValue(UINT64 Value)
add ` between 64 bit values and convert them to string
Definition common.cpp:27
size_t FindCaseInsensitive(std::string Input, std::string ToSearch, size_t Pos)
Find case insensitive sub string in a given substring.
Definition common.cpp:817
Definition Windows.h:19
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
Definition Windows.h:33
ULONG NumberOfModules
Definition Windows.h:34

◆ CommandLmShowUserModeModule()

BOOLEAN CommandLmShowUserModeModule ( UINT32 ProcessId,
const char * SearchModule )

show modules for specified user mode process

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

Variable Documentation

◆ g_ActiveProcessDebuggingState

ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState
extern

State of active debugging thread.

362{0};