diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/mdmpRipper/CMiniDumpObject.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/mdmpRipper/CMiniDumpObject.cpp')
| -rw-r--r-- | utils/mdmpRipper/CMiniDumpObject.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/utils/mdmpRipper/CMiniDumpObject.cpp b/utils/mdmpRipper/CMiniDumpObject.cpp new file mode 100644 index 0000000..0d064da --- /dev/null +++ b/utils/mdmpRipper/CMiniDumpObject.cpp @@ -0,0 +1,246 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#include <windows.h> +#include "tier1/strtools.h" +#include <conio.h> +#include "utlvector.h" +#include <Dbghelp.h> +#include "isqlwrapper.h" +#include "CMiniDumpObject.h" + +extern ISQLWrapper *g_pSqlWrapper; + +CMiniDumpObject::CMiniDumpObject( const char *pszFilename, CUtlVector<module> *pKnownModuleList ) +{ + InitFromFilename( pszFilename, pKnownModuleList ); +} + +CMiniDumpObject::CMiniDumpObject( HANDLE pMiniDumpHandle, CUtlVector<module> *pKnownModuleList ) +{ + InitFromHandle( pMiniDumpHandle, pKnownModuleList ); +} + +void CMiniDumpObject::Init( HANDLE pszFileMap, CUtlVector<module> *pKnownModuleList ) +{ + PMINIDUMP_DIRECTORY miniDumpDir; + PVOID pOutput; + ULONG ulSize; + + if ( !pszFileMap ) + return; + PVOID pMiniDump = MapViewOfFile( pszFileMap, FILE_MAP_READ, 0, 0, 0 ); + + MiniDumpReadDumpStream( pMiniDump, ModuleListStream, &miniDumpDir, &pOutput, &ulSize ); + + int numberOfModules = ((int *)pOutput)[0]; + MINIDUMP_MODULE *pModules = (MINIDUMP_MODULE *)((byte *)pOutput + sizeof(int)); + + for ( int i = 0; i < numberOfModules; i++ ) + { + MINIDUMP_MODULE *pCurrentModule = (pModules + i); + module *newModule = new module; + newModule->key = 0; + newModule->knownVersion = false; + int offset = pCurrentModule->ModuleNameRva; + int nSizeOfName = *(int *)((byte *)pMiniDump + offset); + char nameBuf[1024]; + char *pszName = (char *)(byte *)pMiniDump + offset + sizeof(int); + int j = 0; + for ( j = 0; j < nSizeOfName/2; j++ ) + { + nameBuf[j] = *(pszName + j*2); + } + nameBuf[j] = 0; + strcpy( newModule->name, nameBuf ); + newModule->versionInfo = GetVersionStruct(&pCurrentModule->VersionInfo); + bool added = false; + + for ( int j = 0; j < pKnownModuleList->Count(); j++ ) + { + if ( !Q_stricmp( strrchr( nameBuf, '\\' )+1, pKnownModuleList->Element( j ).name ) ) + { + newModule->myType = pKnownModuleList->Element( j ).myType; + + if ( newModule->versionInfo == pKnownModuleList->Element(j).versionInfo ) + { + newModule->key = pKnownModuleList->Element( j ).key; + newModule->knownVersion = true; + } + else + { + newModule->knownVersion = false; + } + } + if ( newModule->knownVersion ) + break; + } + switch ( newModule->myType ) + { + case GOOD: + m_goodModuleList.AddToTail( *newModule ); + added = true; + break; + case BAD: + m_badModuleList.AddToTail( *newModule ); + added = true; + break; + default: + m_unknownModuleList.AddToTail( *newModule ); + added = true; + break; + } + if ( !added ) + { + newModule->key = 0; + newModule->myType = UNKNOWN; + m_unknownModuleList.AddToTail( *newModule ); + } + } + UnmapViewOfFile( pMiniDump ); +} + +void CMiniDumpObject::InitFromHandle( HANDLE pMiniDumpHandle, CUtlVector<module> *pKnownModuleList ) +{ + if ( INVALID_HANDLE_VALUE != pMiniDumpHandle ) + { + DWORD dwNumRead = 0; + char szMdmp[ 5 ] = { 0 }; + if ( ReadFile( pMiniDumpHandle, (LPVOID)szMdmp, 4, &dwNumRead, NULL ) ) + { + if ( !Q_strcmp( "MDMP", szMdmp )) + { + HANDLE hFileMap = CreateFileMapping( pMiniDumpHandle, NULL, PAGE_READONLY, 0, 0, NULL ); + Init( hFileMap, pKnownModuleList ); + } + } + } +} + +void CMiniDumpObject::InitFromFilename( const char *pszFilename, CUtlVector<module> *pKnownModuleList ) +{ + HANDLE hFile = CreateFile(pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + InitFromHandle( hFile, pKnownModuleList ); +} + +void CMiniDumpObject::GetVersionString( char *pszOutput, version *pVersionInfo ) +{ + char firstHighVer[10]; + char firstLowVer[10]; + char secondHighVer[10]; + char secondLowVer[10]; + + int firstHigh = pVersionInfo->v1; + int secondHigh = pVersionInfo->v2; + int firstLow = pVersionInfo->v3; + int secondLow = pVersionInfo->v4; + + itoa( firstHigh, firstHighVer, 10 ); + itoa( firstLow, firstLowVer, 10 ); + itoa( secondHigh, secondHighVer, 10 ); + itoa( secondLow, secondLowVer, 10 ); + + strcat( pszOutput, firstHighVer ); + strcat( pszOutput, "." ); + strcat( pszOutput, secondHighVer ); + strcat( pszOutput, "." ); + strcat( pszOutput, firstLowVer ); + strcat( pszOutput, "." ); + strcat( pszOutput, secondLowVer ); +} + +version CMiniDumpObject::GetVersionStruct( VS_FIXEDFILEINFO *pVersionInfo ) +{ + version returnVersion; + int highVal = pVersionInfo->dwFileVersionMS; + int lowVal = pVersionInfo->dwFileVersionLS; + returnVersion.v1 = highVal >> 16; + returnVersion.v2 = (highVal << 16)>>16; + returnVersion.v3 = lowVal >> 16; + returnVersion.v4 = (lowVal << 16)>>16; + + return returnVersion; +} + +int CMiniDumpObject::ModuleListToListPanel( vgui::ListPanel *pTokenList, CUtlVector<module> *pModuleList, bool bCumulative, int startingModule) +{ + char keyNameBuf[1024] = "module"; + char modNumBuf[4] = ""; + int moduleNumber = startingModule; + + for ( int i = 0; i < pModuleList->Count(); i++ ) + { + char version[20] = ""; + moduleNumber++; + itoa( moduleNumber, modNumBuf, 10 ); + strcat( keyNameBuf, modNumBuf ); + module currentModule = pModuleList->Element(i); + GetVersionString( version, ¤tModule.versionInfo ); + bool bRepeat = false; + + if ( bCumulative ) + { + int tokenCount = pTokenList->GetItemCount(); + for ( int j = 0; j < tokenCount; j++ ) + { + KeyValues *kv = pTokenList->GetItem( j ); + const char *moduleName = strrchr( kv->GetString( "name" ), '\\' ); + const char *secondModuleName = strrchr( currentModule.name, '\\' ); + const char *checksum = kv->GetString( "checksum" ); + + if ( !stricmp( moduleName, secondModuleName ) && !strcmp( kv->GetString( "version" ), version ) ) + { + int count = kv->GetInt( "count" ); + int key = kv->GetInt( "key" ); + KeyValues *newKv = new KeyValues( keyNameBuf, "name", kv->GetString("name"), "checksum", checksum ); + newKv->SetString( "version", version ); + newKv->SetInt( "count", count+1 ); + newKv->SetInt( "key", key ); + newKv->SetColor( "cellcolor", kv->GetColor( "cellcolor" ) ); + pTokenList->RemoveItem( j ); + pTokenList->AddItem( newKv, j, false, false ); + bRepeat = true; + break; + } + } + } + + if ( !bRepeat ) + { + KeyValues *kv = new KeyValues( keyNameBuf, "name", currentModule.name); + kv->SetString( "version", version ); + kv->SetInt( "key", currentModule.key ); + if ( bCumulative ) + { + kv->SetInt( "count", 1 ); + } + int colorValue = 255; + if ( !currentModule.knownVersion ) + colorValue = 155; + switch ( currentModule.myType ) + { + case GOOD: + kv->SetColor( "cellcolor", Color(0,colorValue,0,255)); + break; + case BAD: + kv->SetColor( "cellcolor", Color(colorValue,0,0,255)); + break; + default: + kv->SetColor( "cellcolor", Color(255,255,0,255)); + break; + } + pTokenList->AddItem( kv, i, false, false ); + bRepeat = false; + } + strcpy( keyNameBuf, "module"); + } + return moduleNumber; +} + + +void CMiniDumpObject::PopulateListPanel( vgui::ListPanel *pTokenList, bool bCumulative ) +{ + int nextModuleNumber = 0; + nextModuleNumber = ModuleListToListPanel( pTokenList, &m_goodModuleList, bCumulative, nextModuleNumber ); + nextModuleNumber = ModuleListToListPanel( pTokenList, &m_unknownModuleList, bCumulative, nextModuleNumber ); + nextModuleNumber = ModuleListToListPanel( pTokenList, &m_badModuleList, bCumulative, nextModuleNumber); + ModuleListToListPanel( pTokenList, &m_badChecksumList, bCumulative, nextModuleNumber ); +} |