📄 excepthandler.cpp
字号:
else
bContinue = FALSE;
}
}
BOOL CExceptionLogger::EnumSymbols(PSYMBOL_INFO pSymbolInfo, ULONG /*SymbolSize*/, PVOID pUserContext)
{
LogSymbol(pSymbolInfo, (STACKFRAME*) pUserContext);
Log(_T("\r\n")); //Each symbol gets its own line
//Continue enumeration
return TRUE;
}
void CExceptionLogger::LogSymbol(PSYMBOL_INFO pSymbolInfo, STACKFRAME* pStackFrame)
{
//Display details on the symbols type
if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER)
Log(_T(" Parameter: "));
else if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_FUNCTION)
Log(_T(" Function: "));
else if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL)
Log(_T(" Local: "));
else if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_INFO_CONSTANT)
Log(_T(" Constant: "));
//Display the symbols name
Log(_T(" %hs"), pSymbolInfo->Name);
//Return immediately if the symbol is not for data
if (pSymbolInfo->Tag != 7) //SymTagData is 7 as taken from the DIA SDK Header file cvconst.h
return;
//Display the value if valid
if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_INFO_VALUEPRESENT)
Log(_T(", Value: %I64d"), pSymbolInfo->Value);
//Punt on register values
if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER)
{
Log(_T(", Register"));
return;
}
//Work out the address of the variable
DWORD dwSymbolAddress = 0;
if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE)
{
Log(_T(", Register Relative"));
dwSymbolAddress = pStackFrame->AddrFrame.Offset;
dwSymbolAddress += ((DWORD) pSymbolInfo->Address);
}
else
{
if (pSymbolInfo->Flags & IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE)
{
Log(_T(", Frame Relative"));
return;
}
dwSymbolAddress = ((DWORD) pSymbolInfo->Address);
}
Log(_T(", Address: %08X"), dwSymbolAddress);
BOOL bHandled = LogUDTSymbolDetails(pSymbolInfo->TypeIndex, pSymbolInfo->ModBase, dwSymbolAddress, 3);
if (!bHandled)
{
//Get the type of the symbol
DWORD dwType = GetBasicType(pSymbolInfo->TypeIndex, pSymbolInfo->ModBase);
//Now that we have the type display the actual symbols value
Log(_T(", "));
LogBasicSymbolDetails(dwType, pSymbolInfo->Size, (void*)dwSymbolAddress);
}
}
BOOL CExceptionLogger::LogUDTSymbolDetails(DWORD dwTypeIndex, DWORD64 modBase, DWORD dwOffset, DWORD dwIndent)
{
__try
{
HANDLE hProcess = GetCurrentProcess();
//First get the symbol name, which will either be the
//type name if a UDT or the member name otherwise
wchar_t* pszTypeName = NULL;
if (SymGetTypeInfo(hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME, &pszTypeName))
{
Log(_T(" %ls"), pszTypeName);
LocalFree(pszTypeName);
}
//Next we need to find out how many children this symbol has
DWORD dwChildren = 0;
SymGetTypeInfo(hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &dwChildren);
//No children then return immediately
if (dwChildren == 0)
return FALSE;
//Form the identation correctly
Log(_T("\r\n"));
for (DWORD j=0; j<dwIndent; j++)
Log(_T("\t"));
//Next get all the type Id's for all the children
struct myTI_FIND_PARAMS : TI_FINDCHILDREN_PARAMS
{
ULONG nOtherChildren[1024];
} myFindParams;
myFindParams.Count = dwChildren;
myFindParams.Start = 0;
if (!SymGetTypeInfo(hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN, &myFindParams))
return FALSE;
//Iterate thro all the children
for (DWORD i=0; i<dwChildren; i++)
{
if (!LogUDTSymbolDetails(myFindParams.ChildId[i], modBase, dwOffset, dwIndent+1))
{
//This child item must be a basic type, so log it's info
//First need to get it's offset relative to the parent
DWORD dwMemberOffset = 0;
SymGetTypeInfo(hProcess, modBase, myFindParams.ChildId[i], TI_GET_OFFSET, &dwMemberOffset);
//Get the TypeID of this child
DWORD dwTypeId = 0;
SymGetTypeInfo(hProcess, modBase, myFindParams.ChildId[i], TI_GET_TYPEID, &dwTypeId);
//Get the length of the child
ULONG64 Length = 0;
SymGetTypeInfo(hProcess, modBase, dwTypeId, TI_GET_LENGTH, &Length);
//get the basic type of the child
DWORD dwBasicType = GetBasicType(myFindParams.ChildId[i], modBase);
//Now call the helper function to display all the child's details
DWORD dwSymbolAddress = dwOffset + dwMemberOffset;
Log(_T(", "));
LogBasicSymbolDetails(dwBasicType, Length, (void*)dwSymbolAddress);
//Each child starts on a new line
if (i<(dwChildren-1))
{
Log(_T("\r\n"));
for (j=0; j<dwIndent; j++)
Log(_T("\t"));
}
}
}
}
__except(1)
{
}
return TRUE;
}
void CExceptionLogger::LogBasicSymbolDetails(DWORD dwBasicType, DWORD64 dwLength, void* pSymbolAddress)
{
__try
{
switch (dwBasicType)
{
case 0: //btNoType is 0 from DIA SDK header file cvconst.h
{
Log(_T("No Type"));
break;
}
case 1: //btVoid is 1 from DIA SDK header file cvconst.h
{
Log(_T("void, Value: %08X"), *((DWORD*)pSymbolAddress));
break;
}
case 2: //btChar is 2 from DIA SDK header file cvconst.h
{
BYTE* pAddr = (BYTE*) pSymbolAddress;
Log(_T("char, len: %d, value(s): "), dwLength);
for (DWORD64 i=0; i<dwLength; i++)
Log(_T("%hc"), pAddr[i]);
break;
}
case 6: //btInt is 6 from DIA SDK header file cvconst.h
{
//Handle the special case of a short
if (dwLength == 2 || dwLength == 6)
{
short* pAddr = (short*) pSymbolAddress;
DWORD64 dwSize = dwLength / sizeof(short);
Log(_T("short, len: %d, value(s): "), dwSize);
for (DWORD64 i=0; i<dwSize; i++)
Log(_T("%d "), pAddr[i]);
}
else
{
int* pAddr = (int*) pSymbolAddress;
DWORD64 dwSize = dwLength / sizeof(int);
Log(_T("int, len: %d, value(s): "), dwSize);
for (DWORD64 i=0; i<dwSize; i++)
Log(_T("%d "), pAddr[i]);
}
break;
}
case 7: //btUInt is 7 from DIA SDK header file cvconst.h
{
//Handle the special case of a WORD
if (dwLength == 2 || dwLength == 6)
{
WORD* pAddr = (WORD*) pSymbolAddress;
DWORD64 dwSize = dwLength / sizeof(WORD);
Log(_T("WORD, len: %d, value(s): "), dwSize);
for (DWORD64 i=0; i<dwSize; i++)
Log(_T("%u "), pAddr[i]);
}
else
{
unsigned int* pAddr = (unsigned int*) pSymbolAddress;
DWORD64 dwSize = dwLength / sizeof(unsigned int);
Log(_T("unsigned int, len: %d, value(s): "), dwSize);
for (DWORD64 i=0; i<dwSize; i++)
Log(_T("%u "), pAddr[i]);
}
break;
}
case 8: //btFloat is 8 from DIA SDK header file cvconst.h
{
if (dwLength == 4)
Log(_T("float, Value: %f"), *((float*)pSymbolAddress));
else if (dwLength == 8)
Log(_T("double, Value: %lf"), *((double*)pSymbolAddress));
else
{
BYTE* pAddr = (BYTE*) pSymbolAddress;
Log(_T("btFloat, len (bytes): %d, value(s): "), dwLength);
for (DWORD64 i=0; i<dwLength; i++)
Log(_T("%02X "), pAddr[i]);
}
break;
}
case 13: //btLong is 13 from DIA SDK header file cvconst.h
{
long* pAddr = (long*) pSymbolAddress;
DWORD64 dwSize = dwLength / sizeof(long);
Log(_T("long, len: %d, value(s): "), dwSize);
for (DWORD64 i=0; i<dwSize; i++)
Log(_T("%ld "), pAddr[i]);
break;
}
case 14: //btULong is 14 from DIA SDK header file cvconst.h
{
unsigned long* pAddr = (unsigned long*) pSymbolAddress;
DWORD64 dwSize = dwLength / sizeof(unsigned long);
Log(_T("unsigned long, len: %d, value(s): "), dwSize);
for (DWORD64 i=0; i<dwSize; i++)
Log(_T("%lu "), pAddr[i]);
break;
}
default:
{
Log(_T("Unknown Type"));
break;
}
}
}
__except(1)
{
Log(_T("Error displaying symbol"));
}
}
DWORD CExceptionLogger::GetBasicType(DWORD dwTypeIndex, DWORD64 modBase)
{
HANDLE hProcess = GetCurrentProcess();
DWORD dwType;
if (SymGetTypeInfo(hProcess, modBase, dwTypeIndex, TI_GET_BASETYPE, &dwType))
return dwType;
DWORD dwTypeID;
if (SymGetTypeInfo(hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &dwTypeID))
{
if (SymGetTypeInfo(hProcess, modBase, dwTypeID, TI_GET_BASETYPE, &dwType) )
return dwType;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -