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

symbol parser More...

#include "pch.h"

Functions

void SymSetTextMessageCallback (PVOID Handler)
 Set the function callback that will be called if any message needs to be shown.
 
VOID ShowMessages (const char *Fmt,...)
 Show messages.
 
PSYMBOL_LOADED_MODULE_DETAILS SymGetModuleBaseFromSearchMask (const char *SearchMask, BOOLEAN SetModuleNameGlobally)
 Interpret and find module base, based on module name.
 
BOOLEAN SymGetFieldOffsetFromModule (UINT64 Base, WCHAR *TypeName, WCHAR *FieldName, UINT32 *FieldOffset)
 Get the offset of a field from the top of a structure.
 
BOOLEAN SymGetDataTypeSizeFromModule (UINT64 Base, WCHAR *TypeName, UINT64 *TypeSize)
 Get the size of a data type (structure)
 
BOOLEAN SymInit ()
 initialize the DbgHelp symbols
 
BOOLEAN SymCheckAndRemoveWow64Prefix (const char *ModuleAddress, const char *PdbFileName, std::string &CustomModuleName)
 Remove wow64 extension to the module names.
 
BOOLEAN SymCheckNtoskrnlPrefix (const char *PdbFileName, std::string &CustomModuleName)
 Check for alternative name of ntoskrn;.
 
UINT32 SymLoadFileSymbol (UINT64 BaseAddress, const char *PdbFileName, const char *CustomModuleName)
 load symbol based on a file name and GUID
 
UINT32 SymUnloadModuleSymbol (char *ModuleName)
 Unload one module symbol.
 
UINT32 SymUnloadAllSymbols ()
 Unload all the symbols.
 
UINT64 SymConvertNameToAddress (const char *FunctionOrVariableName, PBOOLEAN WasFound)
 Convert function name to address.
 
BOOLEAN SymGetFieldOffset (CHAR *TypeName, CHAR *FieldName, UINT32 *FieldOffset)
 Search and show symbols.
 
BOOLEAN SymGetDataTypeSize (CHAR *TypeName, UINT64 *TypeSize)
 Get the size of structures from the symbols.
 
UINT32 SymSearchSymbolForMask (const char *SearchMask)
 Gets the offset from the symbol.
 
BOOLEAN SymCreateSymbolTableForDisassembler (void *CallbackFunction)
 Create symbol table for disassembler.
 
string SymSeparateTo64BitValue (UINT64 Value)
 add ` between 64 bit values and convert them to string
 
BOOL SymGetFileParams (const char *FileName, DWORD &FileSize)
 Get symbol file parameters.
 
BOOL SymGetFileSize (const char *FileName, DWORD &FileSize)
 Get symbol file size.
 
VOID SymShowSymbolInfo (UINT64 ModuleBase)
 Show symbol info.
 
BOOL CALLBACK SymDisplayMaskSymbolsCallback (SYMBOL_INFO *SymInfo, ULONG SymbolSize, PVOID UserContext)
 Callback for showing and enumerating symbols.
 
BOOL CALLBACK SymDeliverDisassemblerSymbolMapCallback (SYMBOL_INFO *SymInfo, ULONG SymbolSize, PVOID UserContext)
 Callback for delivering module!ObjectName to disassembler symbol map.
 
VOID SymShowSymbolDetails (SYMBOL_INFO &SymInfo)
 Show symbols details.
 
const char * SymTagStr (ULONG Tag)
 Interpret different tags for pdbs.
 
BOOLEAN SymConvertFileToPdbPath (const char *LocalFilePath, char *ResultPath)
 Convert a DLL to a Microsoft Symbol path.
 
VOID SymConvertWow64CompatibilityPaths (const char *LocalFilePath, std::string &Wow64ConvertedPath)
 Convert redirection of 32-bit compatibility path.
 
BOOLEAN SymConvertFileToPdbFileAndGuidAndAgeDetails (const char *LocalFilePath, char *PdbFilePath, char *GuidAndAgeDetails, BOOLEAN Is32BitModule)
 Convert a DLL to a Microsoft Symbol details like pdb file path and GUID.
 
BOOLEAN SymbolInitLoad (PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char *SymbolPath, BOOLEAN IsSilentLoad)
 check if the pdb files of loaded symbols are available or not
 
BOOLEAN SymbolPdbDownload (std::string SymName, const std::string &GUID, const std::string &SymPath, BOOLEAN IsSilentLoad)
 download pdb file
 
VOID SymbolAbortLoading ()
 In the case of pressing CTRL+C, it sets a flag to abort the execution of the 'reload'ing and the 'download'ing.
 
BOOLEAN SymShowDataBasedOnSymbolTypes (const char *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const char *AdditionalParameters)
 Perform task for showing structures and data.
 

Variables

std::vector< PSYMBOL_LOADED_MODULE_DETAILSg_LoadedModules
 
BOOLEAN g_IsLoadedModulesInitialized = FALSE
 
BOOLEAN g_AbortLoadingExecution = FALSE
 
CHARg_CurrentModuleName = NULL
 
PVOID g_MessageHandler = NULL
 The handler for ShowMessages function this is because the user might choose not to use printf and instead use his/her handler for showing messages.
 
SymbolMapCallback g_SymbolMapForDisassembler = NULL
 

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-29

Function Documentation

◆ ShowMessages()

VOID ShowMessages ( const char * Fmt,
... )

Show messages.

Parameters
Fmtformat string message
49{
50 va_list ArgList;
51 va_list Args;
52
53 if (g_MessageHandler == NULL)
54 {
55 va_start(Args, Fmt);
56 vprintf(Fmt, Args);
57 va_end(Args);
58 }
59 else
60 {
62 va_start(ArgList, Fmt);
63 int sprintfresult = vsprintf_s(TempMessage, Fmt, ArgList);
64 va_end(ArgList);
65
66 if (sprintfresult != -1)
67 {
68 //
69 // There is another handler
70 //
72 }
73 }
74}
#define TCP_END_OF_BUFFER_CHARS_COUNT
count of characters for tcp end of buffer
Definition Constants.h:440
#define COMMUNICATION_BUFFER_SIZE
Packet size for TCP connections.
Definition Constants.h:330
int(* SendMessageWithParamCallback)(const char *Text)
Callback type that can be used to be used as a custom ShowMessages function (by passing message as a ...
Definition DataTypes.h:122
PVOID g_MessageHandler
The handler for ShowMessages function this is because the user might choose not to use printf and ins...
Definition symbol-parser.cpp:22

◆ SymbolAbortLoading()

VOID SymbolAbortLoading ( )

In the case of pressing CTRL+C, it sets a flag to abort the execution of the 'reload'ing and the 'download'ing.

return VOID

2120{
2122 {
2124 ShowMessages("\naborting, please wait...\n");
2125 }
2126}
#define TRUE
Definition BasicTypes.h:55
VOID ShowMessages(const char *Fmt,...)
Show messages.
Definition symbol-parser.cpp:48
BOOLEAN g_AbortLoadingExecution
Definition symbol-parser.cpp:20

◆ SymbolInitLoad()

BOOLEAN SymbolInitLoad ( PVOID BufferToStoreDetails,
UINT32 StoredLength,
BOOLEAN DownloadIfAvailable,
const char * SymbolPath,
BOOLEAN IsSilentLoad )

check if the pdb files of loaded symbols are available or not

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
DownloadIfAvailableDownload the file if its available online
SymbolPathThe path of symbols
IsSilentLoad
Returns
BOOLEAN
1856{
1857 string Tmp, SymDir, CustomModuleNameStr;
1858 const char * CustomModuleName = NULL;
1859 string SymPath(SymbolPath);
1860 PMODULE_SYMBOL_DETAIL BufferToStoreDetailsConverted = (PMODULE_SYMBOL_DETAIL)BufferToStoreDetails;
1861
1862 vector<string> SplitedSymPath = Split(SymPath, '*');
1863 if (SplitedSymPath.size() < 2)
1864 return FALSE;
1865 if (SplitedSymPath[1].find(":\\") == string::npos)
1866 return FALSE;
1867
1868 Tmp = SymDir = SplitedSymPath[1];
1869
1870 //
1871 // Split each module and details
1872 //
1873 for (size_t i = 0; i < StoredLength / sizeof(MODULE_SYMBOL_DETAIL); i++)
1874 {
1875 //
1876 // Check for abort
1877 //
1879 {
1881 return FALSE;
1882 }
1883
1884 //
1885 // Check if symbol pdb detail is available in the module
1886 //
1887 if (!BufferToStoreDetailsConverted[i].IsSymbolDetailsFound)
1888 {
1889 //
1890 // Ignore the module
1891 //
1892 continue;
1893 }
1894
1895 //
1896 // Check if it's a local path (a path) or a microsoft symbol
1897 //
1898 if (BufferToStoreDetailsConverted[i].IsLocalSymbolPath)
1899 {
1900 //
1901 // If this is a local driver, then load the pdb
1902 //
1903 if (IsFileExists(BufferToStoreDetailsConverted[i].ModuleSymbolPath))
1904 {
1905 BufferToStoreDetailsConverted[i].IsSymbolPDBAvaliable = TRUE;
1906
1907 //
1908 // Load symbol locally
1909 //
1910 if (!IsSilentLoad)
1911 {
1912 ShowMessages("loading symbol '%s'...", Tmp.c_str());
1913 }
1914
1915 //
1916 // Check if we need an alternative module name (in 32-bit modules)
1917 //
1919
1920 // ShowMessages("name: %s , is 32-bit? %s\n", BufferToStoreDetailsConverted[i].FilePath, BufferToStoreDetailsConverted[i].Is32Bit ? "true" : "false");
1921
1922 //
1923 // Check for alternative module names
1924 //
1925 if (BufferToStoreDetailsConverted[i].Is32Bit &&
1926 SymCheckAndRemoveWow64Prefix(BufferToStoreDetailsConverted[i].FilePath,
1927 BufferToStoreDetailsConverted[i].ModuleSymbolPath,
1928 CustomModuleNameStr))
1929 {
1930 //
1931 // The name of the module contains a prefix which should be removed
1932 //
1933 CustomModuleName = CustomModuleNameStr.c_str();
1934 }
1935 else if (!BufferToStoreDetailsConverted[i].Is32Bit &&
1936 SymCheckNtoskrnlPrefix(BufferToStoreDetailsConverted[i].ModuleSymbolPath, CustomModuleNameStr))
1937 {
1938 //
1939 // This is an nt module
1940 //
1941 CustomModuleName = CustomModuleNameStr.c_str();
1942 }
1943
1944 if (SymLoadFileSymbol(BufferToStoreDetailsConverted[i].BaseAddress,
1945 BufferToStoreDetailsConverted[i].ModuleSymbolPath,
1946 CustomModuleName) == 0)
1947 {
1948 if (!IsSilentLoad)
1949 {
1950 ShowMessages("\tloaded\n");
1951 }
1952 }
1953 else
1954 {
1955 if (!IsSilentLoad)
1956 {
1957 ShowMessages("\tnot loaded (already loaded?)\n");
1958 }
1959 }
1960 }
1961 }
1962 else
1963 {
1964 //
1965 // It might be a Windows symbol
1966 //
1967 Tmp = SymDir +
1968 "\\" +
1969 BufferToStoreDetailsConverted[i].ModuleSymbolPath +
1970 "\\" +
1971 BufferToStoreDetailsConverted[i].ModuleSymbolGuidAndAge +
1972 "\\" +
1973 BufferToStoreDetailsConverted[i].ModuleSymbolPath;
1974
1975 //
1976 // Download the symbols file if not available
1977 //
1978 if (DownloadIfAvailable && IsFileExists(Tmp) == FALSE)
1979 {
1980 //
1981 // Download the symbol
1982 //
1983 SymbolPdbDownload(BufferToStoreDetailsConverted[i].ModuleSymbolPath,
1984 BufferToStoreDetailsConverted[i].ModuleSymbolGuidAndAge,
1985 SymPath,
1986 IsSilentLoad);
1987 }
1988
1989 //
1990 // Check again to see if the symbol already download or not
1991 //
1992 if (IsFileExists(Tmp))
1993 {
1994 BufferToStoreDetailsConverted[i].IsSymbolPDBAvaliable = TRUE;
1995
1996 if (!IsSilentLoad)
1997 {
1998 ShowMessages("loading symbol '%s'...", Tmp.c_str());
1999 }
2000
2001 //
2002 // Check if we need an alternative module name (in 32-bit modules)
2003 //
2005
2006 // ShowMessages("name: %s , is 32-bit? %s\n", BufferToStoreDetailsConverted[i].FilePath, BufferToStoreDetailsConverted[i].Is32Bit ? "true" : "false");
2007
2008 //
2009 // Check for alternative module names
2010 //
2011 if (BufferToStoreDetailsConverted[i].Is32Bit &&
2012 SymCheckAndRemoveWow64Prefix(BufferToStoreDetailsConverted[i].FilePath,
2013 Tmp.c_str(),
2014 CustomModuleNameStr))
2015 {
2016 //
2017 // The name of the module contains a prefix which should be removed
2018 //
2019 CustomModuleName = CustomModuleNameStr.c_str();
2020 }
2021 else if (!BufferToStoreDetailsConverted[i].Is32Bit &&
2022 SymCheckNtoskrnlPrefix(Tmp.c_str(), CustomModuleNameStr))
2023 {
2024 //
2025 // This is an nt module
2026 //
2027 CustomModuleName = CustomModuleNameStr.c_str();
2028 }
2029
2030 if (SymLoadFileSymbol(BufferToStoreDetailsConverted[i].BaseAddress, Tmp.c_str(), CustomModuleName) == 0)
2031 {
2032 if (!IsSilentLoad)
2033 {
2034 ShowMessages("\tloaded\n");
2035 }
2036 }
2037 else
2038 {
2039 if (!IsSilentLoad)
2040 {
2041 ShowMessages("\tnot loaded (already loaded?)\n");
2042 }
2043 }
2044 }
2045 }
2046 }
2047
2048 return TRUE;
2049}
#define FALSE
Definition BasicTypes.h:54
UINT32 BOOLEAN const char * SymbolPath
Definition HyperDbgScriptImports.h:65
UINT32 BOOLEAN const char BOOLEAN IsSilentLoad
Definition HyperDbgScriptImports.h:65
UINT32 StoredLength
Definition HyperDbgScriptImports.h:65
const char const char * CustomModuleName
Definition HyperDbgScriptImports.h:47
UINT32 BOOLEAN DownloadIfAvailable
Definition HyperDbgScriptImports.h:65
struct _MODULE_SYMBOL_DETAIL MODULE_SYMBOL_DETAIL
structures for sending and saving details about each module and symbols details
struct _MODULE_SYMBOL_DETAIL * PMODULE_SYMBOL_DETAIL
BOOLEAN IsFileExists(const std::string &FileName)
check if a file exist or not
Definition common-utils.cpp:22
const vector< string > Split(const string &s, const char &c)
general split command
Definition common.cpp:117
NULL()
Definition test-case-generator.py:530
structures for sending and saving details about each module and symbols details
Definition Symbols.h:24
char ModuleSymbolGuidAndAge[MAXIMUM_GUID_AND_AGE_SIZE]
Definition Symbols.h:34
char ModuleSymbolPath[MAX_PATH]
Definition Symbols.h:33
BOOLEAN IsSymbolPDBAvaliable
Definition Symbols.h:28
BOOLEAN SymCheckNtoskrnlPrefix(const char *PdbFileName, std::string &CustomModuleName)
Check for alternative name of ntoskrn;.
Definition symbol-parser.cpp:486
BOOLEAN SymCheckAndRemoveWow64Prefix(const char *ModuleAddress, const char *PdbFileName, std::string &CustomModuleName)
Remove wow64 extension to the module names.
Definition symbol-parser.cpp:427
BOOLEAN SymbolPdbDownload(std::string SymName, const std::string &GUID, const std::string &SymPath, BOOLEAN IsSilentLoad)
download pdb file
Definition symbol-parser.cpp:2063
UINT32 SymLoadFileSymbol(UINT64 BaseAddress, const char *PdbFileName, const char *CustomModuleName)
load symbol based on a file name and GUID
Definition symbol-parser.cpp:532

◆ SymbolPdbDownload()

BOOLEAN SymbolPdbDownload ( std::string SymName,
const std::string & GUID,
const std::string & SymPath,
BOOLEAN IsSilentLoad )

download pdb file

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
SymPathThe path of symbols
IsSilentLoadDownload without any message

return BOOLEAN

2064{
2065 vector<string> SplitedSymPath = Split(SymPath, '*');
2066 if (SplitedSymPath.size() < 2)
2067 return FALSE;
2068 if (SplitedSymPath[1].find(":\\") == string::npos)
2069 return FALSE;
2070 if (SplitedSymPath[2].find("http:") == string::npos && SplitedSymPath[2].find("https:") == string::npos)
2071 return FALSE;
2072
2073 string SymDir = SplitedSymPath[1];
2074 string SymDownloadServer = SplitedSymPath[2];
2075 string DownloadURL = SymDownloadServer + "/" + SymName + "/" + GUID + "/" + SymName;
2076 string SymFullDir = SymDir + "\\" + SymName + "\\" + GUID + "\\";
2077 if (!CreateDirectoryRecursive(SymFullDir))
2078 {
2079 if (!IsSilentLoad)
2080 {
2081 ShowMessages("err, unable to create sympath directory '%s'\n", SymFullDir.c_str());
2082 }
2083 return FALSE;
2084 }
2085
2086 if (!IsSilentLoad)
2087 {
2088 ShowMessages("downloading symbol '%s'...", SymName.c_str());
2089 }
2090
2091 HRESULT Result = URLDownloadToFileA(NULL, DownloadURL.c_str(), (SymFullDir + "\\" + SymName).c_str(), 0, NULL);
2092
2093 if (Result == S_OK)
2094 {
2095 if (!IsSilentLoad)
2096 {
2097 ShowMessages("\tdownloaded\n");
2098 }
2099 return TRUE;
2100 }
2101 else
2102 {
2103 if (!IsSilentLoad)
2104 {
2105 ShowMessages("\tcould not be downloaded (%x) \n", Result);
2106 }
2107 }
2108
2109 return FALSE;
2110}
BOOLEAN CreateDirectoryRecursive(const std::string &Path)
create a directory recursively
Definition common-utils.cpp:54

◆ SymCheckAndRemoveWow64Prefix()

BOOLEAN SymCheckAndRemoveWow64Prefix ( const char * ModuleAddress,
const char * PdbFileName,
std::string & CustomModuleName )

Remove wow64 extension to the module names.

Parameters
ModuleAddress
PdbFileName
Returns
BOOLEAN
428{
429 char ModuleName[_MAX_FNAME] = {0};
430 char PdbModuleName[_MAX_FNAME] = {0};
431
432 //
433 // Determine the name of the file
434 //
435 _splitpath(ModuleAddress, NULL, NULL, ModuleName, NULL);
436 _splitpath(PdbFileName, NULL, NULL, PdbModuleName, NULL);
437
438 //
439 // Convert ModuleName to lowercase
440 //
441 std::transform(ModuleName, ModuleName + strlen(ModuleName), ModuleName, [](unsigned char c) { return std::tolower(c); });
442
443 //
444 // Convert PdbModuleName to lowercase
445 //
446 std::transform(PdbModuleName, PdbModuleName + strlen(PdbModuleName), PdbModuleName, [](unsigned char c) { return std::tolower(c); });
447
448 //
449 // Compare the lowercase strings
450 //
451 if (std::strcmp(ModuleName, PdbModuleName) == 0)
452 {
453 return FALSE;
454 }
455 else
456 {
457 // Convert ModuleAddress to lowercase
458 std::string LowerModuleAddress(ModuleAddress);
459 std::transform(LowerModuleAddress.begin(), LowerModuleAddress.end(), LowerModuleAddress.begin(), [](unsigned char c) { return std::tolower(c); });
460
461 if (PdbModuleName[0] == 'w' && LowerModuleAddress.find(":\\windows\\system32") != std::string::npos)
462 {
463 //
464 // Set CustomModuleName to lowercase ModuleName
465 //
466 CustomModuleName = std::string(ModuleName);
467
468 return TRUE;
469 }
470 else
471 {
472 return FALSE;
473 }
474 }
475}
const char * PdbFileName
Definition HyperDbgScriptImports.h:47

◆ SymCheckNtoskrnlPrefix()

BOOLEAN SymCheckNtoskrnlPrefix ( const char * PdbFileName,
std::string & CustomModuleName )

Check for alternative name of ntoskrn;.

Parameters
PdbFileName
CustomModuleName
Returns
BOOLEAN
487{
488 char PdbModuleName[_MAX_FNAME] = {0};
489
490 //
491 // Determine the name of the file
492 //
493 _splitpath(PdbFileName, NULL, NULL, PdbModuleName, NULL);
494
495 //
496 // Convert PdbModuleName to lowercase
497 //
498 std::transform(PdbModuleName, PdbModuleName + strlen(PdbModuleName), PdbModuleName, [](unsigned char c) { return std::tolower(c); });
499
500 //
501 // Is it "nt" module or not
502 //
503 // Names of kernel
504 // NTOSKRNL.EXE : 1 CPU
505 // NTKRNLMP.EXE : N CPU, SMP
506 // NTKRNLPA.EXE : 1 CPU, PAE
507 // NTKRPAMP.EXE : N CPU SMP, PAE
508 //
509 if (strcmp(PdbModuleName, ("ntkrnlmp")) == 0 || strcmp(PdbModuleName, ("ntoskrnl")) == 0 ||
510 strcmp(PdbModuleName, ("ntkrpamp")) == 0 || strcmp(PdbModuleName, ("ntkrnlpa")) == 0)
511 {
512 CustomModuleName = "nt";
513 return TRUE;
514 }
515
516 //
517 // Not nt module
518 //
519 return FALSE;
520}

◆ SymConvertFileToPdbFileAndGuidAndAgeDetails()

BOOLEAN SymConvertFileToPdbFileAndGuidAndAgeDetails ( const char * LocalFilePath,
char * PdbFilePath,
char * GuidAndAgeDetails,
BOOLEAN Is32BitModule )

Convert a DLL to a Microsoft Symbol details like pdb file path and GUID.

Parameters
LocalFilePath
PdbFilePath
GuidAndAgeDetails
Is32BitModule
Returns
BOOLEAN
1779{
1780 SYMSRV_INDEX_INFO SymInfo = {0};
1781 std::string Wow64ConvertedPath;
1782 const char * FormatStrPdbFilePath = "%s";
1783 const char * ActualLocalFilePath = NULL;
1784 const char * FormatStrPdbFileGuidAndAgeDetails =
1785 "%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x%x";
1786 SymInfo.sizeofstruct = sizeof(SYMSRV_INDEX_INFO);
1787
1788 if (Is32BitModule)
1789 {
1790 SymConvertWow64CompatibilityPaths(LocalFilePath, Wow64ConvertedPath);
1791 ActualLocalFilePath = Wow64ConvertedPath.c_str();
1792 // ShowMessages("local file path: %s | final file path: %s\n", LocalFilePath, ActualLocalFilePath);
1793 }
1794 else
1795 {
1796 ActualLocalFilePath = LocalFilePath;
1797 }
1798
1799 // ShowMessages("the final (actual) address is: %s\n", ActualLocalFilePath);
1800
1801 BOOL Ret = SymSrvGetFileIndexInfo(ActualLocalFilePath, &SymInfo, 0);
1802
1803 if (Ret)
1804 {
1805 wsprintfA(PdbFilePath, FormatStrPdbFilePath, SymInfo.pdbfile);
1806
1807 wsprintfA(GuidAndAgeDetails,
1808 FormatStrPdbFileGuidAndAgeDetails,
1809 SymInfo.guid.Data1,
1810 SymInfo.guid.Data2,
1811 SymInfo.guid.Data3,
1812 SymInfo.guid.Data4[0],
1813 SymInfo.guid.Data4[1],
1814 SymInfo.guid.Data4[2],
1815 SymInfo.guid.Data4[3],
1816 SymInfo.guid.Data4[4],
1817 SymInfo.guid.Data4[5],
1818 SymInfo.guid.Data4[6],
1819 SymInfo.guid.Data4[7],
1820 SymInfo.age);
1821
1822 return TRUE;
1823 }
1824 else
1825 {
1826 //
1827 // ShowMessages("err, unable to get symbol information for %s (%x)\n", ActualLocalFilePath, GetLastError());
1828 //
1829 return FALSE;
1830 }
1831
1832 //
1833 // By default, return false
1834 //
1835 return FALSE;
1836}
int BOOL
Definition BasicTypes.h:23
char * PdbFilePath
Definition HyperDbgScriptImports.h:63
char char BOOLEAN Is32BitModule
Definition HyperDbgScriptImports.h:63
char char * GuidAndAgeDetails
Definition HyperDbgScriptImports.h:63
VOID SymConvertWow64CompatibilityPaths(const char *LocalFilePath, std::string &Wow64ConvertedPath)
Convert redirection of 32-bit compatibility path.
Definition symbol-parser.cpp:1739

◆ SymConvertFileToPdbPath()

BOOLEAN SymConvertFileToPdbPath ( const char * LocalFilePath,
char * ResultPath )

Convert a DLL to a Microsoft Symbol path.

Parameters
LocalFilePath
ResultPath
Returns
BOOLEAN
1688{
1689 SYMSRV_INDEX_INFO SymInfo = {0};
1690 const char * FormatStr =
1691 "%s/%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x%x/%s";
1692 SymInfo.sizeofstruct = sizeof(SYMSRV_INDEX_INFO);
1693
1694 BOOL Ret = SymSrvGetFileIndexInfo(LocalFilePath, &SymInfo, 0);
1695
1696 if (Ret)
1697 {
1698 wsprintfA(ResultPath,
1699 FormatStr,
1700 SymInfo.pdbfile,
1701 SymInfo.guid.Data1,
1702 SymInfo.guid.Data2,
1703 SymInfo.guid.Data3,
1704 SymInfo.guid.Data4[0],
1705 SymInfo.guid.Data4[1],
1706 SymInfo.guid.Data4[2],
1707 SymInfo.guid.Data4[3],
1708 SymInfo.guid.Data4[4],
1709 SymInfo.guid.Data4[5],
1710 SymInfo.guid.Data4[6],
1711 SymInfo.guid.Data4[7],
1712 SymInfo.age,
1713 SymInfo.pdbfile);
1714
1715 return TRUE;
1716 }
1717 else
1718 {
1719 //
1720 // ShowMessages("err, unable to get symbol information for %s (%x)\n", LocalFilePath, GetLastError());
1721 //
1722 return FALSE;
1723 }
1724
1725 //
1726 // By default, return false
1727 //
1728 return FALSE;
1729}
char * ResultPath
Definition HyperDbgScriptImports.h:61

◆ SymConvertNameToAddress()

UINT64 SymConvertNameToAddress ( const char * FunctionOrVariableName,
PBOOLEAN WasFound )

Convert function name to address.

Parameters
FunctionName
WasFound
Returns
UINT64
805{
806 BOOLEAN Found = FALSE;
808 UINT64 Buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR) + sizeof(UINT64) - 1) / sizeof(UINT64)];
809 PSYMBOL_INFO Symbol = (PSYMBOL_INFO)Buffer;
810 string FinalModuleName;
811 string TempName(FunctionOrVariableName);
812 string ExtractedModuleName;
813 string FunctionName;
814
815 //
816 // Not found by default
817 //
818 *WasFound = FALSE;
819
820 //
821 // Retrieve the address from name
822 //
823 Symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
824 Symbol->MaxNameLen = MAX_SYM_NAME;
825
826 //
827 // *** Check if the module has an alternative name, then replace the
828 // original name with alternative name ***
829 //
830
831 //
832 // Check if '!' is present in the function or variable name
833 //
834 size_t FoundIndex = TempName.find('!');
835 if (FoundIndex != std::string::npos)
836 {
837 ExtractedModuleName = TempName.substr(0, FoundIndex);
838 FunctionName = TempName.substr(FoundIndex + 1);
839
840 //
841 // Convert module name to lower-case
842 //
843 std::transform(ExtractedModuleName.begin(), ExtractedModuleName.end(), ExtractedModuleName.begin(), [](unsigned char c) {
844 return std::tolower(c);
845 });
846
847 //
848 // Check if the we find it with an alternative module name or not
849 //
850 for (auto item : g_LoadedModules)
851 {
852 //
853 // Check for the module name
854 //
855 if (strcmp((const char *)item->ModuleName, ExtractedModuleName.c_str()) == 0)
856 {
857 string ModuleName(item->ModuleName);
858 FinalModuleName = ModuleName + "!" + FunctionName;
859 break;
860 }
861
862 //
863 // Check for the alternative module name
864 //
865 if (strcmp((const char *)item->ModuleAlternativeName, ExtractedModuleName.c_str()) == 0)
866 {
867 //
868 // Replace the alternative module name with original module name
869 //
870 string ModuleName(item->ModuleName);
871 FinalModuleName = ModuleName + "!" + FunctionName;
872 break;
873 }
874 }
875 }
876 else
877 {
878 //
879 // It doesn't contain a module name, so we'll use 'nt' by default
880 //
881 for (auto item : g_LoadedModules)
882 {
883 //
884 // Check for the module name
885 //
886 if (strcmp((const char *)item->ModuleAlternativeName, "nt") == 0)
887 {
888 //
889 // Replace the alternative module name with original module name
890 //
891 string ModuleName(item->ModuleName);
892 FinalModuleName = ModuleName + "!" + TempName;
893 break;
894 }
895 }
896 }
897
898 //
899 // Check if the final module name is not empty
900 //
901 if (FinalModuleName.empty())
902 {
903 *WasFound = FALSE;
904 return NULL;
905 }
906
907 if (SymFromName(GetCurrentProcess(), FinalModuleName.c_str(), Symbol))
908 {
909 //
910 // SymFromName returned success
911 //
912 Found = TRUE;
913 Address = Symbol->Address;
914 }
915 else
916 {
917 //
918 // SymFromName failed
919 //
920 Found = FALSE;
921
922 //
923 // ShowMessages("symbol not found (%x)\n", GetLastError());
924 //
925 }
926
927 *WasFound = Found;
928 return Address;
929}
UCHAR BOOLEAN
Definition BasicTypes.h:39
unsigned __int64 UINT64
Definition BasicTypes.h:21
char CHAR
Definition BasicTypes.h:31
UINT64 Address
Definition HyperDbgScriptImports.h:67
PBOOLEAN WasFound
Definition HyperDbgScriptImports.h:45
std::vector< PSYMBOL_LOADED_MODULE_DETAILS > g_LoadedModules
Definition symbol-parser.cpp:18

◆ SymConvertWow64CompatibilityPaths()

VOID SymConvertWow64CompatibilityPaths ( const char * LocalFilePath,
std::string & Wow64ConvertedPath )

Convert redirection of 32-bit compatibility path.

Parameters
LocalFilePath
Returns
VOID
1740{
1741 std::string FilePath(LocalFilePath);
1742
1743 // Convert the path to lowercase
1744 std::transform(FilePath.begin(), FilePath.end(), FilePath.begin(), ::tolower);
1745
1746 // Replace "\windows\system32" with "\windows\syswow64"
1747 size_t pos = FilePath.find(":\\windows\\system32");
1748 if (pos != std::string::npos)
1749 {
1750 FilePath.replace(pos, 18, ":\\windows\\syswow64");
1751 }
1752
1753 // Replace "\program files" with "\program files (x86)"
1754 pos = FilePath.find(":\\program files");
1755 if (pos != std::string::npos)
1756 {
1757 FilePath.replace(pos, 15, ":\\program files (x86)");
1758 }
1759
1760 //
1761 // Copy path to destination
1762 //
1763 Wow64ConvertedPath = FilePath;
1764}

◆ SymCreateSymbolTableForDisassembler()

BOOLEAN SymCreateSymbolTableForDisassembler ( void * CallbackFunction)

Create symbol table for disassembler.

mainly used by disassembler for 'u' command

Parameters
CallbackFunction
Returns
BOOLEAN
1148{
1149 BOOL Ret = FALSE;
1150 BOOLEAN Result = TRUE;
1151
1152 //
1153 // Set the callback function to deliver the name of module!ObjectName
1154 //
1156
1157 //
1158 // Create a symbol table from all modules
1159 //
1160 for (auto item : g_LoadedModules)
1161 {
1162 //
1163 // Set module name
1164 //
1165 g_CurrentModuleName = (char *)item->ModuleName;
1166
1167 //
1168 // Call the callback for the current module
1169 //
1170 Ret = SymEnumSymbols(
1171 GetCurrentProcess(), // Process handle of the current process
1172 item->BaseAddress, // Base address of the module
1173 NULL, // Mask (NULL -> all symbols)
1174 SymDeliverDisassemblerSymbolMapCallback, // The callback function
1175 NULL // A used-defined context can be passed here, if necessary
1176 );
1177
1178 if (!Ret)
1179 {
1180 //
1181 // A module did not added correctly
1182 //
1183 // ShowMessages("err, symbol enum failed (%x)\n", GetLastError());
1184 Result = FALSE;
1185 }
1186 }
1187
1188 return Result;
1189}
VOID(* SymbolMapCallback)(UINT64 Address, char *ModuleName, char *ObjectName, unsigned int ObjectSize)
Callback type that should be used to add list of Addresses to ObjectNames.
Definition Symbols.h:65
BOOL CALLBACK SymDeliverDisassemblerSymbolMapCallback(SYMBOL_INFO *SymInfo, ULONG SymbolSize, PVOID UserContext)
Callback for delivering module!ObjectName to disassembler symbol map.
Definition symbol-parser.cpp:1505
CHAR * g_CurrentModuleName
Definition symbol-parser.cpp:21
SymbolMapCallback g_SymbolMapForDisassembler
Definition symbol-parser.cpp:23

◆ SymDeliverDisassemblerSymbolMapCallback()

BOOL CALLBACK SymDeliverDisassemblerSymbolMapCallback ( SYMBOL_INFO * SymInfo,
ULONG SymbolSize,
PVOID UserContext )

Callback for delivering module!ObjectName to disassembler symbol map.

Parameters
SymInfo
SymbolSize
UserContext
Returns
BOOL
1506{
1507 if (SymInfo != 0 && g_SymbolMapForDisassembler != NULL)
1508 {
1509 //
1510 // Call the remote callback
1511 //
1512 g_SymbolMapForDisassembler(SymInfo->Address, g_CurrentModuleName, SymInfo->Name, SymInfo->Size);
1513 }
1514
1515 //
1516 // Continue enumeration
1517 //
1518 return TRUE;
1519}

◆ SymDisplayMaskSymbolsCallback()

BOOL CALLBACK SymDisplayMaskSymbolsCallback ( SYMBOL_INFO * SymInfo,
ULONG SymbolSize,
PVOID UserContext )

Callback for showing and enumerating symbols.

Parameters
SymInfo
SymbolSize
UserContext
Returns
BOOL
1483{
1484 if (SymInfo != 0)
1485 {
1486 SymShowSymbolDetails(*SymInfo);
1487 }
1488
1489 //
1490 // Continue enumeration
1491 //
1492 return TRUE;
1493}
VOID SymShowSymbolDetails(SYMBOL_INFO &SymInfo)
Show symbols details.
Definition symbol-parser.cpp:1529

◆ SymGetDataTypeSize()

BOOLEAN SymGetDataTypeSize ( CHAR * TypeName,
UINT64 * TypeSize )

Get the size of structures from the symbols.

Parameters
TypeName
FieldName
FieldOffset
Returns
BOOLEAN Whether the module is found successfully or not
1032{
1033 BOOL Ret = FALSE;
1034 UINT32 Index = 0;
1036 BOOLEAN Result = FALSE;
1037
1038 //
1039 // Find module info
1040 //
1041 SymbolInfo = SymGetModuleBaseFromSearchMask(TypeName, TRUE);
1042
1043 //
1044 // Check if module is found
1045 //
1046 if (SymbolInfo == NULL)
1047 {
1048 //
1049 // Module not found or there was an error
1050 //
1051 return FALSE;
1052 }
1053
1054 //
1055 // Remove the *!Name from TypeName as it not supports module name
1056 // at the beginning of a type name
1057 //
1058 while (TypeName[Index] != '\0')
1059 {
1060 if (TypeName[Index] == '!')
1061 {
1062 TypeName = (CHAR *)(TypeName + Index + 1);
1063 break;
1064 }
1065
1066 Index++;
1067 }
1068
1069 //
1070 // Convert FieldName to wide-char, it's because SymGetTypeInfo supports
1071 // wide-char
1072 //
1073 const size_t TypeNameSize = strlen(TypeName) + 1;
1074 WCHAR * TypeNameW = (WCHAR *)malloc(sizeof(wchar_t) * TypeNameSize);
1075
1076 if (TypeNameW == NULL)
1077 {
1078 printf("err, could not allocate buffer");
1079 return FALSE;
1080 }
1081
1082 RtlZeroMemory(TypeNameW, sizeof(wchar_t) * TypeNameSize);
1083 mbstowcs(TypeNameW, TypeName, TypeNameSize);
1084
1085 Result = SymGetDataTypeSizeFromModule(SymbolInfo->ModuleBase, TypeNameW, TypeSize);
1086
1087 free(TypeNameW);
1088
1089 return Result;
1090}
wchar_t WCHAR
Definition BasicTypes.h:32
unsigned int UINT32
Definition BasicTypes.h:48
UINT64 * TypeSize
Definition HyperDbgScriptImports.h:57
Hold detail about the loaded modules.
Definition symbol-parser.h:29
UINT64 ModuleBase
Definition symbol-parser.h:31
BOOLEAN SymGetDataTypeSizeFromModule(UINT64 Base, WCHAR *TypeName, UINT64 *TypeSize)
Get the size of a data type (structure)
Definition symbol-parser.cpp:331
PSYMBOL_LOADED_MODULE_DETAILS SymGetModuleBaseFromSearchMask(const char *SearchMask, BOOLEAN SetModuleNameGlobally)
Interpret and find module base, based on module name.
Definition symbol-parser.cpp:84

◆ SymGetDataTypeSizeFromModule()

BOOLEAN SymGetDataTypeSizeFromModule ( UINT64 Base,
WCHAR * TypeName,
UINT64 * TypeSize )

Get the size of a data type (structure)

Parameters
Base
TypeName
TypeSize
Returns
BOOLEAN Whether the module is found successfully or not
332{
333 //
334 // Allocate a buffer to back the SYMBOL_INFO structure
335 //
336 const DWORD SizeOfStruct =
337 sizeof(SYMBOL_INFOW) + ((MAX_SYM_NAME - 1) * sizeof(wchar_t));
338 uint8_t SymbolInfoBuffer[SizeOfStruct];
339 auto SymbolInfo = PSYMBOL_INFOW(SymbolInfoBuffer);
340
341 //
342 // Initialize the fields that need initialization
343 //
344 SymbolInfo->SizeOfStruct = sizeof(SYMBOL_INFOW);
345 SymbolInfo->MaxNameLen = MAX_SYM_NAME;
346
347 //
348 // Retrieve a type index for the type we're after
349 //
350 if (!SymGetTypeFromNameW(GetCurrentProcess(), Base, TypeName, SymbolInfo))
351 {
352 // ShowMessages("err, SymGetTypeFromName failed (%x)\n",
353 // GetLastError());
354 return FALSE;
355 }
356
357 if (!SymGetTypeInfo(GetCurrentProcess(), Base, SymbolInfo->TypeIndex, TI_GET_LENGTH, TypeSize))
358 {
359 // ShowMessages("err, SymGetTypeInfo failed (%x)\n",
360 // GetLastError());
361 return FALSE;
362 }
363
364 // ShowMessages("type size : %llx\n", TypeSize);
365
366 return TRUE;
367}
unsigned long DWORD
Definition BasicTypes.h:22

◆ SymGetFieldOffset()

BOOLEAN SymGetFieldOffset ( CHAR * TypeName,
CHAR * FieldName,
UINT32 * FieldOffset )

Search and show symbols.

mainly used by the 'x' command

Parameters
TypeName
FieldName
FieldOffset
Returns
BOOLEAN Whether the module is found successfully or not
943{
944 BOOL Ret = FALSE;
945 UINT32 Index = 0;
947 BOOLEAN Result = FALSE;
948
949 //
950 // Find module info
951 //
952 SymbolInfo = SymGetModuleBaseFromSearchMask(TypeName, TRUE);
953
954 //
955 // Check if module is found
956 //
957 if (SymbolInfo == NULL)
958 {
959 //
960 // Module not found or there was an error
961 //
962 return FALSE;
963 }
964
965 //
966 // Remove the *!Name from TypeName as it not supports module name
967 // at the beginning of a type name
968 //
969 while (TypeName[Index] != '\0')
970 {
971 if (TypeName[Index] == '!')
972 {
973 TypeName = (CHAR *)(TypeName + Index + 1);
974 break;
975 }
976
977 Index++;
978 }
979
980 //
981 // Convert TypeName to wide-char, it's because SymGetTypeInfo supports
982 // wide-char
983 //
984 const size_t TypeNameSize = strlen(TypeName) + 1;
985 WCHAR * TypeNameW = (WCHAR *)malloc(sizeof(wchar_t) * TypeNameSize);
986
987 if (TypeNameW == NULL)
988 {
989 printf("err, could not allocate buffer");
990 return FALSE;
991 }
992
993 RtlZeroMemory(TypeNameW, sizeof(wchar_t) * TypeNameSize);
994 mbstowcs(TypeNameW, TypeName, TypeNameSize);
995
996 //
997 // Convert FieldName to wide-char, it's because SymGetTypeInfo supports
998 // wide-char
999 //
1000 const size_t FieldNameSize = strlen(FieldName) + 1;
1001 WCHAR * FieldNameW = (WCHAR *)malloc(sizeof(wchar_t) * FieldNameSize);
1002
1003 if (FieldNameW == NULL)
1004 {
1005 printf("err, could not allocate buffer");
1006 free(TypeNameW);
1007 return FALSE;
1008 }
1009
1010 RtlZeroMemory(FieldNameW, sizeof(wchar_t) * FieldNameSize);
1011 mbstowcs(FieldNameW, FieldName, FieldNameSize);
1012
1013 Result = SymGetFieldOffsetFromModule(SymbolInfo->ModuleBase, TypeNameW, FieldNameW, FieldOffset);
1014
1015 free(TypeNameW);
1016 free(FieldNameW);
1017
1018 return Result;
1019}
CHAR * FieldName
Definition HyperDbgScriptImports.h:55
CHAR UINT32 * FieldOffset
Definition HyperDbgScriptImports.h:55
BOOLEAN SymGetFieldOffsetFromModule(UINT64 Base, WCHAR *TypeName, WCHAR *FieldName, UINT32 *FieldOffset)
Get the offset of a field from the top of a structure.
Definition symbol-parser.cpp:202

◆ SymGetFieldOffsetFromModule()

BOOLEAN SymGetFieldOffsetFromModule ( UINT64 Base,
WCHAR * TypeName,
WCHAR * FieldName,
UINT32 * FieldOffset )

Get the offset of a field from the top of a structure.

Parameters
Base
TypeName
FieldName
FieldOffset

This function is derived from: https://github.com/0vercl0k/sic/blob/master/src/sic/sym.cc

Returns
BOOLEAN Whether the module is found successfully or not
203{
204 BOOLEAN Found = FALSE;
205
206 //
207 // Allocate a buffer to back the SYMBOL_INFO structure
208 //
209 const DWORD SizeOfStruct =
210 sizeof(SYMBOL_INFOW) + ((MAX_SYM_NAME - 1) * sizeof(wchar_t));
211 uint8_t SymbolInfoBuffer[SizeOfStruct];
212 auto SymbolInfo = PSYMBOL_INFOW(SymbolInfoBuffer);
213
214 //
215 // Initialize the fields that need initialization
216 //
217 SymbolInfo->SizeOfStruct = sizeof(SYMBOL_INFOW);
218 SymbolInfo->MaxNameLen = MAX_SYM_NAME;
219
220 //
221 // Retrieve a type index for the type we're after
222 //
223 if (!SymGetTypeFromNameW(GetCurrentProcess(), Base, TypeName, SymbolInfo))
224 {
225 // ShowMessages("err, SymGetTypeFromName failed (%x)\n",
226 // GetLastError());
227 return FALSE;
228 }
229
230 //
231 // Now that we have a type, we need to enumerate its children to find the
232 // field we're after. First step is to get the number of children
233 //
234 const ULONG TypeIndex = SymbolInfo->TypeIndex;
235 DWORD ChildrenCount = 0;
236 if (!SymGetTypeInfo(GetCurrentProcess(), Base, TypeIndex, TI_GET_CHILDRENCOUNT, &ChildrenCount))
237 {
238 // ShowMessages("err, SymGetTypeInfo failed (%x)\n",
239 // GetLastError());
240 return FALSE;
241 }
242
243 //
244 // Allocate enough memory to receive the children ids
245 //
246 auto FindChildrenParamsBacking = std::make_unique<uint8_t[]>(
247 sizeof(_TI_FINDCHILDREN_PARAMS) + ((ChildrenCount - 1) * sizeof(ULONG)));
248 auto FindChildrenParams =
249 (_TI_FINDCHILDREN_PARAMS *)FindChildrenParamsBacking.get();
250
251 //
252 // Initialize the structure with the children count
253 //
254 FindChildrenParams->Count = ChildrenCount;
255
256 //
257 // Get all the children ids
258 //
259 if (!SymGetTypeInfo(GetCurrentProcess(), Base, TypeIndex, TI_FINDCHILDREN, FindChildrenParams))
260 {
261 // ShowMessages("err, SymGetTypeInfo failed (%x)\n",
262 // GetLastError());
263 return FALSE;
264 }
265
266 //
267 // Now that we have all the ids, we can walk them and find the one that
268 // matches the field we're looking for
269 //
270
271 for (DWORD ChildIdx = 0; ChildIdx < ChildrenCount; ChildIdx++)
272 {
273 //
274 // Grab the child name
275 //
276 const ULONG ChildId = FindChildrenParams->ChildId[ChildIdx];
277 WCHAR * ChildName = nullptr;
278 SymGetTypeInfo(GetCurrentProcess(), Base, ChildId, TI_GET_SYMNAME, &ChildName);
279
280 //
281 // Grab the child size - this is useful to know if a field is a bit or a
282 // normal field
283 //
284 UINT64 ChildSize = 0;
285 SymGetTypeInfo(GetCurrentProcess(), Base, ChildId, TI_GET_LENGTH, &ChildSize);
286
287 //
288 // Does this child's name match the field we're looking for?
289 //
290 Found = FALSE;
291 if (wcscmp(ChildName, FieldName) == 0)
292 {
293 //
294 // If we have found the field, now we need to find its offset if
295 // it's a normal field, or its bit position if it is a bit
296 //
297 const IMAGEHLP_SYMBOL_TYPE_INFO Info =
298 (ChildSize == 1) ? TI_GET_BITPOSITION : TI_GET_OFFSET;
299 SymGetTypeInfo(GetCurrentProcess(), Base, ChildId, Info, FieldOffset);
300
301 Found = TRUE;
302 }
303
304 //
305 // Even if we have found a match, we need to clean up the memory
306 //
307 LocalFree(ChildName);
308 ChildName = nullptr;
309
310 //
311 // We can now break out of the loop if we have what we came looking for
312 //
313 if (Found)
314 {
315 break;
316 }
317 }
318
319 return Found;
320}
unsigned long ULONG
Definition BasicTypes.h:37

◆ SymGetFileParams()

BOOL SymGetFileParams ( const char * FileName,
DWORD & FileSize )

Get symbol file parameters.

Parameters
FileName
BaseAddr
FileSize
Returns
BOOL
1221{
1222 //
1223 // Check parameters
1224 //
1225 if (FileName == 0)
1226 {
1227 return FALSE;
1228 }
1229
1230 //
1231 // Determine the extension of the file
1232 //
1233 char FileExt[_MAX_EXT] = {0};
1234
1235 _splitpath(FileName, NULL, NULL, NULL, FileExt);
1236
1237 //
1238 // Is it .PDB file?
1239 //
1240 if (strcmp(FileExt, (".pdb")) == 0 || strcmp(FileExt, (".PDB")) == 0)
1241 {
1242 //
1243 // Yes, it is a .PDB file
1244 // Determine its size, and use a dummy base address
1245 //
1246
1247 if (!SymGetFileSize(FileName, FileSize))
1248 {
1249 return FALSE;
1250 }
1251 }
1252 else
1253 {
1254 //
1255 // It is not a .PDB file
1256 // Base address and file size can be 0
1257 //
1258 FileSize = 0;
1259 return FALSE;
1260 }
1261
1262 return TRUE;
1263}
BOOL SymGetFileSize(const char *FileName, DWORD &FileSize)
Get symbol file size.
Definition symbol-parser.cpp:1274

◆ SymGetFileSize()

BOOL SymGetFileSize ( const char * FileName,
DWORD & FileSize )

Get symbol file size.

Parameters
FileName
FileSize
Returns
BOOL
1275{
1276 //
1277 // Check parameters
1278 //
1279 if (FileName == 0)
1280 {
1281 return FALSE;
1282 }
1283
1284 //
1285 // Open the file
1286 //
1287 HANDLE hFile = CreateFileA(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
1288
1289 if (hFile == INVALID_HANDLE_VALUE)
1290 {
1291 ShowMessages("err, unable to open symbol file (%x)\n", GetLastError());
1292 return FALSE;
1293 }
1294
1295 //
1296 // Obtain the size of the file
1297 //
1298 FileSize = GetFileSize(hFile, NULL);
1299
1300 if (FileSize == INVALID_FILE_SIZE)
1301 {
1302 ShowMessages("err, unable to get symbol file size (%x)\n", GetLastError());
1303
1304 //
1305 // and continue ...
1306 //
1307 }
1308
1309 //
1310 // Close the file
1311 //
1312 if (!CloseHandle(hFile))
1313 {
1314 ShowMessages("err, unable to close symbol file (%x)\n", GetLastError());
1315
1316 //
1317 // and continue ...
1318 //
1319 }
1320
1321 return (FileSize != INVALID_FILE_SIZE);
1322}

◆ SymGetModuleBaseFromSearchMask()

PSYMBOL_LOADED_MODULE_DETAILS SymGetModuleBaseFromSearchMask ( const char * SearchMask,
BOOLEAN SetModuleNameGlobally )

Interpret and find module base, based on module name.

Parameters
SearchMask
Returns
PSYMBOL_LOADED_MODULE_DETAILS NULL means error or not found, otherwise it returns the instance of loaded module based on search mask
85{
86 string Token;
87 char ModuleName[_MAX_FNAME] = {0};
88 int Index = 0;
89 char Ch = NULL;
90
91 if (!g_IsLoadedModulesInitialized || SearchMask == NULL)
92 {
93 //
94 // no module is loaded or search mask is invalid
95 //
96 return NULL;
97 }
98
99 //
100 // Convert search mask to string
101 //
102 string SearchMaskString(SearchMask);
103
104 //
105 // Check if the string contains '!'
106 //
107 char Delimiter = '!';
108 if (SearchMaskString.find(Delimiter) != std::string::npos)
109 {
110 //
111 // Found
112 //
113 Token = SearchMaskString.substr(0, SearchMaskString.find(Delimiter));
114
115 strcpy(ModuleName, Token.c_str());
116
117 if (ModuleName[0] == '\0')
118 {
119 //
120 // Invalid name
121 //
122 return NULL;
123 }
124
125 //
126 // Convert module name to lowercase
127 //
128 while (ModuleName[Index])
129 {
130 Ch = ModuleName[Index];
131
132 //
133 // convert ch to lowercase using toLower()
134 //
135 ModuleName[Index] = tolower(Ch);
136
137 Index++;
138 }
139 }
140 else
141 {
142 //
143 // There is no '!' in the middle of the search mask so,
144 // we assume that the module is nt
145 //
146 RtlZeroMemory(ModuleName, _MAX_FNAME);
147
148 ModuleName[0] = 'n';
149 ModuleName[1] = 't';
150 }
151
152 //
153 // ************* Interpret based on remarks type name *************
154 //
155 for (auto item : g_LoadedModules)
156 {
157 //
158 // Check for the module name
159 //
160 if (strcmp((const char *)item->ModuleName, ModuleName) == 0)
161 {
162 if (SetModuleNameGlobally)
163 {
164 g_CurrentModuleName = (char *)item->ModuleName;
165 }
166
167 return item;
168 }
169
170 //
171 // Check for alternative module name
172 //
173 if (strcmp((const char *)item->ModuleAlternativeName, ModuleName) == 0)
174 {
175 if (SetModuleNameGlobally)
176 {
177 g_CurrentModuleName = (char *)item->ModuleAlternativeName;
178 }
179
180 return item;
181 }
182 }
183
184 //
185 // If the function continues until here then it means
186 // that the module not found
187 //
188 return NULL;
189}
BOOLEAN g_IsLoadedModulesInitialized
Definition symbol-parser.cpp:19

◆ SymInit()

BOOLEAN SymInit ( )

initialize the DbgHelp symbols

Returns
BOOLEAN
376{
377 BOOL Ret = FALSE;
378 DWORD Options = 0;
379
380 //
381 // Get options
382 //
383 Options = SymGetOptions();
384
385 //
386 // SYMOPT_DEBUG option asks DbgHelp to print additional troubleshooting
387 // messages to debug output - use the debugger's Debug Output window
388 // to view the messages
389 //
390 Options |= SYMOPT_DEBUG;
391 Options |= SYMOPT_CASE_INSENSITIVE;
392 SymSetOptions(Options);
393
394 //
395 // Initialize DbgHelp and load symbols for all modules of the current process
396 //
397 Ret = SymInitialize(
398 GetCurrentProcess(), // Process handle of the current process
399 NULL, // No user-defined search path -> use default
400 FALSE // Do not load symbols for modules in the current process
401 );
402
403 if (!Ret)
404 {
405 ShowMessages("err, symbol init failed (%x)\n",
406 GetLastError());
407 return FALSE;
408 }
409
410 //
411 // Indicate that at least one module is loaded
412 //
414
415 return TRUE;
416}

◆ SymLoadFileSymbol()

UINT32 SymLoadFileSymbol ( UINT64 BaseAddress,
const char * PdbFileName,
const char * CustomModuleName )

load symbol based on a file name and GUID

Parameters
BaseAddress
PdbFileName
CustomModuleName
Returns
UINT32
533{
534 DWORD FileSize = 0;
535 int Index = 0;
536 char Ch = NULL;
537 char ModuleName[_MAX_FNAME] = {0};
538 char AlternateModuleName[_MAX_FNAME] = {0};
539 PSYMBOL_LOADED_MODULE_DETAILS ModuleDetails = NULL;
540
541 //
542 // Check if the loaded modules are initialized or not
543 //
545 {
546 //
547 // Initialize the symbol table
548 //
549 SymInit();
550 }
551
552 //
553 // Determine the base address and the file size
554 //
555 if (!SymGetFileParams(PdbFileName, FileSize))
556 {
557 ShowMessages("err, cannot obtain file parameters (internal error)\n");
558 return -1;
559 }
560
561 //
562 // Determine the name of the file
563 //
564 _splitpath(PdbFileName, NULL, NULL, ModuleName, NULL);
565
566 //
567 // Move to alternate list
568 //
569 strcpy(AlternateModuleName, ModuleName);
570
571 //
572 // Convert module name to lowercase
573 //
574 while (ModuleName[Index])
575 {
576 Ch = ModuleName[Index];
577
578 //
579 // convert ch to lowercase using toLower()
580 //
581 ModuleName[Index] = tolower(Ch);
582
583 Index++;
584 }
585
586 //
587 // Allocate buffer to store the details
588 //
589 ModuleDetails = (SYMBOL_LOADED_MODULE_DETAILS *)malloc(sizeof(SYMBOL_LOADED_MODULE_DETAILS));
590
591 if (ModuleDetails == NULL)
592 {
593 ShowMessages("err, allocating buffer for storing symbol details (%x)\n",
594 GetLastError());
595 return -1;
596 }
597
598 RtlZeroMemory(ModuleDetails, sizeof(SYMBOL_LOADED_MODULE_DETAILS));
599
600 ModuleDetails->ModuleBase = SymLoadModule64(
601 GetCurrentProcess(), // Process handle of the current process
602 NULL, // Handle to the module's image file (not needed)
603 PdbFileName, // Path/name of the file
604 NULL, // User-defined short name of the module (it can be NULL)
605 BaseAddress, // Base address of the module (cannot be NULL if .PDB file is
606 // used, otherwise it can be NULL)
607 FileSize // Size of the file (cannot be NULL if .PDB file is used,
608 // otherwise it can be NULL)
609 );
610
611 if (ModuleDetails->ModuleBase == NULL)
612 {
613 ShowMessages("err, loading symbols failed (%x)\n",
614 GetLastError());
615
616 free(ModuleDetails);
617 return -1;
618 }
619
620#ifndef DoNotShowDetailedResult
621
622 //
623 // Load symbols for the module
624 //
625 ShowMessages("loading symbols for: %s\n", PdbFilePath);
626
627 ShowMessages("load address: %I64x\n", ModuleDetails.ModuleBase);
628
629 //
630 // Obtain and display information about loaded symbols
631 //
632 SymShowSymbolInfo(ModuleDetails.ModuleBase);
633
634#endif // !DoNotShowDetailedResult
635
636 //
637 // Make the details (to save)
638 //
639 ModuleDetails->BaseAddress = BaseAddress;
640 strcpy((char *)ModuleDetails->ModuleName, ModuleName);
641 strcpy((char *)ModuleDetails->PdbFilePath, PdbFileName);
642
643 //
644 // Save the custom module name (if any)
645 //
646 if (CustomModuleName != NULL)
647 {
648 strcpy((char *)ModuleDetails->ModuleAlternativeName, CustomModuleName);
649 }
650
651 //
652 // Save it
653 //
654 g_LoadedModules.push_back(ModuleDetails);
655
656 return 0;
657}
UINT64 BaseAddress
Definition symbol-parser.h:30
char PdbFilePath[MAX_PATH]
Definition symbol-parser.h:34
char ModuleAlternativeName[_MAX_FNAME]
Definition symbol-parser.h:33
char ModuleName[_MAX_FNAME]
Definition symbol-parser.h:32
VOID SymShowSymbolInfo(UINT64 ModuleBase)
Show symbol info.
Definition symbol-parser.cpp:1332
BOOL SymGetFileParams(const char *FileName, DWORD &FileSize)
Get symbol file parameters.
Definition symbol-parser.cpp:1220
BOOLEAN SymInit()
initialize the DbgHelp symbols
Definition symbol-parser.cpp:375

◆ SymSearchSymbolForMask()

UINT32 SymSearchSymbolForMask ( const char * SearchMask)

Gets the offset from the symbol.

Parameters
SearchMask
Returns
UINT32
1101{
1102 BOOL Ret = FALSE;
1104
1105 //
1106 // Get the module info
1107 //
1108 SymbolInfo = SymGetModuleBaseFromSearchMask(SearchMask, TRUE);
1109
1110 //
1111 // Check to see if module info is found
1112 //
1113 if (SymbolInfo == NULL)
1114 {
1115 //
1116 // Module not found or there was an error
1117 //
1118 return -1;
1119 }
1120
1121 Ret = SymEnumSymbols(
1122 GetCurrentProcess(), // Process handle of the current process
1123 SymbolInfo->ModuleBase, // Base address of the module
1124 SearchMask, // Mask (NULL -> all symbols)
1125 SymDisplayMaskSymbolsCallback, // The callback function
1126 NULL // A used-defined context can be passed here, if necessary
1127 );
1128
1129 if (!Ret)
1130 {
1131 ShowMessages("err, symbol enum failed (%x)\n",
1132 GetLastError());
1133 }
1134
1135 return 0;
1136}
BOOL CALLBACK SymDisplayMaskSymbolsCallback(SYMBOL_INFO *SymInfo, ULONG SymbolSize, PVOID UserContext)
Callback for showing and enumerating symbols.
Definition symbol-parser.cpp:1482

◆ SymSeparateTo64BitValue()

string SymSeparateTo64BitValue ( UINT64 Value)

add ` between 64 bit values and convert them to string

Parameters
Value
Returns
string
1199{
1200 ostringstream OstringStream;
1201 string Temp;
1202
1203 OstringStream << setw(16) << setfill('0') << hex << Value;
1204 Temp = OstringStream.str();
1205
1206 Temp.insert(8, 1, '`');
1207 return Temp;
1208}
RequestedActionOfThePacket Value(0x1) 00000000

◆ SymSetTextMessageCallback()

void SymSetTextMessageCallback ( PVOID Handler)

Set the function callback that will be called if any message needs to be shown.

Parameters
HandlerFunction that handles the messages
33{
34 g_MessageHandler = Handler;
35
36 //
37 // Set the pdbex's message handler
38 //
39 pdbex_set_logging_method_export(Handler);
40}

◆ SymShowDataBasedOnSymbolTypes()

BOOLEAN SymShowDataBasedOnSymbolTypes ( const char * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
const char * AdditionalParameters )

Perform task for showing structures and data.

used by dt command

Parameters
TypeName
Address
IsStruct
BufferAddress
AdditionalParameters
Returns
BOOLEAN
2146{
2147 vector<string> SplitedSymPath;
2148 char ** ArgvArray = NULL;
2150 UINT32 SizeOfArgv = 0;
2151 UINT32 TypeNameIndex = 0;
2152
2153 //
2154 // Find the symbol info (to get the PDB address)
2155 //
2156 SymbolInfo = SymGetModuleBaseFromSearchMask(TypeName, FALSE);
2157
2158 if (!SymbolInfo)
2159 {
2160 //
2161 // Symbol not found
2162 //
2163 ShowMessages("err, couldn't resolve error at '%s'\n", TypeName);
2164
2165 return FALSE;
2166 }
2167
2168 //
2169 // Convert char* to string
2170 //
2171 std::string AdditionalParametersString(AdditionalParameters);
2172
2173 //
2174 // Split the arguments by space
2175 //
2176 SplitedSymPath = Split(AdditionalParametersString, ' ');
2177
2178 //
2179 // Allocate buffer to convert it to the char*
2180 // + 3 is because of
2181 // 1. file name
2182 // 2. type (structure) name
2183 // 3. PDB file location
2184 //
2185 SizeOfArgv = (UINT32)SplitedSymPath.size() + 3;
2186 ArgvArray = (char **)malloc(SizeOfArgv * sizeof(char *));
2187
2188 if (ArgvArray == NULL)
2189 {
2190 return FALSE;
2191 }
2192
2193 RtlZeroMemory(ArgvArray, SizeOfArgv * sizeof(char *));
2194
2195 //
2196 // First argument is the file name, we let it blank
2197 //
2198 ArgvArray[0] = (char *)NULL;
2199
2200 //
2201 // Remove the module name (if any)
2202 //
2203 while (TypeName[TypeNameIndex] != NULL)
2204 {
2205 if (TypeName[TypeNameIndex] == '!')
2206 {
2207 TypeName = &TypeName[++TypeNameIndex];
2208 break;
2209 }
2210
2211 TypeNameIndex++;
2212 }
2213
2214 //
2215 // Second argument is the type (structure) name
2216 //
2217 ArgvArray[1] = (char *)TypeName;
2218
2219 //
2220 // Third argument is the PDB file location
2221 //
2222 ArgvArray[2] = SymbolInfo->PdbFilePath;
2223
2224 //
2225 // Fill the parameter with char array
2226 //
2227 for (size_t i = 3; i < SizeOfArgv; i++)
2228 {
2229 ArgvArray[i] = (char *)SplitedSymPath.at(i - 3).c_str();
2230 }
2231
2232 //
2233 // Call the pdbex wrapper
2234 //
2235 if (IsStruct)
2236 {
2237 pdbex_export(SizeOfArgv, ArgvArray, true, BufferAddress);
2238 }
2239 else
2240 {
2241 pdbex_export(SizeOfArgv, ArgvArray, false, BufferAddress);
2242 }
2243
2244 //
2245 // Free the buffer allocated for argv
2246 //
2247 free(ArgvArray);
2248
2249 return TRUE;
2250}
UINT64 BOOLEAN IsStruct
Definition HyperDbgScriptImports.h:67
UINT64 BOOLEAN PVOID const char * AdditionalParameters
Definition HyperDbgScriptImports.h:67
UINT64 BOOLEAN PVOID BufferAddress
Definition HyperDbgScriptImports.h:67

◆ SymShowSymbolDetails()

VOID SymShowSymbolDetails ( SYMBOL_INFO & SymInfo)

Show symbols details.

Parameters
SymInfo
Returns
VOID
1530{
1531 if (g_CurrentModuleName == NULL)
1532 {
1533 //
1534 // Name Address
1535 //
1536 ShowMessages("%s ", SymSeparateTo64BitValue(SymInfo.Address).c_str());
1537 }
1538 else
1539 {
1540 //
1541 // Module!Name Address
1542 //
1543 ShowMessages("%s %s!", SymSeparateTo64BitValue(SymInfo.Address).c_str(), g_CurrentModuleName);
1544 }
1545
1546 //
1547 // Name
1548 //
1549 ShowMessages("%s\n", SymInfo.Name);
1550
1551#ifndef DoNotShowDetailedResult
1552
1553 //
1554 // Size
1555 //
1556 ShowMessages(" size: %u", SymInfo.Size);
1557
1558 //
1559 // Kind of symbol (tag)
1560 //
1561 ShowMessages(" symbol: %s ", SymTagStr(SymInfo.Tag));
1562
1563#endif // !DoNotShowDetailedResult
1564}
string SymSeparateTo64BitValue(UINT64 Value)
add ` between 64 bit values and convert them to string
Definition symbol-parser.cpp:1198
const char * SymTagStr(ULONG Tag)
Interpret different tags for pdbs.
Definition symbol-parser.cpp:1574

◆ SymShowSymbolInfo()

VOID SymShowSymbolInfo ( UINT64 ModuleBase)

Show symbol info.

Parameters
ModuleBase
Returns
VOID
1333{
1334 //
1335 // Get module information
1336 //
1337 IMAGEHLP_MODULE64 ModuleInfo;
1338
1339 memset(&ModuleInfo, 0, sizeof(ModuleInfo));
1340
1341 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
1342
1343 BOOL Ret = SymGetModuleInfo64(GetCurrentProcess(), ModuleBase, &ModuleInfo);
1344
1345 if (!Ret)
1346 {
1347 ShowMessages("err, unable to get symbol file information (%x)\n",
1348 GetLastError());
1349 return;
1350 }
1351
1352 //
1353 // Display information about symbols
1354 // Kind of symbols
1355 //
1356 switch (ModuleInfo.SymType)
1357 {
1358 case SymNone:
1359 ShowMessages("no symbols available for the module\n");
1360 break;
1361
1362 case SymExport:
1363 ShowMessages("loaded symbols: Exports\n");
1364 break;
1365
1366 case SymCoff:
1367 ShowMessages("loaded symbols: COFF\n");
1368 break;
1369
1370 case SymCv:
1371 ShowMessages("loaded symbols: CodeView\n");
1372 break;
1373
1374 case SymSym:
1375 ShowMessages("loaded symbols: SYM\n");
1376 break;
1377
1378 case SymVirtual:
1379 ShowMessages("loaded symbols: Virtual\n");
1380 break;
1381
1382 case SymPdb:
1383 ShowMessages("loaded symbols: PDB\n");
1384 break;
1385
1386 case SymDia:
1387 ShowMessages("loaded symbols: DIA\n");
1388 break;
1389
1390 case SymDeferred:
1391
1392 //
1393 // not actually loaded
1394 //
1395 ShowMessages("loaded symbols: Deferred\n");
1396 break;
1397
1398 default:
1399 ShowMessages("loaded symbols: Unknown format\n");
1400 break;
1401 }
1402
1403 //
1404 // Image name
1405 //
1406 if (ModuleInfo.ImageName[0] != '\0')
1407 {
1408 ShowMessages("image name: %s\n", ModuleInfo.ImageName);
1409 }
1410
1411 //
1412 // Loaded image name
1413 //
1414 if (ModuleInfo.LoadedImageName[0] != '\0')
1415 {
1416 ShowMessages("loaded image name: %s\n", ModuleInfo.LoadedImageName);
1417 }
1418
1419 //
1420 // Loaded PDB name
1421 //
1422 if (ModuleInfo.LoadedPdbName[0] != '\0')
1423 {
1424 ShowMessages("PDB file name: %s\n", ModuleInfo.LoadedPdbName);
1425 }
1426
1427 //
1428 // Is debug information unmatched?
1429 // (It can only happen if the debug information is contained
1430 // in a separate file (.DBG or .PDB)
1431 //
1432 if (ModuleInfo.PdbUnmatched || ModuleInfo.DbgUnmatched)
1433 {
1434 ShowMessages("warning, unmatched symbols\n");
1435 }
1436
1437 //
1438 // *** Contents ***
1439 //
1440
1441 //
1442 // Line numbers available?
1443 //
1444 ShowMessages("line numbers: %s\n",
1445 ModuleInfo.LineNumbers ? "available" : "not available");
1446
1447 //
1448 // Global symbols available?
1449 //
1450 ShowMessages("global symbols: %s\n",
1451 ModuleInfo.GlobalSymbols ? "available" : "not available");
1452
1453 //
1454 // Type information available?
1455 //
1456 ShowMessages("type information: %s\n",
1457 ModuleInfo.TypeInfo ? ("Available") : ("Not available"));
1458
1459 //
1460 // Source indexing available?
1461 //
1462 ShowMessages("source indexing: %s\n",
1463 ModuleInfo.SourceIndexed ? "yes" : "no");
1464
1465 //
1466 // Public symbols available?
1467 //
1468 ShowMessages("public symbols: %s\n",
1469 ModuleInfo.Publics ? "available" : "not available");
1470}

◆ SymTagStr()

const char * SymTagStr ( ULONG Tag)

Interpret different tags for pdbs.

Parameters
Tag
Returns
const char *
1575{
1576 switch (Tag)
1577 {
1578 case SymTagNull:
1579 return ("Null");
1580
1581 case SymTagExe:
1582 return ("Exe");
1583
1584 case SymTagCompiland:
1585 return ("Compiland");
1586
1587 case SymTagCompilandDetails:
1588 return ("CompilandDetails");
1589
1590 case SymTagCompilandEnv:
1591 return ("CompilandEnv");
1592
1593 case SymTagFunction:
1594 return ("Function");
1595
1596 case SymTagBlock:
1597 return ("Block");
1598
1599 case SymTagData:
1600 return ("Data");
1601
1602 case SymTagAnnotation:
1603 return ("Annotation");
1604
1605 case SymTagLabel:
1606 return ("Label");
1607
1608 case SymTagPublicSymbol:
1609 return ("PublicSymbol");
1610
1611 case SymTagUDT:
1612 return ("UDT");
1613
1614 case SymTagEnum:
1615 return ("Enum");
1616
1617 case SymTagFunctionType:
1618 return ("FunctionType");
1619
1620 case SymTagPointerType:
1621 return ("PointerType");
1622
1623 case SymTagArrayType:
1624 return ("ArrayType");
1625
1626 case SymTagBaseType:
1627 return ("BaseType");
1628
1629 case SymTagTypedef:
1630 return ("Typedef");
1631
1632 case SymTagBaseClass:
1633 return ("BaseClass");
1634
1635 case SymTagFriend:
1636 return ("Friend");
1637
1638 case SymTagFunctionArgType:
1639 return ("FunctionArgType");
1640
1641 case SymTagFuncDebugStart:
1642 return ("FuncDebugStart");
1643
1644 case SymTagFuncDebugEnd:
1645 return ("FuncDebugEnd");
1646
1647 case SymTagUsingNamespace:
1648 return ("UsingNamespace");
1649
1650 case SymTagVTableShape:
1651 return ("VTableShape");
1652
1653 case SymTagVTable:
1654 return ("VTable");
1655
1656 case SymTagCustom:
1657 return ("Custom");
1658
1659 case SymTagThunk:
1660 return ("Thunk");
1661
1662 case SymTagCustomType:
1663 return ("CustomType");
1664
1665 case SymTagManagedType:
1666 return ("ManagedType");
1667
1668 case SymTagDimension:
1669 return ("Dimension");
1670
1671 default:
1672 return ("Unknown");
1673 }
1674
1675 return ("");
1676}
POOL_TYPE SIZE_T ULONG Tag
Definition Hooks.h:168

◆ SymUnloadAllSymbols()

UINT32 SymUnloadAllSymbols ( )

Unload all the symbols.

Returns
UINT32
727{
728 BOOL Ret = FALSE;
729 BOOLEAN IsAnythingLoaded = FALSE;
730
731 //
732 // Check if it's already initialized
733 //
735 {
736 return 0;
737 }
738
739 for (auto item : g_LoadedModules)
740 {
741 //
742 // At least one module is loaded
743 //
744 IsAnythingLoaded = TRUE;
745
746 //
747 // Unload symbols for the module
748 //
749 Ret = SymUnloadModule64(GetCurrentProcess(), item->ModuleBase);
750
751 if (!Ret)
752 {
753 // ShowMessages("err, unload symbol failed (%x)\n",
754 // GetLastError());
755 }
756
757 free(item);
758 }
759
760 //
761 // Check if there is at least one module is loaded
762 //
763 if (!IsAnythingLoaded)
764 {
765 //
766 // Nothing is loaded yet!
767 //
768 return 0;
769 }
770
771 //
772 // Clear the list
773 //
774 g_LoadedModules.clear();
775
776 //
777 // Uninitialize DbgHelp
778 //
779 Ret = SymCleanup(GetCurrentProcess());
780
781 if (!Ret)
782 {
783 ShowMessages("err, symbol cleanup failed (%x)\n", GetLastError());
784 return 0;
785 }
786
787 //
788 // It's not initialized anymore
789 //
791
792 return 0;
793}

◆ SymUnloadModuleSymbol()

UINT32 SymUnloadModuleSymbol ( char * ModuleName)

Unload one module symbol.

Parameters
ModuleName
Returns
UINT32
668{
669 BOOLEAN OneModuleFound = FALSE;
670 BOOL Ret = FALSE;
671 UINT32 Index = 0;
672
673 for (auto item : g_LoadedModules)
674 {
675 Index++;
676
677 if (strcmp(item->ModuleName, ModuleName) == 0 || strcmp(item->ModuleAlternativeName, ModuleName) == 0)
678 {
679 //
680 // Unload symbol for the module
681 //
682 Ret = SymUnloadModule64(GetCurrentProcess(), item->ModuleBase);
683
684 if (!Ret)
685 {
686 ShowMessages("err, unload symbol failed (%x)\n",
687 GetLastError());
688 return -1;
689 }
690
691 OneModuleFound = TRUE;
692
693 free(item);
694
695 break;
696 }
697 }
698
699 if (!OneModuleFound)
700 {
701 //
702 // Not found
703 //
704 return -1;
705 }
706
707 //
708 // Remove it from the vector
709 //
710 std::vector<PSYMBOL_LOADED_MODULE_DETAILS>::iterator it = g_LoadedModules.begin();
711 std::advance(it, --Index);
712 g_LoadedModules.erase(it);
713
714 //
715 // Success
716 //
717 return 0;
718}

Variable Documentation

◆ g_AbortLoadingExecution

BOOLEAN g_AbortLoadingExecution = FALSE

◆ g_CurrentModuleName

CHAR* g_CurrentModuleName = NULL

◆ g_IsLoadedModulesInitialized

BOOLEAN g_IsLoadedModulesInitialized = FALSE

◆ g_LoadedModules

std::vector<PSYMBOL_LOADED_MODULE_DETAILS> g_LoadedModules

◆ g_MessageHandler

PVOID g_MessageHandler = NULL

The handler for ShowMessages function this is because the user might choose not to use printf and instead use his/her handler for showing messages.

◆ g_SymbolMapForDisassembler

SymbolMapCallback g_SymbolMapForDisassembler = NULL