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, UINT32 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.
BOOLEAN SymbolCheckAndAllocateModuleInformation (PRTL_PROCESS_MODULES *Modules)
 Check and allocate module information.

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_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
264{
265 if (g_SymbolTable == NULL || g_SymbolTableSize == NULL)
266 {
267 ShowMessages("err, symbol table is empty. please use '.sym reload' "
268 "to build the symbol table\n");
269 return;
270 }
271
272 //
273 // show packet details
274 //
275 for (SIZE_T i = 0; i < g_SymbolTableSize / sizeof(MODULE_SYMBOL_DETAIL); i++)
276 {
277 ShowMessages("is pdb details available? : %s\n", g_SymbolTable[i].IsSymbolDetailsFound ? "true" : "false");
278 ShowMessages("is pdb a path instead of module name? : %s\n", g_SymbolTable[i].IsLocalSymbolPath ? "true" : "false");
279 ShowMessages("base address : %llx\n", g_SymbolTable[i].BaseAddress);
280 ShowMessages("file path : %s\n", g_SymbolTable[i].FilePath);
281 ShowMessages("guid and age : %s\n", g_SymbolTable[i].ModuleSymbolGuidAndAge);
282 ShowMessages("module symbol path/name : %s\n", g_SymbolTable[i].ModuleSymbolPath);
283 ShowMessages("is user-mode? : %s - is 32-bit? %s\n",
284 g_SymbolTable[i].IsUserMode ? "true" : "false",
285 g_SymbolTable[i].Is32Bit ? "true" : "false");
286 ShowMessages("========================================================================\n");
287 }
288}
struct _MODULE_SYMBOL_DETAIL MODULE_SYMBOL_DETAIL
structures for sending and saving details about each module and symbols details
PMODULE_SYMBOL_DETAIL g_SymbolTable
The buffer that stores the details of symbol table.
Definition globals.h:619
UINT32 g_SymbolTableSize
The buffer that stores size of the details of symbol table.
Definition globals.h:626

◆ 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
1211{
1212 //
1213 // Check to avoid overflow in symbol table
1214 //
1216 {
1217 ShowMessages("err, the symbol table buffer is full, unable to add new symbol\n");
1218 return FALSE;
1219 }
1220
1221 //
1222 // Check if we found an already built symbol table
1223 //
1224 if (g_SymbolTable == NULL)
1225 {
1226 //
1227 // Allocate Details buffer
1228 //
1230
1231 if (g_SymbolTable == NULL)
1232 {
1233 ShowMessages("err, unable to allocate memory for module list (%x)\n",
1234 GetLastError());
1235 return FALSE;
1236 }
1237
1238 //
1239 // Reset the index
1240 //
1242
1243 //
1244 // Make sure buffer is zero
1245 //
1247 }
1248
1249 //
1250 // Move it to the new buffer
1251 //
1252 memcpy(&g_SymbolTable[g_SymbolTableCurrentIndex], SymbolDetail, sizeof(MODULE_SYMBOL_DETAIL));
1253
1254 //
1255 // Add to index for future symbols
1256 //
1258
1259 //
1260 // Compute the (new) current size
1261 //
1263
1264 return TRUE;
1265}
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
#define MAXIMUM_SUPPORTED_SYMBOLS
maximum supported modules to load their symbol information
Definition Constants.h:485
struct _MODULE_SYMBOL_DETAIL * PMODULE_SYMBOL_DETAIL
UINT32 g_SymbolTableCurrentIndex
The index to hold the track of added symbols.
Definition globals.h:633

◆ 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
760{
761 BOOLEAN Status;
762 ULONG ReturnedLength;
763 PRTL_PROCESS_MODULES ModuleInfo = NULL;
764 PMODULE_SYMBOL_DETAIL ModuleSymDetailArray = NULL;
765 CHAR SystemRoot[MAX_PATH] = {0};
766 CHAR ModuleSymbolPath[MAX_PATH] = {0};
767 CHAR TempPath[MAX_PATH] = {0};
768 CHAR ModuleSymbolGuidAndAge[MAXIMUM_GUID_AND_AGE_SIZE] = {0};
769 BOOLEAN IsSymbolPdbDetailAvailable = FALSE;
770 BOOLEAN IsFreeUsermodeModulesBuffer = FALSE;
771 UINT32 ModuleDetailsSize = 0;
772 UINT32 ModulesCount = 0;
773 PUSERMODE_LOADED_MODULE_DETAILS ModuleDetailsRequest = NULL;
775 USERMODE_LOADED_MODULE_DETAILS ModuleCountRequest = {0};
776
777 //
778 // Check if we found an already built symbol table
779 //
781
782 //
783 // Get system root
784 //
785 if (GetSystemDirectoryA(SystemRoot, MAX_PATH) == NULL)
786 {
787 ShowMessages("err, unable to get system directory (%x)\n",
788 GetLastError());
789
790 return FALSE;
791 }
792
793 string SystemRootString(SystemRoot);
794
795 //
796 // Convert root path to lower-case
797 //
798 transform(SystemRootString.begin(),
799 SystemRootString.end(),
800 SystemRootString.begin(),
801 [](UCHAR c) { return std::tolower(c); });
802
803 //
804 // Remove system32 from the root
805 //
806 Replace(SystemRootString, "\\system32", "");
807
808 //
809 // *****************************************************************
810 // Get kernel-mode modules information
811 // *****************************************************************
812 //
814 {
815 ShowMessages("err, unable to get module information\n");
816 return FALSE;
817 }
818
819 //
820 // *****************************************************************
821 // Get user-mode modules information
822 // *****************************************************************
823 //
824
825 //
826 // We won't fail the entire process if the user-mode modules is failed
827 //
828
829 do
830 {
831 //
832 // Check if debugger is loaded or not
833 //
834 if (!g_DeviceHandle)
835 {
836 break;
837 }
838
839 //
840 // Set the module details to get the details
841 //
842 ModuleCountRequest.ProcessId = UserProcessId;
843 ModuleCountRequest.OnlyCountModules = TRUE;
844
845 //
846 // Send the request to the kernel
847 //
848 Status = DeviceIoControl(
849 g_DeviceHandle, // Handle to device
851 // code
852 &ModuleCountRequest, // Input Buffer to driver.
853 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Input buffer length
854 &ModuleCountRequest, // Output Buffer from driver.
855 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Length of output
856 // buffer in bytes.
857 &ReturnedLength, // Bytes placed in buffer.
858 NULL // synchronous call
859 );
860
861 if (!Status)
862 {
863 break;
864 }
865
866 //
867 // Check if counting modules was successful or not
868 //
869 if (ModuleCountRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
870 {
871 ModulesCount = ModuleCountRequest.ModulesCount;
872
873 // ShowMessages("Count of modules : 0x%x\n", ModuleCountRequest.ModulesCount);
874
875 ModuleDetailsSize = sizeof(USERMODE_LOADED_MODULE_DETAILS) +
876 (ModuleCountRequest.ModulesCount * sizeof(USERMODE_LOADED_MODULE_SYMBOLS));
877
878 ModuleDetailsRequest = (PUSERMODE_LOADED_MODULE_DETAILS)malloc(ModuleDetailsSize);
879
880 if (ModuleDetailsRequest == NULL)
881 {
882 break;
883 }
884
885 RtlZeroMemory(ModuleDetailsRequest, ModuleDetailsSize);
886
887 //
888 // Set the module details to get the modules (not count)
889 //
890 ModuleDetailsRequest->ProcessId = UserProcessId;
891 ModuleDetailsRequest->OnlyCountModules = FALSE;
892
893 //
894 // Send the request to the kernel
895 //
896 Status = DeviceIoControl(
897 g_DeviceHandle, // Handle to device
899 // code
900 ModuleDetailsRequest, // Input Buffer to driver.
901 sizeof(USERMODE_LOADED_MODULE_DETAILS), // Input buffer length
902 ModuleDetailsRequest, // Output Buffer from driver.
903 ModuleDetailsSize, // Length of output
904 // buffer in bytes.
905 &ReturnedLength, // Bytes placed in buffer.
906 NULL // synchronous call
907 );
908
909 if (!Status)
910 {
911 free(ModuleDetailsRequest);
912 break;
913 }
914
915 //
916 // check the module list
917 //
918 if (ModuleDetailsRequest->Result == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
919 {
920 //
921 // Se the modules buffer
922 //
923 Modules = (PUSERMODE_LOADED_MODULE_SYMBOLS)((UINT64)ModuleDetailsRequest +
925
926 //
927 // Check if modules buffer is valid
928 //
929 if (Modules == NULL)
930 {
931 ModulesCount = 0;
932 free(ModuleDetailsRequest);
933 break;
934 }
935 }
936 else
937 {
938 ShowErrorMessage(ModuleDetailsRequest->Result);
939 free(ModuleDetailsRequest);
940 break;
941 }
942
943 //
944 // Everything is okay when we reached here
945 //
946 IsFreeUsermodeModulesBuffer = TRUE;
947 }
948 else
949 {
950 ShowErrorMessage(ModuleCountRequest.Result);
951 break;
952 }
953
954 } while (FALSE);
955
956 //
957 // *****************************************************************
958 //
959
960 //
961 // Allocate Details buffer
962 //
963 ModuleSymDetailArray = (PMODULE_SYMBOL_DETAIL)malloc(
964 (ModuleInfo->NumberOfModules + ModulesCount) * sizeof(MODULE_SYMBOL_DETAIL));
965
966 if (ModuleSymDetailArray == NULL)
967 {
968 ShowMessages("err, unable to allocate memory for module list (%x)\n",
969 GetLastError());
970
971 if (IsFreeUsermodeModulesBuffer)
972 {
973 free(ModuleDetailsRequest);
974 }
975
976 free(ModuleInfo);
977 return FALSE;
978 }
979
980 //
981 // Make sure buffer is zero
982 //
983 RtlZeroMemory(ModuleSymDetailArray, (ModuleInfo->NumberOfModules + ModulesCount) * sizeof(MODULE_SYMBOL_DETAIL));
984
985 //
986 // ----------------------------------------------------------------------------------
987 // Add user-modules
988 // ----------------------------------------------------------------------------------
989 //
990
991 if (ModulesCount != 0)
992 {
993 for (UINT32 i = 0; i < ModulesCount; i++)
994 {
995 //
996 // For logging purpose
997 //
998
999 /*
1000 ShowMessages("%016llx\t%016llx\t%ws\n",
1001 Modules[i].BaseAddress,
1002 Modules[i].Entrypoint,
1003 Modules[i].FilePath);
1004 */
1005
1006 //
1007 // Read symbol signature details
1008 //
1009 RtlZeroMemory(ModuleSymbolPath, sizeof(ModuleSymbolPath));
1010 RtlZeroMemory(TempPath, sizeof(TempPath));
1011 RtlZeroMemory(ModuleSymbolGuidAndAge, sizeof(ModuleSymbolGuidAndAge));
1012 std::vector<BYTE> LoadedImageBytes;
1013
1014 //
1015 // Convert symbol path from unicode to ascii
1016 //
1017 wcstombs(TempPath, Modules[i].FilePath, MAX_PATH);
1018
1019 if (SendOverSerial && Modules[i].BaseAddress != 0 &&
1020 SymbolReadLoadedUserModuleForCodeView(Modules[i].BaseAddress, UserProcessId, LoadedImageBytes) &&
1022 LoadedImageBytes.size(),
1023 TempPath,
1024 ModuleSymbolPath,
1025 ModuleSymbolGuidAndAge,
1026 ModuleDetailsRequest->Is32Bit))
1027 {
1028 IsSymbolPdbDetailAvailable = TRUE;
1029
1030 // ShowMessages("Hash : %s , Symbol path : %s\n", ModuleSymbolGuidAndAge, ModuleSymbolPath);
1031 }
1033 TempPath,
1034 ModuleSymbolPath,
1035 ModuleSymbolGuidAndAge,
1036 ModuleDetailsRequest->Is32Bit))
1037 {
1038 IsSymbolPdbDetailAvailable = TRUE;
1039
1040 // ShowMessages("Hash : %s , Symbol path : %s\n", ModuleSymbolGuidAndAge, ModuleSymbolPath);
1041 }
1042 else
1043 {
1044 IsSymbolPdbDetailAvailable = FALSE;
1045
1046 // ShowMessages("err, unable to get module pdb details\n");
1047 }
1048
1049 //
1050 // Build the structure for this module
1051 //
1052 ModuleSymDetailArray[i].BaseAddress = Modules[i].BaseAddress;
1053 ModuleSymDetailArray[i].IsUserMode = TRUE;
1054 ModuleSymDetailArray[i].Is32Bit = ModuleDetailsRequest->Is32Bit;
1055
1056 memcpy(ModuleSymDetailArray[i].FilePath, TempPath, strlen(TempPath));
1057
1058 if (IsSymbolPdbDetailAvailable)
1059 {
1060 ModuleSymDetailArray[i].IsSymbolDetailsFound = TRUE;
1061 memcpy(ModuleSymDetailArray[i].ModuleSymbolGuidAndAge, ModuleSymbolGuidAndAge, MAXIMUM_GUID_AND_AGE_SIZE);
1062 memcpy(ModuleSymDetailArray[i].ModuleSymbolPath, ModuleSymbolPath, MAX_PATH);
1063
1064 //
1065 // Check if pdb file name is a real path or a module name
1066 //
1067 string ModuleSymbolPathString(ModuleSymbolPath);
1068 if (ModuleSymbolPathString.find(":\\") != std::string::npos)
1069 ModuleSymDetailArray[i].IsLocalSymbolPath = TRUE;
1070 else
1071 ModuleSymDetailArray[i].IsLocalSymbolPath = FALSE;
1072 }
1073 else
1074 {
1075 ModuleSymDetailArray[i].IsSymbolDetailsFound = FALSE;
1076 }
1077
1078 //
1079 // Check if it should be send to the remote debugger over serial
1080 // and also make sure that we're connected to the remote debugger
1081 // and this is a debuggee
1082 //
1083 if (SendOverSerial)
1084 {
1085 KdSendSymbolDetailPacket(&ModuleSymDetailArray[i], i, ModuleInfo->NumberOfModules + ModulesCount);
1086 }
1087 }
1088 }
1089
1090 //
1091 // ----------------------------------------------------------------------------------
1092 // Add kernel-modules
1093 // ----------------------------------------------------------------------------------
1094 //
1095
1096 for (UINT32 i = 0; i < ModuleInfo->NumberOfModules; i++)
1097 {
1098 UINT32 IndexInSymbolBuffer = ModulesCount + i;
1099
1100 auto PathName = ModuleInfo->Modules[i].FullPathName + ModuleInfo->Modules[i].OffsetToFileName;
1101
1102 //
1103 // Read symbol signature details
1104 //
1105 RtlZeroMemory(ModuleSymbolPath, sizeof(ModuleSymbolPath));
1106 RtlZeroMemory(ModuleSymbolGuidAndAge, sizeof(ModuleSymbolGuidAndAge));
1107
1108 string ModuleFullPath((const CHAR *)ModuleInfo->Modules[i].FullPathName);
1109
1110 if (ModuleFullPath.rfind("\\SystemRoot\\", 0) == 0)
1111 {
1112 //
1113 // Path starts with \SystemRoot\
1114 // we should change it to the real system root
1115 // path
1116 //
1117 Replace(ModuleFullPath, "\\SystemRoot", SystemRootString);
1118 }
1119
1120 //
1121 // Kernel modules are all 64-bit
1122 //
1124 ModuleSymbolPath,
1125 ModuleSymbolGuidAndAge,
1126 FALSE))
1127 {
1128 IsSymbolPdbDetailAvailable = TRUE;
1129
1130 //
1131 // ShowMessages("Hash : %s , Symbol path : %s\n", ModuleSymbolGuidAndAge, ModuleSymbolPath);
1132 //
1133 }
1134 else
1135 {
1136 IsSymbolPdbDetailAvailable = FALSE;
1137
1138 //
1139 // ShowMessages("err, unable to get module pdb details\n");
1140 //
1141 }
1142
1143 //
1144 // Build the structure for this module
1145 //
1146 ModuleSymDetailArray[IndexInSymbolBuffer].BaseAddress = (UINT64)ModuleInfo->Modules[i].ImageBase;
1147 memcpy(ModuleSymDetailArray[IndexInSymbolBuffer].FilePath, ModuleFullPath.c_str(), ModuleFullPath.size());
1148
1149 if (IsSymbolPdbDetailAvailable)
1150 {
1151 ModuleSymDetailArray[IndexInSymbolBuffer].IsSymbolDetailsFound = TRUE;
1152 memcpy(ModuleSymDetailArray[IndexInSymbolBuffer].ModuleSymbolGuidAndAge, ModuleSymbolGuidAndAge, MAXIMUM_GUID_AND_AGE_SIZE);
1153 memcpy(ModuleSymDetailArray[IndexInSymbolBuffer].ModuleSymbolPath, ModuleSymbolPath, MAX_PATH);
1154
1155 //
1156 // Check if pdb file name is a real path or a module name
1157 //
1158 string ModuleSymbolPathString(ModuleSymbolPath);
1159 if (ModuleSymbolPathString.find(":\\") != std::string::npos)
1160 ModuleSymDetailArray[IndexInSymbolBuffer].IsLocalSymbolPath = TRUE;
1161 else
1162 ModuleSymDetailArray[IndexInSymbolBuffer].IsLocalSymbolPath = FALSE;
1163 }
1164 else
1165 {
1166 ModuleSymDetailArray[IndexInSymbolBuffer].IsSymbolDetailsFound = FALSE;
1167 }
1168
1169 //
1170 // Check if it should be send to the remote debugger over serial
1171 // and also make sure that we're connected to the remote debugger
1172 // and this is a debuggee
1173 //
1174 if (SendOverSerial)
1175 {
1176 KdSendSymbolDetailPacket(&ModuleSymDetailArray[IndexInSymbolBuffer], IndexInSymbolBuffer, ModuleInfo->NumberOfModules + ModulesCount);
1177 }
1178 }
1179
1180 //
1181 // ----------------------------------------------------------------------------------
1182 //
1183
1184 //
1185 // Store the buffer and length of module symbols details
1186 //
1187 *BufferToStoreDetails = ModuleSymDetailArray;
1188 *StoredLength = (ModuleInfo->NumberOfModules + ModulesCount) * sizeof(MODULE_SYMBOL_DETAIL);
1189
1190 free(ModuleInfo);
1191
1192 if (IsFreeUsermodeModulesBuffer)
1193 {
1194 free(ModuleDetailsRequest);
1195 }
1196
1197 return TRUE;
1198}
struct _RTL_PROCESS_MODULES * PRTL_PROCESS_MODULES
UCHAR BOOLEAN
Definition BasicTypes.h:35
unsigned char UCHAR
Definition BasicTypes.h:34
unsigned int UINT32
Definition BasicTypes.h:54
char CHAR
Definition BasicTypes.h:33
unsigned long ULONG
Definition BasicTypes.h:31
#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:493
#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
BOOLEAN ShowErrorMessage(UINT32 Error)
shows the error message
Definition debugger.cpp:40
VOID KdSendSymbolDetailPacket(PMODULE_SYMBOL_DETAIL SymbolDetailPacket, UINT32 CurrentSymbolInfoIndex, UINT32 TotalSymbols)
Send each packet of debugging information (PDB) to the debugger.
Definition kd.cpp:3424
BOOL Replace(std::string &str, const std::string &from, const std::string &to)
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
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:246
BOOLEAN ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetailsWrapper(const BYTE *LoadedImageBytes, SIZE_T LoadedImageSize, const CHAR *LocalFilePath, CHAR *PdbFilePath, CHAR *GuidAndAgeDetails, BOOLEAN Is32BitModule)
ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails wrapper.
Definition script-engine-wrapper.cpp:268
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
ULONG NumberOfModules
Definition Windows.h:34
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
UINT64 BaseAddress
Definition Symbols.h:40
BOOLEAN SymbolCheckAndAllocateModuleInformation(PRTL_PROCESS_MODULES *Modules)
Check and allocate module information.
Definition symbol.cpp:1303
BOOLEAN SymbolDeleteSymTable()
Delete and free structures and variables related to the symbols.
Definition symbol.cpp:717

◆ SymbolCheckAndAllocateModuleInformation()

BOOLEAN SymbolCheckAndAllocateModuleInformation ( PRTL_PROCESS_MODULES * Modules)

Check and allocate module information.

The caller should free the buffer

Parameters
Modules
Returns
BOOLEAN
1304{
1305 NTSTATUS Status = STATUS_UNSUCCESSFUL;
1306 ULONG SysModuleInfoBufferSize = 0;
1307
1308 //
1309 // Enable Debug privilege to the current token
1310 //
1312 {
1313 ShowMessages("err, couldn't set debug privilege\n");
1314 return FALSE;
1315 }
1316
1317 //
1318 // Get required size of "RTL_PROCESS_MODULES" buffer
1319 //
1320 Status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, NULL, NULL, &SysModuleInfoBufferSize);
1321
1322 //
1323 // print the size of the buffer
1324 //
1325 // ShowMessages("size of the buffer : %x\n", SysModuleInfoBufferSize);
1326
1327 *Modules = (PRTL_PROCESS_MODULES)malloc(SysModuleInfoBufferSize);
1328
1329 if (*Modules == NULL)
1330 {
1331 ShowMessages("err, unable to allocate memory for module list (%x)\n",
1332 GetLastError());
1333 return FALSE;
1334 }
1335
1336 //
1337 // Get the module list
1338 //
1339 Status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, *Modules, SysModuleInfoBufferSize, NULL);
1340
1341 if (!NT_SUCCESS(Status))
1342 {
1343 ShowMessages("err, unable to query module list (%x)\n", Status);
1344 free(*Modules);
1345
1346 return FALSE;
1347 }
1348
1349 return TRUE;
1350}
@ SystemModuleInformation
Definition SyscallFootprints.h:27
enum _SYSTEM_INFORMATION_CLASS SYSTEM_INFORMATION_CLASS
System information class.
#define STATUS_UNSUCCESSFUL
Definition Windows.h:172
BOOLEAN WindowsSetDebugPrivilege()
Adjust kernel debug privilege.
Definition windows-privilege.c:25

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

◆ SymbolCreateDisassemblerMapCallback()

VOID SymbolCreateDisassemblerMapCallback ( UINT64 Address,
CHAR * ModuleName,
CHAR * ObjectName,
UINT32 ObjectSize )

Callback for creating symbol map for disassembler.

Parameters
Address
ModuleName
ObjectName
ObjectSize
Returns
VOID
92{
93 //
94 // It has a string, should not be initialized with zero
95 //
96 LOCAL_FUNCTION_DESCRIPTION LocalFunctionDescription = {};
97 string FinalModuleName = "";
98
99 if (ObjectSize == 0)
100 {
102 }
103
104 //
105 // Convert module name to string
106 //
107 if (ModuleName != NULL)
108 {
109 FinalModuleName += std::string(ModuleName) + "!";
110 }
111
112 //
113 // Convert object name to string
114 //
115 if (ObjectName != NULL)
116 {
117 FinalModuleName += std::string(ObjectName);
118 }
119
120 //
121 // Create the structure
122 //
123 LocalFunctionDescription.ObjectName = std::move(FinalModuleName);
124 LocalFunctionDescription.ObjectSize = ObjectSize;
125
126 //
127 // Add to disassembler map
128 //
129 g_DisassemblerSymbolMap[Address] = LocalFunctionDescription;
130}
#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:721
std::map< UINT64, LOCAL_FUNCTION_DESCRIPTION > g_DisassemblerSymbolMap
Symbol table for disassembler.
Definition globals.h:522
UINT32 ObjectSize
Definition symbol.h:25
std::string ObjectName
Definition symbol.h:24
struct _LOCAL_FUNCTION_DESCRIPTION LOCAL_FUNCTION_DESCRIPTION
Save the local function symbols' description.

◆ SymbolCreateDisassemblerSymbolMap()

BOOLEAN SymbolCreateDisassemblerSymbolMap ( )

Update (or create) symbol map for the disassembler.

Returns
BOOLEAN
139{
140 //
141 // Clear the map table
142 //
144
145 //
146 // Get all the symbols in the callback
147 //
149
150 return TRUE;
151}
BOOLEAN ScriptEngineCreateSymbolTableForDisassemblerWrapper(PVOID CallbackFunction)
ScriptEngineCreateSymbolTableForDisassembler wrapper.
Definition script-engine-wrapper.cpp:160
VOID SymbolCreateDisassemblerMapCallback(UINT64 Address, CHAR *ModuleName, CHAR *ObjectName, UINT32 ObjectSize)
Callback for creating symbol map for disassembler.
Definition symbol.cpp:88

◆ SymbolDeleteSymTable()

BOOLEAN SymbolDeleteSymTable ( )

Delete and free structures and variables related to the symbols.

Returns
BOOLEAN shows whether the operation was successful or not
718{
719 //
720 // Unload all symbols
721 //
723
724 //
725 // Delete symbols
726 //
727 if (g_SymbolTable != NULL)
728 {
729 free(g_SymbolTable);
730
734 return TRUE;
735 }
736 else
737 {
738 return FALSE;
739 }
740}
UINT32 ScriptEngineUnloadAllSymbolsWrapper()
ScriptEngineUnloadAllSymbols wrapper.
Definition script-engine-wrapper.cpp:92

◆ SymbolInitialReload()

VOID SymbolInitialReload ( )

Initial load of symbols (for previously download symbols).

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

◆ 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
299{
300 string SymbolServer;
301 BOOLEAN Result = FALSE;
302
303 //
304 // *** Read symbol path/server from config file ***
305 //
306
307 if (!CommandSettingsGetValueFromConfigFile("SymbolServer", SymbolServer))
308 {
309 ShowMessages("please configure the symbol path (use '.help .sympath' for more information)\n");
310 return FALSE;
311 }
312
313 //
314 // Check if symbol table is empty
315 //
316 if (g_SymbolTable == NULL || g_SymbolTableSize == NULL)
317 {
318 ShowMessages("symbol table is empty, please use '.sym reload' to build a symbol table\n");
319 return FALSE;
320 }
321
322 //
323 // *** Load or download available symbols ***
324 //
325
326 //
327 // Indicate that we're in loading routines
328 //
332 IsDownload,
333 SymbolServer.c_str(),
334 SilentLoad);
335
336 //
337 // Build symbol table for disassembler
338 //
340
341 //
342 // Not in loading routines anymore
343 //
345
346 return Result;
347}
BOOLEAN g_IsExecutingSymbolLoadingRoutines
Executing symbol reloading or downloading routines.
Definition globals.h:516
BOOLEAN ScriptEngineSymbolInitLoadWrapper(PMODULE_SYMBOL_DETAIL BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const CHAR *SymbolPath, BOOLEAN IsSilentLoad)
ScriptEngineSymbolInitLoad wrapper.
Definition script-engine-wrapper.cpp:192
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:138

◆ SymbolLocalReload()

BOOLEAN SymbolLocalReload ( UINT32 UserProcessId)

Locally reload the symbol table.

Parameters
UserProcessId
Returns
BOOLEAN
50{
51 ShowMessages("interpreting symbols and creating symbol maps\n");
52
54
55 //
56 // And also load the symbols
57 //
59}
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:756

◆ 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
70{
71 //
72 // Load already downloaded symbol (won't download at this point)
73 //
75}

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

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_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.