├── .clang-format ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── Windbg_DLLs ├── x64 │ ├── dbghelp.dll │ └── symsrv.dll └── x86 │ ├── dbghelp.dll │ └── symsrv.dll ├── clean.bat ├── hyperplatform_log_parser.sln └── hyperplatform_log_parser ├── driver_symbol_resolver.cpp ├── driver_symbol_resolver.h ├── hyperplatform_log_parser.cpp ├── hyperplatform_log_parser.vcxproj ├── hyperplatform_log_parser.vcxproj.filters ├── log_line_parser.cpp ├── log_line_parser.h ├── log_parser.cpp ├── log_parser.h ├── scoped_resource ├── scope_exit.h └── unique_resource.h ├── stdafx.cpp ├── stdafx.h ├── symbol_resolver.cpp ├── symbol_resolver.h ├── targetver.h ├── utility.cpp └── utility.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Google 4 | AccessModifierOffset: -1 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlinesLeft: true 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: All 15 | AllowShortIfStatementsOnASingleLine: true 16 | AllowShortLoopsOnASingleLine: true 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakBeforeMultilineStrings: true 19 | AlwaysBreakTemplateDeclarations: true 20 | BinPackArguments: true 21 | BinPackParameters: true 22 | BraceWrapping: 23 | AfterClass: false 24 | AfterControlStatement: false 25 | AfterEnum: false 26 | AfterFunction: false 27 | AfterNamespace: false 28 | AfterObjCDeclaration: false 29 | AfterStruct: false 30 | AfterUnion: false 31 | BeforeCatch: false 32 | BeforeElse: false 33 | IndentBraces: false 34 | BreakBeforeBinaryOperators: None 35 | BreakBeforeBraces: Attach 36 | BreakBeforeTernaryOperators: true 37 | BreakConstructorInitializersBeforeComma: false 38 | ColumnLimit: 80 39 | CommentPragmas: '^ IWYU pragma:' 40 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 41 | ConstructorInitializerIndentWidth: 4 42 | ContinuationIndentWidth: 4 43 | Cpp11BracedListStyle: true 44 | DerivePointerAlignment: true 45 | DisableFormat: false 46 | ExperimentalAutoDetectBinPacking: false 47 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 48 | IncludeCategories: 49 | - Regex: '^<.*\.h>' 50 | Priority: 1 51 | - Regex: '^<.*' 52 | Priority: 2 53 | - Regex: '.*' 54 | Priority: 3 55 | IndentCaseLabels: true 56 | IndentWidth: 2 57 | IndentWrappedFunctionNames: false 58 | KeepEmptyLinesAtTheStartOfBlocks: false 59 | MacroBlockBegin: '' 60 | MacroBlockEnd: '' 61 | MaxEmptyLinesToKeep: 1 62 | NamespaceIndentation: None 63 | ObjCBlockIndentWidth: 2 64 | ObjCSpaceAfterProperty: false 65 | ObjCSpaceBeforeProtocolList: false 66 | PenaltyBreakBeforeFirstCallParameter: 1 67 | PenaltyBreakComment: 300 68 | PenaltyBreakFirstLessLess: 120 69 | PenaltyBreakString: 1000 70 | PenaltyExcessCharacter: 1000000 71 | PenaltyReturnTypeOnItsOwnLine: 200 72 | SortIncludes: false 73 | PointerAlignment: Left 74 | SpaceAfterCStyleCast: false 75 | SpaceBeforeAssignmentOperators: true 76 | SpaceBeforeParens: ControlStatements 77 | SpaceInEmptyParentheses: false 78 | SpacesBeforeTrailingComments: 2 79 | SpacesInAngles: false 80 | SpacesInContainerLiterals: true 81 | SpacesInCStyleCastParentheses: false 82 | SpacesInParentheses: false 83 | SpacesInSquareBrackets: false 84 | Standard: Auto 85 | TabWidth: 8 86 | UseTab: Never 87 | ... 88 | 89 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Satoshi Tanda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | hyperplaform_log_parser 2 | ======================== 3 | 4 | Introduction 5 | ------------- 6 | hyperplaform_log_parser is a user-mode program parsing logs created by 7 | HyperPlatform. hyperplaform_log_parser monitors updates in a log file and parses 8 | log lines if any new entries are added. Also, hyperplaform_log_parser is able to 9 | resolve symbol names if possible. 10 | 11 | Currently, hyperplaform_log_parser supports logs from MemoryMon. 12 | 13 | 14 | Installation and Uninstallation 15 | -------------------------------- 16 | Run hyperplaform_log_parser.exe with a path to a log file. For example, 17 | 18 | > hyperplaform_log_parser.exe C:\Windows\MemoryMon.log 19 | 20 | hyperplaform_log_parser.exe is able to use symbol information if a specified log 21 | file is created by the current boot session, internet connection is available 22 | and accompaning Windbg DLLs (dbghelp.dll and symsrv.dll) are stored in the same 23 | folder as hyperplaform_log_parser.exe. 24 | 25 | 26 | Output 27 | ------- 28 | All logs are printed out to STDIO. There is an example of outout with symbol 29 | information: 30 | 31 | 08:47:07.276 4: 0 executed fffffa800194a468, will return to fffff80002ad8c1c nt!KiRetireDpcList+0x1bc 32 | 08:47:07.276 4: 0 executed fffffa8003d46007, will return to fffffa800194a4ad 33 | 08:47:07.276 4: 0 executed fffffa8003d47580, will return to fffffa8003d460b0 34 | 08:47:07.291 4: 64 executed fffffa8003d4ae1c, will return to fffff80002ad7b69 nt!ExpWorkerThread+0x111 35 | 08:45:07.265 4: 64 executed fffffa8002626629, will return to 4 36 | 37 | 38 | Supported Platforms 39 | ---------------------- 40 | - x86 and x64 Windows 7, 8.1 and 10 41 | 42 | 43 | License 44 | -------- 45 | This software is released under the MIT License, see LICENSE. 46 | -------------------------------------------------------------------------------- /Windbg_DLLs/x64/dbghelp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/hyperplatform_log_parser/7a7eba3c8c582fa43ba2a47372a363080796d2d4/Windbg_DLLs/x64/dbghelp.dll -------------------------------------------------------------------------------- /Windbg_DLLs/x64/symsrv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/hyperplatform_log_parser/7a7eba3c8c582fa43ba2a47372a363080796d2d4/Windbg_DLLs/x64/symsrv.dll -------------------------------------------------------------------------------- /Windbg_DLLs/x86/dbghelp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/hyperplatform_log_parser/7a7eba3c8c582fa43ba2a47372a363080796d2d4/Windbg_DLLs/x86/dbghelp.dll -------------------------------------------------------------------------------- /Windbg_DLLs/x86/symsrv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tandasat/hyperplatform_log_parser/7a7eba3c8c582fa43ba2a47372a363080796d2d4/Windbg_DLLs/x86/symsrv.dll -------------------------------------------------------------------------------- /clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del *.sdf 3 | del *.VC.db 4 | del /s *.aps 5 | del /a:h *.suo 6 | rmdir /s /q .vs 7 | rmdir /s /q ipch 8 | rmdir /s /q x64 9 | rmdir /s /q Debug 10 | rmdir /s /q Release 11 | rmdir /s /q hyperplatform_log_parser\x64 12 | rmdir /s /q hyperplatform_log_parser\Debug 13 | rmdir /s /q hyperplatform_log_parser\Release 14 | pause 15 | -------------------------------------------------------------------------------- /hyperplatform_log_parser.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperplatform_log_parser", "hyperplatform_log_parser\hyperplatform_log_parser.vcxproj", "{E61F484B-EBB8-4C23-9157-17A1AA3E5660}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{731098F8-C0FE-4D8A-9505-ADD8E3ED79A1}" 9 | ProjectSection(SolutionItems) = preProject 10 | .clang-format = .clang-format 11 | .gitattributes = .gitattributes 12 | .gitignore = .gitignore 13 | clean.bat = clean.bat 14 | README.md = README.md 15 | EndProjectSection 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|x64 = Debug|x64 20 | Debug|x86 = Debug|x86 21 | Release|x64 = Release|x64 22 | Release|x86 = Release|x86 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Debug|x64.ActiveCfg = Debug|x64 26 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Debug|x64.Build.0 = Debug|x64 27 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Debug|x86.ActiveCfg = Debug|Win32 28 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Debug|x86.Build.0 = Debug|Win32 29 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Release|x64.ActiveCfg = Release|x64 30 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Release|x64.Build.0 = Release|x64 31 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Release|x86.ActiveCfg = Release|Win32 32 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660}.Release|x86.Build.0 = Release|Win32 33 | EndGlobalSection 34 | GlobalSection(SolutionProperties) = preSolution 35 | HideSolutionNode = FALSE 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/driver_symbol_resolver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #include "stdafx.h" 10 | #include "driver_symbol_resolver.h" 11 | #include "utility.h" 12 | 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // macro utilities 16 | // 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // constants and macros 21 | // 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // types 26 | // 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // 30 | // prototypes 31 | // 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | // 35 | // variables 36 | // 37 | 38 | //////////////////////////////////////////////////////////////////////////////// 39 | // 40 | // implementations 41 | // 42 | 43 | std::basic_string DriverSymbolResolver::GetName( 44 | std::uint64_t address, std::uint64_t base_address) { 45 | if (!address || !base_address) { 46 | return {}; 47 | } 48 | 49 | UpdateDriverList(); 50 | 51 | for (auto &driver : driver_list_) { 52 | if (driver.first != base_address) { 53 | continue; 54 | } 55 | 56 | // Does it need to update a symbol? 57 | if (driver.first != driver_base_) { 58 | symbol_resolver_.UnloadModule(symbol_module_base_); 59 | symbol_module_base_ = symbol_resolver_.LoadModule(driver.second); 60 | driver_base_ = driver.first; 61 | } 62 | 63 | if (symbol_module_base_) { 64 | const auto offset = address - base_address; 65 | const auto name = symbol_resolver_.GetName(symbol_module_base_ + offset); 66 | if (!name.empty()) { 67 | std::tr2::sys::path path(driver.second); 68 | auto driverBaseName = path.stem().wstring(); 69 | if (driverBaseName == L"ntoskrnl" || driverBaseName == L"ntkrnlpa") { 70 | driverBaseName = L"nt"; 71 | } 72 | return driverBaseName + L"!" + name; 73 | } 74 | } 75 | } 76 | return {}; 77 | } 78 | 79 | bool DriverSymbolResolver::UpdateDriverList() { 80 | const auto now = std::chrono::system_clock::now(); 81 | const auto elapsed_seconds = now - list_updated_time_; 82 | if (elapsed_seconds.count() > 5) { 83 | list_updated_time_ = now; 84 | driver_list_ = GetDriverList(); 85 | return true; 86 | } 87 | return false; 88 | } 89 | 90 | // Get a list of drivers' base addresses and file paths that are currently 91 | // loaded in the kernel. 92 | DriverSymbolResolver::DriverInfoList DriverSymbolResolver::GetDriverList() { 93 | // Determine the current number of drivers 94 | DWORD needed = 0; 95 | std::array base_addresses; 96 | if (!::EnumDeviceDrivers( 97 | base_addresses.data(), 98 | static_cast(base_addresses.size() * sizeof(void *)), 99 | &needed)) { 100 | utility::ThrowRuntimeError(TEXT("EnumDeviceDrivers failed.")); 101 | } 102 | 103 | TCHAR system_root[MAX_PATH]; 104 | if (!::ExpandEnvironmentStrings(TEXT("%SystemRoot%"), system_root, 105 | _countof(system_root))) { 106 | utility::ThrowRuntimeError(TEXT("ExpandEnvironmentStrings failed.")); 107 | } 108 | 109 | // Collect their base names 110 | DriverInfoList list; 111 | const auto number_of_drivers = needed / sizeof(base_addresses.at(0)); 112 | for (std::uint32_t i = 0; i < number_of_drivers; ++i) { 113 | std::array path_buffer; 114 | if (!::GetDeviceDriverFileName(base_addresses.at(i), path_buffer.data(), 115 | static_cast(path_buffer.size()))) { 116 | utility::ThrowRuntimeError(TEXT("GetDeviceDriverBaseName failed.")); 117 | } 118 | 119 | std::basic_string path(path_buffer.data()); 120 | if (path.compare(0, 11, TEXT("\\SystemRoot")) == 0) { 121 | path.replace(0, 11, system_root); 122 | } else if (path.compare(0, 4, TEXT("\\??\\")) == 0) { 123 | path.replace(0, 4, TEXT("")); 124 | } 125 | std::transform(path.begin(), path.end(), path.begin(), ::tolower); 126 | list.emplace_back(reinterpret_cast(base_addresses.at(i)), 127 | path); 128 | } 129 | return list; 130 | } 131 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/driver_symbol_resolver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #ifndef HYPERPLATFORM_LOG_PARSER_DRIVER_SYMBOL_RESOLVER_H_ 10 | #define HYPERPLATFORM_LOG_PARSER_DRIVER_SYMBOL_RESOLVER_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "symbol_resolver.h" 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // macro utilities 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // constants and macros 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // types 33 | // 34 | 35 | class DriverSymbolResolver { 36 | public: 37 | std::basic_string GetName(std::uint64_t address, 38 | std::uint64_t base_address); 39 | 40 | private: 41 | using DriverInfo = std::pair>; 42 | using DriverInfoList = std::vector; 43 | 44 | bool UpdateDriverList(); 45 | static DriverInfoList GetDriverList(); 46 | 47 | SymbolResolver symbol_resolver_; 48 | DriverInfoList driver_list_; 49 | std::chrono::time_point list_updated_time_; 50 | std::uint64_t symbol_module_base_; 51 | std::uint64_t driver_base_; 52 | }; 53 | 54 | //////////////////////////////////////////////////////////////////////////////// 55 | // 56 | // prototypes 57 | // 58 | 59 | //////////////////////////////////////////////////////////////////////////////// 60 | // 61 | // variables 62 | // 63 | 64 | //////////////////////////////////////////////////////////////////////////////// 65 | // 66 | // implementations 67 | // 68 | 69 | #endif // HYPERPLATFORM_LOG_PARSER_DRIVER_SYMBOL_RESOLVER_H_ 70 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/hyperplatform_log_parser.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements an entry point of the driver. 7 | // 8 | 9 | #include "stdafx.h" 10 | #include "log_parser.h" 11 | #include "utility.h" 12 | 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // macro utilities 16 | // 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // constants and macros 21 | // 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // types 26 | // 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // 30 | // prototypes 31 | // 32 | 33 | bool AppMain(_In_ const std::vector> &args); 34 | 35 | //////////////////////////////////////////////////////////////////////////////// 36 | // 37 | // variables 38 | // 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | // 42 | // implementations 43 | // 44 | // 45 | 46 | int _tmain(int argc, TCHAR *argv[]) { 47 | auto exit_code = EXIT_FAILURE; 48 | try { 49 | std::vector> args; 50 | for (auto i = 0; i < argc; ++i) { 51 | args.push_back(argv[i]); 52 | } 53 | if (AppMain(args)) { 54 | exit_code = EXIT_SUCCESS; 55 | } 56 | } catch (std::exception &e) { 57 | std::cout << e.what() << std::endl; 58 | } catch (...) { 59 | std::cout << "Unhandled exception occurred." << std::endl; 60 | } 61 | return exit_code; 62 | } 63 | 64 | // A main application loop 65 | _Use_decl_annotations_ bool AppMain( 66 | const std::vector> &args) { 67 | if (args.size() == 1) { 68 | std::cout << "Usage:\n" 69 | << " >this.exe \n" << std::endl; 70 | return false; 71 | } 72 | 73 | LogParser log_parser(args.at(1)); 74 | for (;;) { 75 | std::this_thread::sleep_for(std::chrono::seconds(1)); 76 | log_parser.ParseFile(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/hyperplatform_log_parser.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {E61F484B-EBB8-4C23-9157-17A1AA3E5660} 23 | Win32Proj 24 | hyperplatform_log_parser 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | Use 87 | Level4 88 | Disabled 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Use 100 | Level4 101 | Disabled 102 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 103 | true 104 | 105 | 106 | Console 107 | true 108 | 109 | 110 | 111 | 112 | Level4 113 | Use 114 | MaxSpeed 115 | true 116 | true 117 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | MultiThreaded 120 | 121 | 122 | Console 123 | true 124 | true 125 | true 126 | 127 | 128 | 129 | 130 | Level4 131 | Use 132 | MaxSpeed 133 | true 134 | true 135 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 136 | true 137 | MultiThreaded 138 | 139 | 140 | Console 141 | true 142 | true 143 | true 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | Create 164 | Create 165 | Create 166 | Create 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/hyperplatform_log_parser.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {1d76cbe8-bd76-43b0-af4c-a5050a4ea471} 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files\scoped_resource 29 | 30 | 31 | Header Files\scoped_resource 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/log_line_parser.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #include "stdafx.h" 10 | #include "log_line_parser.h" 11 | #include "utility.h" 12 | 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // macro utilities 16 | // 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // constants and macros 21 | // 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // types 26 | // 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // 30 | // prototypes 31 | // 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | // 35 | // variables 36 | // 37 | 38 | //////////////////////////////////////////////////////////////////////////////// 39 | // 40 | // implementations 41 | // 42 | 43 | bool LogLineParser::Parse(const std::string &log_line) { 44 | if (log_line.empty()) { 45 | return false; 46 | } 47 | 48 | // Split a log into some basic elements 49 | const auto log_elements = utility::Split(log_line, '\t'); 50 | time_ = log_elements[0]; 51 | pid_ = std::stoul(log_elements[3]); 52 | tid_ = std::stoul(log_elements[4]); 53 | message_ = log_elements[6]; 54 | 55 | // Get a digit for a pointer 56 | SYSTEM_INFO system_info = {}; 57 | GetNativeSystemInfo(&system_info); 58 | pointer_size_ = 59 | (system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) 60 | ? "16" 61 | : "8"; 62 | 63 | if (TryParseExecutionLog()) { 64 | return true; 65 | } 66 | if (TryParseRweLog()) { 67 | return true; 68 | } 69 | return false; 70 | } 71 | 72 | // Attempts to parse a line reported for dodgy region execution 73 | bool LogLineParser::TryParseExecutionLog() { 74 | // clang-format off 75 | std::regex regex( 76 | "\\[EXEC\\] \\*\\*\\* " 77 | "VA = ([[:xdigit:]]{" + pointer_size_ + "}), " 78 | "PA = [[:xdigit:]]{16}, " 79 | "Return = ([[:xdigit:]]{" + pointer_size_ + "}), " 80 | "ReturnBase = ([[:xdigit:]]{" + pointer_size_ + "})"); 81 | // clang-format on 82 | 83 | std::smatch match; 84 | if (!std::regex_match(message_, match, regex)) { 85 | return false; 86 | } 87 | 88 | // Successfully parsed. Print it to STDIO 89 | const auto executed_address = std::stoull(match[1].str(), nullptr, 16); 90 | const auto return_address = std::stoull(match[2].str(), nullptr, 16); 91 | const auto return_base_address = std::stoull(match[3].str(), nullptr, 16); 92 | const auto symbol = 93 | driver_symbol_resolver_.GetName(return_address, return_base_address); 94 | const std::string format_string = "%s %5u:%5u executed %" + pointer_size_ + 95 | "llx, will return to %" + pointer_size_ + 96 | "llx %S\n"; 97 | printf(format_string.c_str(), time_.c_str(), pid_, tid_, executed_address, 98 | return_address, symbol.c_str()); 99 | return true; 100 | } 101 | 102 | // Attempts to parse a line reported by MemoryMonRWE 103 | bool LogLineParser::TryParseRweLog() { 104 | // clang-format off 105 | std::regex regex( 106 | "[SR]= ([[:xdigit:]]{" + pointer_size_ + "}) " 107 | "\\(([[:xdigit:]]{" + pointer_size_ + "})\\), " 108 | "[D]= ([[:xdigit:]]{" + pointer_size_ + "}) " 109 | "\\(([[:xdigit:]]{" + pointer_size_ + "})\\), " 110 | "T= [RWE]"); 111 | // clang-format on 112 | 113 | std::smatch match; 114 | if (!std::regex_match(message_, match, regex)) { 115 | return false; 116 | } 117 | 118 | // Successfully parsed. Print it to STDIO 119 | const auto s_address = std::stoull(match[1].str(), nullptr, 16); 120 | const auto s_base = std::stoull(match[2].str(), nullptr, 16); 121 | const auto d_address = std::stoull(match[3].str(), nullptr, 16); 122 | const auto d_base = std::stoull(match[4].str(), nullptr, 16); 123 | const auto s_symbol = driver_symbol_resolver_.GetName(s_address, s_base); 124 | const auto d_symbol = driver_symbol_resolver_.GetName(d_address, d_base); 125 | 126 | const std::string format_string = "%s %5u:%5u S= %-50S, D= %-50S\n"; 127 | printf(format_string.c_str(), time_.c_str(), pid_, tid_, s_symbol.c_str(), 128 | d_symbol.c_str()); 129 | return true; 130 | } 131 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/log_line_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #ifndef HYPERPLATFORM_LOG_PARSER_LOG_LINE_PARSER_H_ 10 | #define HYPERPLATFORM_LOG_PARSER_LOG_LINE_PARSER_H_ 11 | 12 | #include 13 | #include 14 | #include "driver_symbol_resolver.h" 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // macro utilities 19 | // 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // constants and macros 24 | // 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // 28 | // types 29 | // 30 | 31 | class LogLineParser { 32 | public: 33 | bool Parse(const std::string &log_line); 34 | 35 | private: 36 | bool TryParseExecutionLog(); 37 | bool TryParseRweLog(); 38 | 39 | DriverSymbolResolver driver_symbol_resolver_; 40 | std::string time_; 41 | std::uint32_t pid_; 42 | std::uint32_t tid_; 43 | std::string message_; 44 | std::string pointer_size_; 45 | }; 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | // 49 | // prototypes 50 | // 51 | 52 | //////////////////////////////////////////////////////////////////////////////// 53 | // 54 | // variables 55 | // 56 | 57 | //////////////////////////////////////////////////////////////////////////////// 58 | // 59 | // implementations 60 | // 61 | 62 | #endif // HYPERPLATFORM_LOG_PARSER_LOG_LINE_PARSER_H_ 63 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/log_parser.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #include "stdafx.h" 10 | #include "log_parser.h" 11 | 12 | //////////////////////////////////////////////////////////////////////////////// 13 | // 14 | // macro utilities 15 | // 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | // 19 | // constants and macros 20 | // 21 | 22 | //////////////////////////////////////////////////////////////////////////////// 23 | // 24 | // types 25 | // 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | // 29 | // prototypes 30 | // 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | // 34 | // variables 35 | // 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // 39 | // implementations 40 | // 41 | 42 | LogParser::LogParser(const std::basic_string& log_path) 43 | : log_path_(log_path) {} 44 | 45 | // Opens a log file and checks if the length is the same as the last check. If 46 | // not, parse newly added lines. 47 | bool LogParser::ParseFile() { 48 | std::ifstream log_file(log_path_); 49 | if (!log_file) { 50 | return false; 51 | } 52 | log_file.seekg(0, log_file.end); 53 | const auto end_position = log_file.tellg(); 54 | if (end_position < old_position_) { 55 | old_position_ = 0; 56 | } 57 | if (end_position == old_position_) { 58 | return false; 59 | } 60 | 61 | // Parse new lines 62 | log_file.seekg(old_position_, log_file.beg); 63 | std::string log_line; 64 | while (!log_file.eof()) { 65 | std::getline(log_file, log_line); 66 | log_line_parser_.Parse(log_line); 67 | } 68 | old_position_ = end_position; 69 | return true; 70 | } 71 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/log_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #ifndef HYPERPLATFORM_LOG_PARSER_LOG_PARSER_H_ 10 | #define HYPERPLATFORM_LOG_PARSER_LOG_PARSER_H_ 11 | 12 | #include 13 | #include 14 | #include "log_line_parser.h" 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // macro utilities 19 | // 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // constants and macros 24 | // 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // 28 | // types 29 | // 30 | 31 | class LogParser { 32 | public: 33 | explicit LogParser(const std::basic_string& log_path); 34 | bool ParseFile(); 35 | 36 | private: 37 | LogLineParser log_line_parser_; 38 | std::basic_string log_path_; 39 | std::streampos old_position_; 40 | }; 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // 44 | // prototypes 45 | // 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | // 49 | // variables 50 | // 51 | 52 | //////////////////////////////////////////////////////////////////////////////// 53 | // 54 | // implementations 55 | // 56 | 57 | #endif // HYPERPLATFORM_LOG_PARSER_LOG_PARSER_H_ 58 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/scoped_resource/scope_exit.h: -------------------------------------------------------------------------------- 1 | // This implementation is copied from below with small modification. 2 | // 3 | // P0052R1 - Generic Scope Guard and RAII Wrapper for the Standard Library 4 | // by Peter Sommerlad and Andrew L. Sandoval 5 | 6 | #ifndef SCOPE_EXIT_H_ 7 | #define SCOPE_EXIT_H_ 8 | #include 9 | #include 10 | // modeled slightly after Andrescu’s talk and article(s) 11 | namespace std { 12 | namespace experimental { 13 | template 14 | struct scope_exit { 15 | // construction 16 | explicit scope_exit(EF f) noexcept : exit_function{f} { 17 | static_assert(std::is_nothrow_copy_constructible{}, "must be copyable"); 18 | } 19 | // move ctor for factory 20 | scope_exit(scope_exit &&rhs) noexcept 21 | : exit_function{rhs.exit_function}, 22 | execute_on_destruction_flag{rhs.execute_on_destruction_flag} { 23 | rhs.release(); 24 | } 25 | // release 26 | ~scope_exit() { 27 | if (execute_on_destruction_flag) exit_function(); 28 | } 29 | void release() noexcept { execute_on_destruction_flag = false; } 30 | scope_exit(scope_exit const &) = delete; 31 | scope_exit &operator=(scope_exit const &) = delete; 32 | scope_exit &operator=(scope_exit &&) = delete; 33 | 34 | private: 35 | EF exit_function; // exposition only 36 | bool execute_on_destruction_flag{true}; // exposition only 37 | }; 38 | 39 | template 40 | auto make_scope_exit(EF exit_function) noexcept { 41 | return scope_exit(exit_function); 42 | } 43 | template 44 | auto make_scope_fail(EF exit_function) noexcept { 45 | return make_scope_exit([ =, ec = std::uncaught_exceptions() ]() { 46 | if (ec < uncaught_exceptions()) exit_function(); 47 | }); 48 | } 49 | template 50 | auto make_scope_success(EF exit_function) noexcept { 51 | return make_scope_exit([ =, ec = std::uncaught_exceptions() ]() { 52 | if (!(ec < uncaught_exceptions())) exit_function(); 53 | }); 54 | } 55 | } 56 | } 57 | #endif /∗ SCOPE EXIT H */ 58 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/scoped_resource/unique_resource.h: -------------------------------------------------------------------------------- 1 | // This implementation is copied from below with small modification. 2 | // 3 | // P0052R1 - Generic Scope Guard and RAII Wrapper for the Standard Library 4 | // by Peter Sommerlad and Andrew L. Sandoval 5 | 6 | #ifndef UNIQUE_RESOURCE_H_ 7 | #define UNIQUE_RESOURCE_H_ 8 | #include 9 | namespace std { 10 | namespace experimental { 11 | namespace __detail { 12 | template 13 | struct provide_operator_arrow_for_pointer_to_class_types { 14 | }; // R is non-pointer or pointer - to - non - class - type 15 | template 16 | struct provide_operator_arrow_for_pointer_to_class_types< 17 | DERIVED, R, typename std::enable_if< 18 | std::is_pointer::value && 19 | (std::is_class>::value || 20 | std::is_union>::value)>::type> { 21 | R operator->() const { return static_cast(this)->get(); } 22 | }; 23 | 24 | template 25 | struct provide_operator_star_for_pointer_types { 26 | }; // R is non-pointer or pointer-tonon-class-type 27 | template 28 | struct provide_operator_star_for_pointer_types< 29 | DERIVED, R, std::enable_if_t::value, void *>> { 30 | std::add_lvalue_reference_t> operator*() const 31 | noexcept { 32 | return *(static_cast(this)->get()); 33 | } 34 | }; 35 | } // namespace detail 36 | template 37 | class unique_resource 38 | : public __detail::provide_operator_arrow_for_pointer_to_class_types< 39 | unique_resource, R>, 40 | __detail::provide_operator_star_for_pointer_types, 41 | R> { 42 | static_assert(std::is_nothrow_copy_constructible::value, 43 | "RESOURCE type must not throw on copy"); 44 | static_assert(std::is_nothrow_copy_constructible::value, 45 | "DELETER type must not throw on copy"); 46 | 47 | public: 48 | // construction 49 | explicit unique_resource(R r, D d) noexcept : resource{r}, deleter{d} {} 50 | unique_resource(unique_resource &&other) noexcept 51 | : resource(std::forward(other.resource)), 52 | deleter(std::move(other.deleter)), 53 | execute_on_destruction{other.execute_on_destruction} { 54 | other.release(); 55 | } 56 | unique_resource(unique_resource const &) = delete; // no copies! 57 | 58 | unique_resource &operator=(unique_resource &&other) noexcept( 59 | noexcept(unique_resource::reset())) { 60 | reset(); 61 | deleter = std::move(other.deleter); 62 | resource = std::move(other.resource); 63 | execute_on_destruction = other.execute_on_destruction; 64 | other.release(); 65 | return *this; 66 | } 67 | unique_resource &operator=(unique_resource const &) = delete; 68 | ~unique_resource() { reset(); } 69 | void reset() { 70 | if (execute_on_destruction) { 71 | execute_on_destruction = false; 72 | get_deleter()(resource); 73 | } 74 | } 75 | void reset(R r) { 76 | reset(); 77 | resource = r; 78 | execute_on_destruction = true; 79 | } 80 | R release() noexcept { 81 | execute_on_destruction = false; 82 | return get(); 83 | } 84 | R const &get() const noexcept { return resource; } 85 | operator R const &() const noexcept { return resource; } 86 | const D &get_deleter() const noexcept { return deleter; } 87 | 88 | private: 89 | R resource; // exposition only 90 | D deleter; // exposition only 91 | bool execute_on_destruction = true; // exposition only 92 | }; 93 | 94 | // factories 95 | template 96 | auto make_unique_resource(R resource, D deleter) noexcept { 97 | return unique_resource(resource, deleter); 98 | } 99 | template 100 | auto make_unique_resource(std::reference_wrapper resource, 101 | D deleter) noexcept { 102 | return unique_resource(resource.get(), deleter); 103 | } 104 | template 105 | auto make_unique_resource_checked(R r, S invalid, D d) noexcept { 106 | bool mustrelease = bool(r == invalid); 107 | auto ur = unique_resource(r, d); 108 | if (mustrelease) ur.release(); 109 | return ur; 110 | } 111 | } 112 | } 113 | #endif /∗ UNIQUE RESOURCE H */ 114 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // stdafx.cpp : source file that includes just the standard includes 6 | // TaiyakiUser.pch will be the pre-compiled header 7 | // stdafx.obj will contain the pre-compiled type information 8 | 9 | #include "stdafx.h" 10 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/stdafx.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // stdafx.h : include file for standard system include files, 6 | // or project specific include files that are used frequently, but 7 | // are changed infrequently 8 | 9 | #ifndef HYPERPLATFORM_LOG_PARSER_STDAFX_H_ 10 | #define HYPERPLATFORM_LOG_PARSER_STDAFX_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "targetver.h" 28 | #include 29 | #include 30 | #include 31 | #pragma comment(lib, "Psapi.lib") 32 | #include 33 | #pragma comment(lib, "Shlwapi.lib") 34 | 35 | //////////////////////////////////////////////////////////////////////////////// 36 | // 37 | // macro utilities 38 | // 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | // 42 | // constants and macros 43 | // 44 | 45 | //////////////////////////////////////////////////////////////////////////////// 46 | // 47 | // types 48 | // 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | // 52 | // prototypes 53 | // 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // 57 | // variables 58 | // 59 | 60 | //////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // implementations 63 | // 64 | 65 | #endif // HYPERPLATFORM_LOG_PARSER_STDAFX_H_ 66 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/symbol_resolver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | #include "stdafx.h" 9 | #include "symbol_resolver.h" 10 | #include "utility.h" 11 | 12 | //////////////////////////////////////////////////////////////////////////////// 13 | // 14 | // macro utilities 15 | // 16 | 17 | // 'to_string' macro to support to switch between ANSI and UNICODE builds. 18 | #define SYMBOLRESOLVER_STRINGIFY(x) #x 19 | #define SYMBOLRESOLVER_TOSTRING(x) SYMBOLRESOLVER_STRINGIFY(x) 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // constants and macros 24 | // 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // 28 | // types 29 | // 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | // 33 | // prototypes 34 | // 35 | 36 | //////////////////////////////////////////////////////////////////////////////// 37 | // 38 | // variables 39 | // 40 | 41 | //////////////////////////////////////////////////////////////////////////////// 42 | // 43 | // implementations 44 | // 45 | 46 | /*_Use_decl_annotations_*/ SymbolResolver::SymbolResolver() 47 | : dbghelp_(std::experimental::make_unique_resource( 48 | ::LoadLibrary(TEXT("DbgHelp.dll")), &::FreeLibrary)), 49 | SymInitialize_(reinterpret_cast( 50 | ::GetProcAddress(dbghelp_, SYMBOLRESOLVER_TOSTRING(SymInitialize)))), 51 | SymCleanup_(reinterpret_cast( 52 | ::GetProcAddress(dbghelp_, SYMBOLRESOLVER_TOSTRING(SymCleanup)))), 53 | SymSetOptions_(reinterpret_cast( 54 | ::GetProcAddress(dbghelp_, SYMBOLRESOLVER_TOSTRING(SymSetOptions)))), 55 | SymGetOptions_(reinterpret_cast( 56 | ::GetProcAddress(dbghelp_, SYMBOLRESOLVER_TOSTRING(SymGetOptions)))), 57 | SymFromName_(reinterpret_cast( 58 | ::GetProcAddress(dbghelp_, SYMBOLRESOLVER_TOSTRING(SymFromName)))), 59 | SymFromAddr_(reinterpret_cast( 60 | ::GetProcAddress(dbghelp_, SYMBOLRESOLVER_TOSTRING(SymFromAddr)))), 61 | SymLoadModuleEx_(reinterpret_cast(::GetProcAddress( 62 | dbghelp_, SYMBOLRESOLVER_TOSTRING(SymLoadModuleEx)))), 63 | SymUnloadModule64_( 64 | reinterpret_cast(::GetProcAddress( 65 | dbghelp_, SYMBOLRESOLVER_TOSTRING(SymUnloadModule64)))), 66 | SymGetSearchPath_(reinterpret_cast(::GetProcAddress( 67 | dbghelp_, SYMBOLRESOLVER_TOSTRING(SymGetSearchPath)))), 68 | process_(std::experimental::make_unique_resource( 69 | ::GetCurrentProcess(), *const_cast(&SymCleanup_))) { 70 | if (!dbghelp_ || !SymInitialize_ || !SymCleanup_ || !SymSetOptions_ || 71 | !SymGetOptions_ || !SymFromName_ || !SymFromAddr_ || !SymLoadModuleEx_ || 72 | !SymUnloadModule64_ || !SymGetSearchPath_) { 73 | utility::ThrowRuntimeError( 74 | TEXT("At least one of DbgHelp APIs was not initialized.")); 75 | } 76 | 77 | TCHAR dbghelp_path[MAX_PATH]; 78 | ::GetModuleFileName(dbghelp_.get(), dbghelp_path, _countof(dbghelp_path)); 79 | 80 | const auto original_pptions = SymGetOptions_(); 81 | SymSetOptions_(original_pptions | SYMOPT_CASE_INSENSITIVE | SYMOPT_DEBUG | 82 | SYMOPT_UNDNAME | SYMOPT_AUTO_PUBLICS | SYMOPT_DEFERRED_LOADS); 83 | 84 | // Use a predefined symbols search path if _NT_SYMBOL_PATH is not registered 85 | const auto ret = 86 | ::GetEnvironmentVariable(TEXT("_NT_SYMBOL_PATH"), nullptr, 0); 87 | TCHAR *path = nullptr; 88 | if (ret == 0 && ::GetLastError() == ERROR_ENVVAR_NOT_FOUND) { 89 | path = TEXT(".;srv*.\\Symbols*http://msdl.microsoft.com/download/symbols"); 90 | } 91 | 92 | if (!SymInitialize_(process_, path, FALSE)) { 93 | utility::ThrowRuntimeError(TEXT("SymInitialize failed.")); 94 | } 95 | } 96 | 97 | // Load a module and return its base address 98 | _Use_decl_annotations_ std::uint64_t SymbolResolver::LoadModule( 99 | const std::basic_string &module_path) { 100 | return SymLoadModuleEx_(process_, nullptr, module_path.c_str(), nullptr, 0, 0, 101 | nullptr, 0); 102 | } 103 | 104 | // Unload a module 105 | _Use_decl_annotations_ bool SymbolResolver::UnloadModule( 106 | _In_ std::uint64_t BaseAddress) { 107 | return (SymUnloadModule64_(process_, BaseAddress) != FALSE); 108 | } 109 | 110 | // Return an offset of the symbols from the base address of the module 111 | _Use_decl_annotations_ std::uint64_t SymbolResolver::GetOffset( 112 | const std::basic_string &symbol_name) const { 113 | std::uint8_t buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)] = {}; 114 | auto symbol = reinterpret_cast(buffer); 115 | symbol->SizeOfStruct = sizeof(SYMBOL_INFO); 116 | symbol->MaxNameLen = MAX_SYM_NAME; 117 | 118 | if (!SymFromName_(process_, symbol_name.c_str(), symbol)) { 119 | return 0; 120 | } 121 | return symbol->Address - symbol->ModBase; 122 | } 123 | 124 | // Return a symbol name from the address or an empty string on error 125 | _Use_decl_annotations_ std::basic_string SymbolResolver::GetName( 126 | std::uint64_t address) const { 127 | std::uint8_t buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)] = {}; 128 | auto symbol = reinterpret_cast(buffer); 129 | symbol->SizeOfStruct = sizeof(SYMBOL_INFO); 130 | symbol->MaxNameLen = MAX_SYM_NAME; 131 | 132 | std::uint64_t displacement = 0; 133 | if (!SymFromAddr_(process_, address, &displacement, symbol)) { 134 | return {}; 135 | } 136 | if (!displacement) { 137 | return symbol->Name; 138 | } 139 | std::basic_stringstream stream; 140 | stream << "+0x" << std::nouppercase << std::hex << displacement; 141 | std::basic_string result(stream.str()); 142 | return symbol->Name + result; 143 | } 144 | 145 | // Delete these macros 146 | #undef SYMBOLRESOLVER_STRINGIFY 147 | #undef SYMBOLRESOLVER_TOSTRING 148 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/symbol_resolver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module declares interfaces of a SymbolResolver class. 7 | // 8 | 9 | #ifndef HYPERPLATFORM_LOG_PARSER_SYMBOL_RESOLVER_H_ 10 | #define HYPERPLATFORM_LOG_PARSER_SYMBOL_RESOLVER_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | // Support UNICODE build for DbgHelp.h 17 | #if defined(UNICODE) 18 | #define DBGHELP_TRANSLATE_TCHAR 19 | #endif 20 | 21 | // Note from MSDN: 22 | // All DbgHelp functions, such as this one, are single threaded. 23 | // Therefore, calls from more than one thread to this function will 24 | // likely result in unexpected behavior or memory corruption. 25 | // To avoid this, you must synchronize all concurrent calls 26 | // from more than one thread to this function. 27 | #pragma warning(push) 28 | #pragma warning(disable : 4091) 29 | #include 30 | #pragma warning(pop) 31 | 32 | // Original headers 33 | #include "scoped_resource/scope_exit.h" 34 | #include "scoped_resource/unique_resource.h" 35 | 36 | //////////////////////////////////////////////////////////////////////////////// 37 | // 38 | // macro utilities 39 | // 40 | 41 | //////////////////////////////////////////////////////////////////////////////// 42 | // 43 | // constants and macros 44 | // 45 | 46 | //////////////////////////////////////////////////////////////////////////////// 47 | // 48 | // types 49 | // 50 | 51 | class SymbolResolver { 52 | public: 53 | SymbolResolver(); 54 | 55 | std::uint64_t LoadModule(_In_ const std::basic_string &module_path); 56 | 57 | bool UnloadModule(_In_ std::uint64_t base_address); 58 | 59 | std::uint64_t GetOffset( 60 | _In_ const std::basic_string &symbol_name) const; 61 | 62 | std::basic_string GetName(_In_ std::uint64_t address) const; 63 | 64 | private: 65 | using SymInitializeType = decltype(&SymInitialize); 66 | using SymCleanupType = decltype(&SymCleanup); 67 | using SymSetOptionsType = decltype(&SymSetOptions); 68 | using SymGetOptionsType = decltype(&SymGetOptions); 69 | using SymFromNameType = decltype(&SymFromName); 70 | using SymFromAddrType = decltype(&SymFromAddr); 71 | using SymLoadModuleExType = decltype(&SymLoadModuleEx); 72 | using SymUnloadModule64Type = decltype(&SymUnloadModule64); 73 | using SymGetSearchPathType = decltype(&SymGetSearchPath); 74 | 75 | std::experimental::unique_resource 76 | dbghelp_; 77 | const SymInitializeType SymInitialize_; 78 | const SymCleanupType SymCleanup_; 79 | const SymSetOptionsType SymSetOptions_; 80 | const SymGetOptionsType SymGetOptions_; 81 | const SymFromNameType SymFromName_; 82 | const SymFromAddrType SymFromAddr_; 83 | const SymLoadModuleExType SymLoadModuleEx_; 84 | const SymUnloadModule64Type SymUnloadModule64_; 85 | const SymGetSearchPathType SymGetSearchPath_; 86 | const std::experimental::unique_resource process_; 87 | }; 88 | 89 | //////////////////////////////////////////////////////////////////////////////// 90 | // 91 | // prototypes 92 | // 93 | 94 | //////////////////////////////////////////////////////////////////////////////// 95 | // 96 | // variables 97 | // 98 | 99 | //////////////////////////////////////////////////////////////////////////////// 100 | // 101 | // implementations 102 | // 103 | 104 | #endif // HYPERPLATFORM_LOG_PARSER_SYMBOL_RESOLVER_H_ 105 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/targetver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef HYPERPLATFORM_LOG_PARSER_TARGETVER_H_ 6 | #define HYPERPLATFORM_LOG_PARSER_TARGETVER_H_ 7 | 8 | #include 9 | #define _WIN32_WINNT _WIN32_WINNT_WIN7 10 | #include 11 | 12 | #endif // HYPERPLATFORM_LOG_PARSER_TARGETVER_H_ 13 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/utility.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #include "stdafx.h" 10 | #include "utility.h" 11 | #include "scoped_resource/unique_resource.h" 12 | #include "scoped_resource/scope_exit.h" 13 | 14 | namespace utility { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | //////////////////////////////////////////////////////////////////////////////// 36 | // 37 | // variables 38 | // 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | // 42 | // implementations 43 | // 44 | 45 | // Return an error message of corresponding Win32 error code. 46 | _Use_decl_annotations_ std::basic_string GetWin32ErrorMessage( 47 | std::uint32_t error_code) { 48 | TCHAR *message_raw = nullptr; 49 | if (!::FormatMessage( 50 | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, 51 | error_code, LANG_USER_DEFAULT, reinterpret_cast(&message_raw), 52 | 0, nullptr)) { 53 | return TEXT(""); 54 | } 55 | if (!message_raw) { 56 | return TEXT(""); 57 | } 58 | auto message = std::experimental::make_unique_resource(std::move(message_raw), 59 | &LocalFree); 60 | 61 | const auto length = ::_tcslen(message.get()); 62 | if (!length) { 63 | return TEXT(""); 64 | } 65 | 66 | if (message.get()[length - 2] == TEXT('\r')) { 67 | message.get()[length - 2] = TEXT('\0'); 68 | } 69 | return message.get(); 70 | } 71 | 72 | // Display an error message with an error message of the current error code. 73 | _Use_decl_annotations_ void PrintErrorMessage( 74 | const std::basic_string &message) { 75 | const auto error_code = ::GetLastError(); 76 | const auto error_message = GetWin32ErrorMessage(error_code); 77 | ::_ftprintf_s(stderr, _T("%s : %lu(0x%08x) : %s\n"), message.c_str(), 78 | error_code, error_code, error_message.c_str()); 79 | } 80 | 81 | // Throw std::runtime_error with an error message. 82 | _Use_decl_annotations_ void ThrowRuntimeError( 83 | const std::basic_string &message) { 84 | const auto error_code = ::GetLastError(); 85 | const auto error_message = GetWin32ErrorMessage(error_code); 86 | char msg[1024]; 87 | #if UNICODE 88 | static const char kFormatString[] = "%S : %lu(0x%08x) : %S"; 89 | #else 90 | static const char kFormatString[] = "%s : %lu(0x%08x) : %s"; 91 | #endif 92 | StringCchPrintfA(msg, _countof(msg), kFormatString, message.c_str(), 93 | error_code, error_code, error_message.c_str()); 94 | throw std::runtime_error(msg); 95 | } 96 | 97 | _Use_decl_annotations_ std::wstring StrToWStr(const std::string &str) { 98 | typedef std::codecvt_utf8 convert_typeX; 99 | std::wstring_convert converterX; 100 | 101 | return converterX.from_bytes(str); 102 | } 103 | 104 | _Use_decl_annotations_ std::string WStrToStr(const std::wstring &Wstr) { 105 | typedef std::codecvt_utf8 convert_typeX; 106 | std::wstring_convert converterX; 107 | 108 | return converterX.to_bytes(Wstr); 109 | } 110 | 111 | } // End of namespace utility 112 | -------------------------------------------------------------------------------- /hyperplatform_log_parser/utility.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // 6 | // This module implements a SymbolResolver class. 7 | // 8 | 9 | #ifndef HYPERPLATFORM_LOG_PARSER_UTILITY_H_ 10 | #define HYPERPLATFORM_LOG_PARSER_UTILITY_H_ 11 | 12 | #include 13 | #include 14 | 15 | namespace utility { 16 | //////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // macro utilities 19 | // 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // constants and macros 24 | // 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // 28 | // types 29 | // 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | // 33 | // prototypes 34 | // 35 | 36 | std::basic_string GetWin32ErrorMessage(_In_ std::uint32_t error_code); 37 | 38 | void PrintErrorMessage(_In_ const std::basic_string &message); 39 | 40 | [[noreturn]] void ThrowRuntimeError( 41 | _In_ const std::basic_string &message); 42 | 43 | std::wstring StrToWStr(_In_ const std::string &str); 44 | 45 | std::string WStrToStr(_In_ const std::wstring &Wstr); 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | // 49 | // variables 50 | // 51 | 52 | //////////////////////////////////////////////////////////////////////////////// 53 | // 54 | // implementations 55 | // 56 | 57 | template 58 | std::vector> Split(_In_ const std::basic_string &str, 59 | _In_ T delim) { 60 | std::vector> elems; 61 | std::basic_stringstream ss(str); 62 | std::basic_string item; 63 | while (std::getline(ss, item, delim)) { 64 | elems.push_back(item); 65 | } 66 | return elems; 67 | } 68 | 69 | } // End of namespace utility 70 | 71 | #endif // HYPERPLATFORM_LOG_PARSER_UTILITY_H_ 72 | --------------------------------------------------------------------------------