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

symbol parser More...

#include "pch.h"

Functions

VOID SymbolInitialReload ()
 Initial load of symbols (for previously download symbols)
 
BOOLEAN SymbolLocalReload (UINT32 UserProcessId)
 Locally reload the symbol table.
 
VOID SymbolPrepareDebuggerWithSymbolInfo (UINT32 UserProcessId)
 Initial and send the results of serial for the debugger in the case of debugger mode.
 
VOID SymbolCreateDisassemblerMapCallback (UINT64 Address, char *ModuleName, char *ObjectName, unsigned int ObjectSize)
 Callback for creating symbol map for disassembler.
 
BOOLEAN SymbolCreateDisassemblerSymbolMap ()
 Update (or create) symbol map for the disassembler.
 
BOOLEAN SymbolShowFunctionNameBasedOnAddress (UINT64 Address, PUINT64 UsedBaseAddress)
 shows the functions' name for the disassembler
 
VOID SymbolBuildAndShowSymbolTable ()
 Build and show symbol table details.
 
BOOLEAN SymbolLoadOrDownloadSymbols (BOOLEAN IsDownload, BOOLEAN SilentLoad)
 Load or download symbols.
 
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 evaluate expressions
 
BOOLEAN SymbolDeleteSymTable ()
 Delete and free structures and variables related to the symbols.
 
BOOLEAN SymbolBuildSymbolTable (PMODULE_SYMBOL_DETAIL *BufferToStoreDetails, PUINT32 StoredLength, UINT32 UserProcessId, BOOLEAN SendOverSerial)
 make the initial packet required for symbol server or reload packet
 
BOOLEAN SymbolBuildAndUpdateSymbolTable (PMODULE_SYMBOL_DETAIL SymbolDetail)
 Allocate (build) and update the symbol table whenever a debuggee is attached on the debugger mode.
 
BOOLEAN SymbolReloadSymbolTableInDebuggerMode (UINT32 ProcessId)
 Update the symbol table from remote debuggee in debugger mode.
 

Variables

PMODULE_SYMBOL_DETAIL g_SymbolTable
 The buffer that stores the details of symbol table.
 
UINT32 g_SymbolTableSize
 The buffer that stores size of the details of symbol table.
 
UINT32 g_SymbolTableCurrentIndex
 The index to hold the track of added symbols.
 
BOOLEAN g_IsExecutingSymbolLoadingRoutines
 Executing symbol reloading or downloading routines.
 
BOOLEAN g_IsSerialConnectedToRemoteDebugger
 Shows if the debugger was connected to remote debugger (A remote host)
 
BOOLEAN g_AddressConversion
 Whether converting addresses to object names or not.
 
std::map< UINT64, LOCAL_FUNCTION_DESCRIPTIONg_DisassemblerSymbolMap
 Symbol table for disassembler.
 

Detailed Description

symbol parser

Author
Alee Amini (alee@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2021-05-20

Function Documentation

◆ SymbolBuildAndShowSymbolTable()

VOID SymbolBuildAndShowSymbolTable ( )

Build and show symbol table details.

Parameters
BuildLocalSymTableShould this function call to build local symbol or the symbols are from a remote debuggee in debugger mode
Returns
VOID
265{
266 if (g_SymbolTable == NULL || g_SymbolTableSize == NULL)
267 {
268 ShowMessages("err, symbol table is empty. please use '.sym reload' "
269 "to build the symbol table\n");
270 return;
271 }
272
273 //
274 // show packet details
275 //
276 for (size_t i = 0; i < g_SymbolTableSize / sizeof(MODULE_SYMBOL_DETAIL); i++)
277 {
278 ShowMessages("is pdb details available? : %s\n", g_SymbolTable[i].IsSymbolDetailsFound ? "true" : "false");
279 ShowMessages("is pdb a path instead of module name? : %s\n", g_SymbolTable[i].IsLocalSymbolPath ? "true" : "false");
280 ShowMessages("base address : %llx\n", g_SymbolTable[i].BaseAddress);
281 ShowMessages("file path : %s\n", g_SymbolTable[i].FilePath);
282 ShowMessages("guid and age : %s\n", g_SymbolTable[i].ModuleSymbolGuidAndAge);
283 ShowMessages("module symbol path/name : %s\n", g_SymbolTable[i].ModuleSymbolPath);
284 ShowMessages("is user-mode? : %s - is 32-bit? %s\n",
285 g_SymbolTable[i].IsUserMode ? "true" : "false",
286 g_SymbolTable[i].Is32Bit ? "true" : "false");
287 ShowMessages("========================================================================\n");
288 }
289}
struct _MODULE_SYMBOL_DETAIL MODULE_SYMBOL_DETAIL
structures for sending and saving details about each module and symbols details
VOID ShowMessages(const char *Fmt,...)
Show messages.
Definition libhyperdbg.cpp:96
PMODULE_SYMBOL_DETAIL g_SymbolTable
The buffer that stores the details of symbol table.
Definition globals.h:609
UINT32 g_SymbolTableSize
The buffer that stores size of the details of symbol table.
Definition globals.h:616

◆ SymbolBuildAndUpdateSymbolTable()

BOOLEAN SymbolBuildAndUpdateSymbolTable ( PMODULE_SYMBOL_DETAIL SymbolDetail)

Allocate (build) and update the symbol table whenever a debuggee is attached on the debugger mode.

Parameters
SymbolDetailPointer to a buffer that was received as the single symbol info
Returns
BOOLEAN shows whether the operation was successful or not
941{
942 //
943 // Check to avoid overflow in symbol table
944 //
946 {
947 ShowMessages("err, the symbol table buffer is full, unable to add new symbol\n");
948 return FALSE;
949 }
950
951 //
952 // Check if we found an already built symbol table
953 //
954 if (g_SymbolTable == NULL)
955 {
956 //
957 // Allocate Details buffer
958 //
960
961 if (g_SymbolTable == NULL)
962 {
963 ShowMessages("err, unable to allocate memory for module list (%x)\n",
964 GetLastError());
965 return FALSE;
966 }
967
968 //
969 // Reset the index
970 //
972
973 //
974 // Make sure buffer is zero
975 //
977 }
978
979 //
980 // Move it to the new buffer
981 //
982 memcpy(&g_SymbolTable[g_SymbolTableCurrentIndex], SymbolDetail, sizeof(MODULE_SYMBOL_DETAIL));
983
984 //
985 // Add to index for future symbols
986 //
988
989 //
990 // Compute the (new) current size
991 //
993
994 return TRUE;
995}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
#define MAXIMUM_SUPPORTED_SYMBOLS
maximum supported modules to load their symbol information
Definition Constants.h:483
struct _MODULE_SYMBOL_DETAIL * PMODULE_SYMBOL_DETAIL
structures for sending and saving details about each module and symbols details
Definition Symbols.h:24
UINT32 g_SymbolTableCurrentIndex
The index to hold the track of added symbols.
Definition globals.h:623

◆ SymbolBuildSymbolTable()

BOOLEAN SymbolBuildSymbolTable ( PMODULE_SYMBOL_DETAIL * BufferToStoreDetails,
PUINT32 StoredLength,
UINT32 UserProcessId,
BOOLEAN SendOverSerial )

make the initial packet required for symbol server or reload packet

Parameters
BufferToStoreDetailsPointer to a buffer to store the symbols details this buffer will be allocated by this function and needs to be freed by caller
StoredLengthThe length that stored on the BufferToStoreDetails
UserProcessIdWhich user mode process to get its modules
SendOverSerialShows whether the packet should be sent to the debugger over the serial or not
Returns
BOOLEAN shows whether the operation was successful or not
476{
477 PRTL_PROCESS_MODULES ModuleInfo;
478 NTSTATUS NtStatus;
479 BOOLEAN Status;
480 ULONG ReturnedLength;
481 PMODULE_SYMBOL_DETAIL ModuleSymDetailArray = NULL;
482 char SystemRoot[MAX_PATH] = {0};
483 char ModuleSymbolPath[MAX_PATH] = {0};
484 char TempPath[MAX_PATH] = {0};
485 char ModuleSymbolGuidAndAge[MAXIMUM_GUID_AND_AGE_SIZE] = {0};
486 BOOLEAN IsSymbolPdbDetailAvailable = FALSE;
487 BOOLEAN IsFreeUsermodeModulesBuffer = FALSE;
488 ULONG SysModuleInfoBufferSize = 0;
489 UINT32 ModuleDetailsSize = 0;
490 UINT32 ModulesCount = 0;
491 PUSERMODE_LOADED_MODULE_DETAILS ModuleDetailsRequest = NULL;
493 USERMODE_LOADED_MODULE_DETAILS ModuleCountRequest = {0};
494
495 //
496 // Check if we found an already built symbol table
497 //
499
500 //
501 // Get system root
502 //
503 if (GetSystemDirectoryA(SystemRoot, MAX_PATH) == NULL)
504 {
505 ShowMessages("err, unable to get system directory (%x)\n",
506 GetLastError());
507
508 return FALSE;
509 }
510
511 string SystemRootString(SystemRoot);
512
513 //
514 // Convert root path to lower-case
515 //
516 transform(SystemRootString.begin(),
517 SystemRootString.end(),
518 SystemRootString.begin(),
519 [](unsigned char c) { return std::tolower(c); });
520
521 //
522 // Remove system32 from the root
523 //
524 Replace(SystemRootString, "\\system32", "");
525
526 //
527 // *****************************************************************
528 // Get kernel-mode modules information
529 // *****************************************************************
530 //
531
532 //
533 // Get required size of "RTL_PROCESS_MODULES" buffer
534 //
535 NtStatus = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, NULL, NULL, &SysModuleInfoBufferSize);
536
537 //
538 // Allocate memory for the module list
539 //
540 ModuleInfo = (PRTL_PROCESS_MODULES)VirtualAlloc(
541 NULL,
542 SysModuleInfoBufferSize,
543 MEM_COMMIT | MEM_RESERVE,
544 PAGE_READWRITE);
545
546 if (!ModuleInfo)
547 {
548 ShowMessages("err, unable to allocate memory for module list (%x)\n",
549 GetLastError());
550 return FALSE;
551 }
552
553 if (!NT_SUCCESS(
554 NtStatus = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation,
555 ModuleInfo,
556 SysModuleInfoBufferSize,
557 NULL)))
558 {
559 ShowMessages("err, unable to query module list (%#x)\n", NtStatus);
560
561 VirtualFree(ModuleInfo, 0, MEM_RELEASE);
562 return FALSE;
563 }
564
565 //
566 // *****************************************************************
567 // Get user-mode modules information
568 // *****************************************************************
569 //
570
571 //
572 // We won't fail the entire process if the user-mode modules is failed
573 //
574
575 do
576 {
577 //
578 // Check if debugger is loaded or not
579 //
580 if (!g_DeviceHandle)
581 {
582 break;
583 }
584
585 //
586 // Set the module details to get the details
587 //
588 ModuleCountRequest.ProcessId = UserProcessId;
589 ModuleCountRequest.OnlyCountModules = TRUE;
590
591 //
592 // Send the request to the kernel
593 //
594 Status = DeviceIoControl(
595 g_DeviceHandle, // Handle to device
597 // code
598 &ModuleCountRequest, // Input Buffer to driver.
599 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Input buffer length
600 &ModuleCountRequest, // Output Buffer from driver.
601 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Length of output
602 // buffer in bytes.
603 &ReturnedLength, // Bytes placed in buffer.
604 NULL // synchronous call
605 );
606
607 if (!Status)
608 {
609 break;
610 }
611
612 //
613 // Check if counting modules was successful or not
614 //
615 if (ModuleCountRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
616 {
617 ModulesCount = ModuleCountRequest.ModulesCount;
618
619 // ShowMessages("Count of modules : 0x%x\n", ModuleCountRequest.ModulesCount);
620
621 ModuleDetailsSize = sizeof(USERMODE_LOADED_MODULE_DETAILS) +
622 (ModuleCountRequest.ModulesCount * sizeof(USERMODE_LOADED_MODULE_SYMBOLS));
623
624 ModuleDetailsRequest = (PUSERMODE_LOADED_MODULE_DETAILS)malloc(ModuleDetailsSize);
625
626 if (ModuleDetailsRequest == NULL)
627 {
628 break;
629 }
630
631 RtlZeroMemory(ModuleDetailsRequest, ModuleDetailsSize);
632
633 //
634 // Set the module details to get the modules (not count)
635 //
636 ModuleDetailsRequest->ProcessId = UserProcessId;
637 ModuleDetailsRequest->OnlyCountModules = FALSE;
638
639 //
640 // Send the request to the kernel
641 //
642 Status = DeviceIoControl(
643 g_DeviceHandle, // Handle to device
645 // code
646 ModuleDetailsRequest, // Input Buffer to driver.
647 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Input buffer length
648 ModuleDetailsRequest, // Output Buffer from driver.
649 ModuleDetailsSize, // Length of output
650 // buffer in bytes.
651 &ReturnedLength, // Bytes placed in buffer.
652 NULL // synchronous call
653 );
654
655 if (!Status)
656 {
657 free(ModuleDetailsRequest);
658 break;
659 }
660
661 //
662 // check the module list
663 //
664 if (ModuleCountRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
665 {
666 //
667 // Se the modules buffer
668 //
669 Modules = (PUSERMODE_LOADED_MODULE_SYMBOLS)((UINT64)ModuleDetailsRequest +
671
672 //
673 // Check if modules buffer is valid
674 //
675 if (Modules == NULL)
676 {
677 ModulesCount = 0;
678 free(ModuleDetailsRequest);
679 break;
680 }
681 }
682 else
683 {
684 ShowErrorMessage(ModuleCountRequest.Result);
685 free(ModuleDetailsRequest);
686 break;
687 }
688
689 //
690 // Everything is okay when we reached here
691 //
692 IsFreeUsermodeModulesBuffer = TRUE;
693 }
694 else
695 {
696 ShowErrorMessage(ModuleCountRequest.Result);
697 break;
698 }
699
700 } while (FALSE);
701
702 //
703 // *****************************************************************
704 //
705
706 //
707 // Allocate Details buffer
708 //
709 ModuleSymDetailArray = (PMODULE_SYMBOL_DETAIL)malloc(
710 (ModuleInfo->NumberOfModules + ModulesCount) * sizeof(MODULE_SYMBOL_DETAIL));
711
712 if (ModuleSymDetailArray == NULL)
713 {
714 ShowMessages("err, unable to allocate memory for module list (%x)\n",
715 GetLastError());
716
717 if (IsFreeUsermodeModulesBuffer)
718 {
719 free(ModuleDetailsRequest);
720 }
721 return FALSE;
722 }
723
724 //
725 // Make sure buffer is zero
726 //
727 RtlZeroMemory(ModuleSymDetailArray, (ModuleInfo->NumberOfModules + ModulesCount) * sizeof(MODULE_SYMBOL_DETAIL));
728
729 //
730 // ----------------------------------------------------------------------------------
731 // Add user-modules
732 // ----------------------------------------------------------------------------------
733 //
734
735 if (ModulesCount != 0)
736 {
737 for (UINT32 i = 0; i < ModulesCount; i++)
738 {
739 //
740 // For logging purpose
741 //
742
743 /*
744 ShowMessages("%016llx\t%016llx\t%ws\n",
745 Modules[i].BaseAddress,
746 Modules[i].Entrypoint,
747 Modules[i].FilePath);
748 */
749
750 //
751 // Read symbol signature details
752 //
753 RtlZeroMemory(ModuleSymbolPath, sizeof(ModuleSymbolPath));
754 RtlZeroMemory(TempPath, sizeof(TempPath));
755 RtlZeroMemory(ModuleSymbolGuidAndAge, sizeof(ModuleSymbolGuidAndAge));
756
757 //
758 // Convert symbol path from unicode to ascii
759 //
760 wcstombs(TempPath, Modules[i].FilePath, MAX_PATH);
761
763 TempPath,
764 ModuleSymbolPath,
765 ModuleSymbolGuidAndAge,
766 ModuleDetailsRequest->Is32Bit))
767 {
768 IsSymbolPdbDetailAvailable = TRUE;
769
770 // ShowMessages("Hash : %s , Symbol path : %s\n", ModuleSymbolGuidAndAge, ModuleSymbolPath);
771 }
772 else
773 {
774 IsSymbolPdbDetailAvailable = FALSE;
775
776 // ShowMessages("err, unable to get module pdb details\n");
777 }
778
779 //
780 // Build the structure for this module
781 //
782 ModuleSymDetailArray[i].BaseAddress = Modules[i].BaseAddress;
783 ModuleSymDetailArray[i].IsUserMode = TRUE;
784 ModuleSymDetailArray[i].Is32Bit = ModuleDetailsRequest->Is32Bit;
785
786 memcpy(ModuleSymDetailArray[i].FilePath, TempPath, strlen(TempPath));
787
788 if (IsSymbolPdbDetailAvailable)
789 {
790 ModuleSymDetailArray[i].IsSymbolDetailsFound = TRUE;
791 memcpy(ModuleSymDetailArray[i].ModuleSymbolGuidAndAge, ModuleSymbolGuidAndAge, MAXIMUM_GUID_AND_AGE_SIZE);
792 memcpy(ModuleSymDetailArray[i].ModuleSymbolPath, ModuleSymbolPath, MAX_PATH);
793
794 //
795 // Check if pdb file name is a real path or a module name
796 //
797 string ModuleSymbolPathString(ModuleSymbolPath);
798 if (ModuleSymbolPathString.find(":\\") != std::string::npos)
799 ModuleSymDetailArray[i].IsLocalSymbolPath = TRUE;
800 else
801 ModuleSymDetailArray[i].IsLocalSymbolPath = FALSE;
802 }
803 else
804 {
805 ModuleSymDetailArray[i].IsSymbolDetailsFound = FALSE;
806 }
807
808 //
809 // Check if it should be send to the remote debugger over serial
810 // and also make sure that we're connected to the remote debugger
811 // and this is a debuggee
812 //
813 if (SendOverSerial)
814 {
815 KdSendSymbolDetailPacket(&ModuleSymDetailArray[i], i, ModuleInfo->NumberOfModules + ModulesCount);
816 }
817 }
818 }
819
820 //
821 // ----------------------------------------------------------------------------------
822 // Add kernel-modules
823 // ----------------------------------------------------------------------------------
824 //
825
826 for (UINT32 i = 0; i < ModuleInfo->NumberOfModules; i++)
827 {
828 UINT32 IndexInSymbolBuffer = ModulesCount + i;
829
830 auto PathName = ModuleInfo->Modules[i].FullPathName + ModuleInfo->Modules[i].OffsetToFileName;
831
832 //
833 // Read symbol signature details
834 //
835 RtlZeroMemory(ModuleSymbolPath, sizeof(ModuleSymbolPath));
836 RtlZeroMemory(ModuleSymbolGuidAndAge, sizeof(ModuleSymbolGuidAndAge));
837
838 string ModuleFullPath((const char *)ModuleInfo->Modules[i].FullPathName);
839
840 if (ModuleFullPath.rfind("\\SystemRoot\\", 0) == 0)
841 {
842 //
843 // Path starts with \SystemRoot\
844 // we should change it to the real system root
845 // path
846 //
847 Replace(ModuleFullPath, "\\SystemRoot", SystemRootString);
848 }
849
850 //
851 // Kernel modules are all 64-bit
852 //
854 ModuleSymbolPath,
855 ModuleSymbolGuidAndAge,
856 FALSE))
857 {
858 IsSymbolPdbDetailAvailable = TRUE;
859
860 //
861 // ShowMessages("Hash : %s , Symbol path : %s\n", ModuleSymbolGuidAndAge, ModuleSymbolPath);
862 //
863 }
864 else
865 {
866 IsSymbolPdbDetailAvailable = FALSE;
867
868 //
869 // ShowMessages("err, unable to get module pdb details\n");
870 //
871 }
872
873 //
874 // Build the structure for this module
875 //
876 ModuleSymDetailArray[IndexInSymbolBuffer].BaseAddress = (UINT64)ModuleInfo->Modules[i].ImageBase;
877 memcpy(ModuleSymDetailArray[IndexInSymbolBuffer].FilePath, ModuleFullPath.c_str(), ModuleFullPath.size());
878
879 if (IsSymbolPdbDetailAvailable)
880 {
881 ModuleSymDetailArray[IndexInSymbolBuffer].IsSymbolDetailsFound = TRUE;
882 memcpy(ModuleSymDetailArray[IndexInSymbolBuffer].ModuleSymbolGuidAndAge, ModuleSymbolGuidAndAge, MAXIMUM_GUID_AND_AGE_SIZE);
883 memcpy(ModuleSymDetailArray[IndexInSymbolBuffer].ModuleSymbolPath, ModuleSymbolPath, MAX_PATH);
884
885 //
886 // Check if pdb file name is a real path or a module name
887 //
888 string ModuleSymbolPathString(ModuleSymbolPath);
889 if (ModuleSymbolPathString.find(":\\") != std::string::npos)
890 ModuleSymDetailArray[IndexInSymbolBuffer].IsLocalSymbolPath = TRUE;
891 else
892 ModuleSymDetailArray[IndexInSymbolBuffer].IsLocalSymbolPath = FALSE;
893 }
894 else
895 {
896 ModuleSymDetailArray[IndexInSymbolBuffer].IsSymbolDetailsFound = FALSE;
897 }
898
899 //
900 // Check if it should be send to the remote debugger over serial
901 // and also make sure that we're connected to the remote debugger
902 // and this is a debuggee
903 //
904 if (SendOverSerial)
905 {
906 KdSendSymbolDetailPacket(&ModuleSymDetailArray[IndexInSymbolBuffer], i, ModuleInfo->NumberOfModules + ModulesCount);
907 }
908 }
909
910 //
911 // ----------------------------------------------------------------------------------
912 //
913
914 //
915 // Store the buffer and length of module symbols details
916 //
917 *BufferToStoreDetails = ModuleSymDetailArray;
918 *StoredLength = (ModuleInfo->NumberOfModules + ModulesCount) * sizeof(MODULE_SYMBOL_DETAIL);
919
920 VirtualFree(ModuleInfo, 0, MEM_RELEASE);
921
922 if (IsFreeUsermodeModulesBuffer)
923 {
924 free(ModuleDetailsRequest);
925 }
926
927 return TRUE;
928}
UCHAR BOOLEAN
Definition BasicTypes.h:39
unsigned __int64 UINT64
Definition BasicTypes.h:21
unsigned int UINT32
Definition BasicTypes.h:48
unsigned long ULONG
Definition BasicTypes.h:37
#define MAXIMUM_GUID_AND_AGE_SIZE
maximum size for GUID and Age of PE @detail It seems that 33 bytes is enough but let's have more spac...
Definition Constants.h:491
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
@ SystemModuleInformation
Definition Hooks.h:116
enum _SYSTEM_INFORMATION_CLASS SYSTEM_INFORMATION_CLASS
System information class.
UINT32 StoredLength
Definition HyperDbgScriptImports.h:65
#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
struct _RTL_PROCESS_MODULES * PRTL_PROCESS_MODULES
BOOL Replace(std::string &str, const std::string &from, const std::string &to)
general replace all function
Definition common.cpp:73
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:38
VOID KdSendSymbolDetailPacket(PMODULE_SYMBOL_DETAIL SymbolDetailPacket, UINT32 CurrentSymbolInfoIndex, UINT32 TotalSymbols)
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
NULL()
Definition test-case-generator.py:530
BOOLEAN ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetailsWrapper(const char *LocalFilePath, char *PdbFilePath, char *GuidAndAgeDetails, BOOLEAN Is32BitModule)
ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails wrapper.
Definition script-engine-wrapper.cpp:245
BOOLEAN IsUserMode
Definition Symbols.h:29
BOOLEAN Is32Bit
Definition Symbols.h:30
UINT64 BaseAddress
Definition Symbols.h:31
BOOLEAN IsLocalSymbolPath
Definition Symbols.h:26
BOOLEAN IsSymbolDetailsFound
Definition Symbols.h:25
Definition Windows.h:33
ULONG NumberOfModules
Definition Windows.h:34
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
UINT64 BaseAddress
Definition Symbols.h:40
BOOLEAN SymbolDeleteSymTable()
Delete and free structures and variables related to the symbols.
Definition symbol.cpp:433

◆ SymbolConvertNameOrExprToAddress()

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 evaluate expressions

Parameters
TextToConvertthe target string
Resultresult will be save to the pointer
Returns
BOOLEAN shows whether the conversion was successful or not
361{
362 BOOLEAN IsFound = FALSE;
363 BOOLEAN HasError = NULL;
365
366 if (!ConvertStringToUInt64(TextToConvert, &Address))
367 {
368 //
369 // Check for symbol object names
370 //
371 string ConstTextToConvert = TextToConvert;
372 Address = ScriptEngineConvertNameToAddressWrapper(ConstTextToConvert.c_str(), &IsFound);
373
374 if (!IsFound)
375 {
376 //
377 // It's neither a number, nor a founded object name,
378 // as the last resort, we have to test whether it's an expression or not
379 // if we're in the Debugger Mode then we have to send it the kernel to get
380 // the evaluation, if we're in VMI mode, then we evaluate it here with all
381 // registers set to Zero
382 //
383 Address = ScriptEngineEvalSingleExpression(TextToConvert, &HasError);
384
385 if (HasError)
386 {
387 //
388 // Not found or has error
389 //
390 IsFound = FALSE;
391 }
392 else
393 {
394 //
395 // Expression evaluated successfully
396 //
397 IsFound = TRUE;
398 }
399 }
400 else
401 {
402 //
403 // Object name is found
404 //
405 IsFound = TRUE;
406 }
407 }
408 else
409 {
410 //
411 // It's a hex number
412 //
413 IsFound = TRUE;
414 }
415
416 //
417 // Set the number if the address is founded
418 //
419 if (IsFound)
420 {
421 *Result = Address;
422 }
423
424 return IsFound;
425}
UINT64 Address
Definition HyperDbgScriptImports.h:67
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
UINT64 ScriptEngineConvertNameToAddressWrapper(const char *FunctionOrVariableName, PBOOLEAN WasFound)
ScriptEngineConvertNameToAddress wrapper.
Definition script-engine-wrapper.cpp:53
UINT64 ScriptEngineEvalSingleExpression(string Expr, PBOOLEAN HasError)
Get the value from the evaluation of single expression from local debuggee and remote debuggee.
Definition script-engine.cpp:30

◆ SymbolCreateDisassemblerMapCallback()

VOID SymbolCreateDisassemblerMapCallback ( UINT64 Address,
char * ModuleName,
char * ObjectName,
unsigned int ObjectSize )

Callback for creating symbol map for disassembler.

Parameters
Address
ModuleName
ObjectName
ObjectSize
Returns
VOID
93{
94 //
95 // It has a string, should not be initialized with zero
96 //
97 LOCAL_FUNCTION_DESCRIPTION LocalFunctionDescription = {};
98 string FinalModuleName = "";
99
100 if (ObjectSize == 0)
101 {
103 }
104
105 //
106 // Convert module name to string
107 //
108 if (ModuleName != NULL)
109 {
110 FinalModuleName += std::string(ModuleName) + "!";
111 }
112
113 //
114 // Convert object name to string
115 //
116 if (ObjectName != NULL)
117 {
118 FinalModuleName += std::string(ObjectName);
119 }
120
121 //
122 // Create the structure
123 //
124 LocalFunctionDescription.ObjectName = std::move(FinalModuleName);
125 LocalFunctionDescription.ObjectSize = ObjectSize;
126
127 //
128 // Add to disassembler map
129 //
130 g_DisassemblerSymbolMap[Address] = LocalFunctionDescription;
131}
#define DISASSEMBLY_MAXIMUM_DISTANCE_FROM_OBJECT_NAME
Maximum length for a function (to be used in showing distance from symbol functions in the 'u' comman...
Definition Constants.h:593
Save the local function symbols' description.
Definition symbol.h:23
UINT32 ObjectSize
Definition symbol.h:25
std::string ObjectName
Definition symbol.h:24
std::map< UINT64, LOCAL_FUNCTION_DESCRIPTION > g_DisassemblerSymbolMap
Symbol table for disassembler.
Definition globals.h:512

◆ SymbolCreateDisassemblerSymbolMap()

BOOLEAN SymbolCreateDisassemblerSymbolMap ( )

Update (or create) symbol map for the disassembler.

Returns
BOOLEAN
140{
141 //
142 // Clear the map table
143 //
145
146 //
147 // Get all the symbols in the callback
148 //
150
151 return TRUE;
152}
BOOLEAN ScriptEngineCreateSymbolTableForDisassemblerWrapper(void *CallbackFunction)
ScriptEngineCreateSymbolTableForDisassembler wrapper.
Definition script-engine-wrapper.cpp:159
VOID SymbolCreateDisassemblerMapCallback(UINT64 Address, char *ModuleName, char *ObjectName, unsigned int ObjectSize)
Callback for creating symbol map for disassembler.
Definition symbol.cpp:89

◆ SymbolDeleteSymTable()

BOOLEAN SymbolDeleteSymTable ( )

Delete and free structures and variables related to the symbols.

Returns
BOOLEAN shows whether the operation was successful or not
434{
435 //
436 // Unload all symbols
437 //
439
440 //
441 // Delete symbols
442 //
443 if (g_SymbolTable != NULL)
444 {
445 free(g_SymbolTable);
446
450 return TRUE;
451 }
452 else
453 {
454 return FALSE;
455 }
456}
UINT32 ScriptEngineUnloadAllSymbolsWrapper()
ScriptEngineUnloadAllSymbols wrapper.
Definition script-engine-wrapper.cpp:91

◆ SymbolInitialReload()

VOID SymbolInitialReload ( )

Initial load of symbols (for previously download symbols)

Returns
VOID
35{
36 //
37 // Load already downloaded symbol (won't download at this point)
38 //
39 ShowMessages("interpreting symbols and creating symbol maps\n");
41}
BOOLEAN SymbolLoadOrDownloadSymbols(BOOLEAN IsDownload, BOOLEAN SilentLoad)
Load or download symbols.
Definition symbol.cpp:299

◆ SymbolLoadOrDownloadSymbols()

BOOLEAN SymbolLoadOrDownloadSymbols ( BOOLEAN IsDownload,
BOOLEAN SilentLoad )

Load or download symbols.

Parameters
IsDownloadDownload from remote server if not available locally
SilentLoadLoad without any message
Returns
BOOLEAN
300{
301 string SymbolServer;
302 BOOLEAN Result = FALSE;
303
304 //
305 // *** Read symbol path/server from config file ***
306 //
307
308 if (!CommandSettingsGetValueFromConfigFile("SymbolServer", SymbolServer))
309 {
310 ShowMessages("please configure the symbol path (use '.help .sympath' for more information)\n");
311 return FALSE;
312 }
313
314 //
315 // Check if symbol table is empty
316 //
317 if (g_SymbolTable == NULL || g_SymbolTableSize == NULL)
318 {
319 ShowMessages("symbol table is empty, please use '.sym reload' to build a symbol table\n");
320 return FALSE;
321 }
322
323 //
324 // *** Load or download available symbols ***
325 //
326
327 //
328 // Indicate that we're in loading routines
329 //
333 IsDownload,
334 SymbolServer.c_str(),
335 SilentLoad);
336
337 //
338 // Build symbol table for disassembler
339 //
341
342 //
343 // Not in loading routines anymore
344 //
346
347 return Result;
348}
BOOLEAN ScriptEngineSymbolInitLoadWrapper(PMODULE_SYMBOL_DETAIL BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char *SymbolPath, BOOLEAN IsSilentLoad)
ScriptEngineSymbolInitLoad wrapper.
Definition script-engine-wrapper.cpp:191
BOOLEAN CommandSettingsGetValueFromConfigFile(std::string OptionName, std::string &OptionValue)
Gets the setting values from config file.
Definition settings.cpp:60
BOOLEAN SymbolCreateDisassemblerSymbolMap()
Update (or create) symbol map for the disassembler.
Definition symbol.cpp:139
BOOLEAN g_IsExecutingSymbolLoadingRoutines
Executing symbol reloading or downloading routines.
Definition globals.h:506

◆ SymbolLocalReload()

BOOLEAN SymbolLocalReload ( UINT32 UserProcessId)

Locally reload the symbol table.

Parameters
UserProcessId
Returns
BOOLEAN
51{
52 ShowMessages("interpreting symbols and creating symbol maps\n");
53
55
56 //
57 // And also load the symbols
58 //
60}
BOOLEAN SymbolBuildSymbolTable(PMODULE_SYMBOL_DETAIL *BufferToStoreDetails, PUINT32 StoredLength, UINT32 UserProcessId, BOOLEAN SendOverSerial)
make the initial packet required for symbol server or reload packet
Definition symbol.cpp:472

◆ SymbolPrepareDebuggerWithSymbolInfo()

VOID SymbolPrepareDebuggerWithSymbolInfo ( UINT32 UserProcessId)

Initial and send the results of serial for the debugger in the case of debugger mode.

Parameters
UserProcessId
Returns
VOID
71{
72 //
73 // Load already downloaded symbol (won't download at this point)
74 //
76}

◆ SymbolReloadSymbolTableInDebuggerMode()

BOOLEAN SymbolReloadSymbolTableInDebuggerMode ( UINT32 ProcessId)

Update the symbol table from remote debuggee in debugger mode.

Parameters
ProcessId
Returns
BOOLEAN shows whether the operation was successful or not
1005{
1006 //
1007 // Check if we found an already built symbol table
1008 //
1010
1011 //
1012 // Request to send new symbol details
1013 //
1015 {
1016 ShowMessages("symbol table updated successfully\n");
1017 return TRUE;
1018 }
1019 else
1020 {
1021 return FALSE;
1022 }
1023}
BOOLEAN KdSendSymbolReloadPacketToDebuggee(UINT32 ProcessId)
Send symbol reload packet to the debuggee.
Definition kd.cpp:493

◆ SymbolShowFunctionNameBasedOnAddress()

BOOLEAN SymbolShowFunctionNameBasedOnAddress ( UINT64 Address,
PUINT64 UsedBaseAddress )

shows the functions' name for the disassembler

Parameters
Address
UsedBaseAddress
Returns
BOOLEAN
163{
164 std::map<UINT64, LOCAL_FUNCTION_DESCRIPTION>::iterator Low, Prev;
165 UINT64 Pos = Address;
166
167 //
168 // Check if showing function (object) names is not prohibited
169 // form settings command
170 //
172 {
173 return FALSE;
174 }
175
176 //
177 // Check if we already built the symbol map for disassembler or not
178 //
179 if (!g_DisassemblerSymbolMap.empty())
180 {
181 Low = g_DisassemblerSymbolMap.lower_bound(Pos);
182
183 if (Low == g_DisassemblerSymbolMap.end())
184 {
185 //
186 // Nothing found, maybe use rbegin()
187 //
188 return FALSE;
189 }
190 else if (Low == g_DisassemblerSymbolMap.begin() && Low->first > Address)
191 {
192 //
193 // Nothing to do, address is below the lowest entry in symbol table
194 //
195 return FALSE;
196 }
197 else if (Low->first == Address)
198 {
199 if (*UsedBaseAddress != Address)
200 {
201 ShowMessages("%s", Low->second.ObjectName.c_str());
202 *UsedBaseAddress = Address;
203 return TRUE;
204 }
205
206 return FALSE;
207 }
208 else
209 {
210 Prev = std::prev(Low);
211 UINT64 Diff = Address - Prev->first;
212
213 //
214 // Check, so we have a threshold boundary to add +xx to the
215 // symbols function name, in otherwords, the maximum number of
216 // bytes that a function could contain (it's definitely not the
217 // best option to find start and end of function, it's an approximate
218 // and not always might be true)
219 //
220 if (Prev->second.ObjectSize >= Diff)
221 {
222 if (*UsedBaseAddress != Prev->first)
223 {
224 ShowMessages("%s+0x%x", Prev->second.ObjectName.c_str(), Diff);
225 *UsedBaseAddress = Prev->first;
226 return TRUE;
227 }
228
229 return FALSE;
230 }
232 {
233 //
234 // We add the logic of adding Name+X+X to show that a address is x bytes
235 // after the Object Name and not within the size of the function but x
236 // bytes from the above of the function
237 //
238 if (*UsedBaseAddress != Prev->first)
239 {
240 ShowMessages("%s+0x%x+0x%x", Prev->second.ObjectName.c_str(), Diff, Diff - Prev->second.ObjectSize);
241 *UsedBaseAddress = Prev->first;
242 return TRUE;
243 }
244
245 return FALSE;
246 }
247 }
248 }
249
250 //
251 // Nothing is showed
252 //
253 return FALSE;
254}
BOOLEAN g_AddressConversion
Whether converting addresses to object names or not.
Definition globals.h:584

Variable Documentation

◆ g_AddressConversion

BOOLEAN g_AddressConversion
extern

Whether converting addresses to object names or not.

it is enabled by default

◆ g_DisassemblerSymbolMap

std::map<UINT64, LOCAL_FUNCTION_DESCRIPTION> g_DisassemblerSymbolMap
extern

Symbol table for disassembler.

◆ g_IsExecutingSymbolLoadingRoutines

BOOLEAN g_IsExecutingSymbolLoadingRoutines
extern

Executing symbol reloading or downloading routines.

◆ g_IsSerialConnectedToRemoteDebugger

BOOLEAN g_IsSerialConnectedToRemoteDebugger
extern

Shows if the debugger was connected to remote debugger (A remote host)

◆ g_SymbolTable

PMODULE_SYMBOL_DETAIL g_SymbolTable
extern

The buffer that stores the details of symbol table.

◆ g_SymbolTableCurrentIndex

UINT32 g_SymbolTableCurrentIndex
extern

The index to hold the track of added symbols.

◆ g_SymbolTableSize

UINT32 g_SymbolTableSize
extern

The buffer that stores size of the details of symbol table.