//获取枚举类型变量的值 std::wstring GetEnumTypeValue(int typeID, DWORD modBase, const BYTE* pData) { std::wstring valueName; //获取枚举值的基本类型 CBaseTypeEnum cBaseType = GetCBaseType(typeID, modBase); //获取枚举值的个数 DWORD childrenCount; SymGetTypeInfo( GetDebuggeeHandle(), modBase, typeID, TI_GET_CHILDRENCOUNT, &childrenCount); //获取每个枚举值 TI_FINDCHILDREN_PARAMS* pFindParams = (TI_FINDCHILDREN_PARAMS*)malloc(sizeof(TI_FINDCHILDREN_PARAMS) + childrenCount * sizeof(ULONG)); pFindParams->Start = 0; pFindParams->Count = childrenCount; SymGetTypeInfo( GetDebuggeeHandle(), modBase, typeID, TI_FINDCHILDREN, pFindParams); for (int index = 0; index != childrenCount; ++index) { //获取枚举值 VARIANT enumValue; SymGetTypeInfo( GetDebuggeeHandle(), modBase, pFindParams->ChildId[index], TI_GET_VALUE, &enumValue); if (VariantEqual(enumValue, cBaseType, pData) == TRUE) { //获取枚举值的名称 WCHAR* pBuffer; SymGetTypeInfo( GetDebuggeeHandle(), modBase, pFindParams->ChildId[index], TI_GET_SYMNAME, &pBuffer); valueName = pBuffer; LocalFree(pBuffer); break; } } free(pFindParams); //如果没有找到对应的枚举值,则显示它的基本类型值 if (valueName.length() == 0) { valueName = GetBaseTypeValue(typeID, modBase, pData); } return valueName; }
//获取表示C/C++基本类型的枚举 //假定typeID已经是基本类型的ID. CBaseTypeEnum GetCBaseType(int typeID, DWORD modBase) { //获取BaseTypeEnum DWORD baseType; SymGetTypeInfo( GetDebuggeeHandle(), modBase, typeID, TI_GET_BASETYPE, &baseType); //获取基本类型的长度 ULONG64 length; SymGetTypeInfo( GetDebuggeeHandle(), modBase, typeID, TI_GET_LENGTH, &length); switch (baseType) { case btVoid: return cbtVoid; case btChar: return cbtChar; case btWChar: return cbtWChar; case btInt: switch (length) { case 2: return cbtShort; case 4: return cbtInt; default: return cbtLongLong; } case btUInt: switch (length) { case 1: return cbtUChar; case 2: return cbtUShort; case 4: return cbtUInt; default: return cbtULongLong; } case btFloat: switch (length) { case 4: return cbtFloat; default: return cbtDouble; } case btBool: return cbtBool; case btLong: return cbtLong; case btULong: return cbtULong; default: return cbtNone; } }
//获取函数类型的名称 std::wstring GetFunctionTypeName(int typeID, DWORD modBase) { std::wostringstream nameBuilder; //获取参数数量 DWORD paramCount; SymGetTypeInfo( GetDebuggeeHandle(), modBase, typeID, TI_GET_CHILDRENCOUNT, ¶mCount); //获取返回值的名称 DWORD returnTypeID; SymGetTypeInfo( GetDebuggeeHandle(), modBase, typeID, TI_GET_TYPEID, &returnTypeID); nameBuilder << GetTypeName(returnTypeID, modBase); //获取每个参数的名称 BYTE* pBuffer = (BYTE*)malloc(sizeof(TI_FINDCHILDREN_PARAMS) + sizeof(ULONG) * paramCount); TI_FINDCHILDREN_PARAMS* pFindParams = (TI_FINDCHILDREN_PARAMS*)pBuffer; pFindParams->Count = paramCount; pFindParams->Start = 0; SymGetTypeInfo( GetDebuggeeHandle(), modBase, typeID, TI_FINDCHILDREN, pFindParams); nameBuilder << TEXT('('); for (int index = 0; index != paramCount; ++index) { DWORD paramTypeID; SymGetTypeInfo( GetDebuggeeHandle(), modBase, pFindParams->ChildId[index], TI_GET_TYPEID, ¶mTypeID); if (index != 0) { nameBuilder << TEXT(", "); } nameBuilder << GetTypeName(paramTypeID, modBase); } nameBuilder << TEXT(')'); free(pBuffer); return nameBuilder.str(); }
bool DumpTypeIndex( DWORD64 modBase, DWORD dwTypeIndex, unsigned nestingLevel, DWORD_PTR offset, char ending = '\n' ) { if( nestingLevel > 5 ) { return false; } DWORD typeTag = SymTagNull; if( !SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag ) ) return false; // don't process function. if( typeTag == SymTagFunction || typeTag == SymTagTypedef ) return false; // Get the name of the symbol. This will either be a Type name (if a UDT), // or the structure member name. WCHAR * pwszTypeName; CHAR pszTypeName[256] = { 0 }; if( SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME, &pwszTypeName ) ) { if( pwszTypeName[0] == 0 ) { LocalFree( pwszTypeName ); return false; } //if( nestingLevel == 1 ) _putc( '\n' ); if( typeTag == SymTagUDT ) { _putc( '\n' ); // Add appropriate indentation level (since this routine is recursive) for( unsigned j = 0; j <= nestingLevel; j++ ) _putc( '\t' ); _printf( "{%lS}", pwszTypeName ); } else { // Add appropriate indentation level (since this routine is recursive) for( unsigned j = 0; j <= nestingLevel; j++ ) _putc( '\t' ); _printf( "%lS = ", pwszTypeName ); } sprintf_s( pszTypeName, "%lS", pwszTypeName ); LocalFree( pwszTypeName ); } ULONG64 length = 0; // Get the size of the child member SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_LENGTH, &length ); DWORD typeId = 0; bool ret = true; switch( typeTag ) { case SymTagData: if( SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &typeId ) ) { ret = DumpTypeIndex( modBase, typeId, nestingLevel, offset ); } else { _putc( ending ); } break; case SymTagUDT: if( offset > 0xffff ) DumpChild( modBase, dwTypeIndex, nestingLevel, offset ); else _putc( ending ); break; case SymTagEnum: if( SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &typeId ) ) { ret = DumpTypeIndex( modBase, typeId, nestingLevel + 1, offset ); } else { _putc( ending ); } break; case SymTagPointerType: { _printf( "{0x%p}", *( (PVOID*) offset ) ); if( !SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &typeId ) ) break; ULONG64 dwLength; if( !SymGetTypeInfo( m_hProcess, modBase, typeId, TI_GET_LENGTH, &dwLength ) ) break; DWORD dwBasicType = 0; if( SymGetTypeInfo( m_hProcess, modBase, typeId, TI_GET_BASETYPE, &dwBasicType ) ) { if( dwBasicType == btChar || dwBasicType == btWChar ) { FormatOutputValue( (BasicType) dwBasicType, length, *(LPVOID*) offset ); if( ending ) _putc( ending ); break; } } else { ret = DumpTypeIndex( modBase, typeId, nestingLevel, offset ); } } break; case SymTagArrayType: { DWORD dwCount = 0; DWORD dwTypeId = 0; ULONG64 dwTypeLength = 0; DWORD dwBasicType; if( !SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_COUNT, &dwCount ) ) { _putc( ending ); break; } if( !SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &dwTypeId ) ) { _putc( ending ); break; } if( !SymGetTypeInfo( m_hProcess, modBase, dwTypeId, TI_GET_LENGTH, &dwTypeLength ) ) { _putc( ending ); break; } char ending = ','; if( SymGetTypeInfo( m_hProcess, modBase, dwTypeId, TI_GET_BASETYPE, &dwBasicType ) ) { if( dwBasicType == btWChar || dwBasicType == btChar ) ending = 0; } _printf( "{0x%p} ", offset ); for( DWORD dwIndex = 0; dwIndex < dwCount && dwIndex < 8; ++dwIndex ) { DumpTypeIndex( modBase, dwTypeId, nestingLevel + 1, (DWORD_PTR) ( offset + dwIndex * dwTypeLength ), ending ); } if( ending != '\n' ) _putc( '\n' ); } break; case SymTagBaseType: { BasicType basicType = GetBasicType( dwTypeIndex, modBase ); FormatOutputValue( basicType, length, (PVOID) offset ); if( ending ) _putc( ending ); } break; case SymTagBaseClass: if( SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &typeId ) ) { ret = DumpTypeIndex( modBase, typeId, nestingLevel + 1, offset ); } else { if( ending ) _putc( ending ); } break; default: _printf( "{0x%p} ", offset ); if( ending ) _putc( ending ); break; } return ret; }