├── .gitignore ├── IDA_ClassInformer.sln ├── Plugin ├── ClassInformerRes.qrc ├── Class_Informer.txt ├── IDA_ClassInformer_PlugIn.vcxproj ├── IDA_ClassInformer_PlugIn.vcxproj.filters ├── Main.cpp ├── Main.h ├── MainDialog.cpp ├── MainDialog.h ├── PropertySheet.props ├── RTTI.cpp ├── RTTI.h ├── StdAfx.h ├── Vftable.cpp ├── Vftable.h ├── banner.png ├── checkbox-checked.png ├── completed.ogg ├── dialog.ui ├── icon.png ├── progress-style.qss ├── style.qss ├── undname.h └── view-style.qss ├── README.md └── build.bat /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/visualstudio 3 | 4 | ### VisualStudio ### 5 | ## Ignore Visual Studio temporary files, build results, and 6 | ## files generated by popular Visual Studio add-ons. 7 | ## 8 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 9 | 10 | # User-specific files 11 | *.suo 12 | *.user 13 | *.userosscache 14 | *.sln.docstates 15 | 16 | # User-specific files (MonoDevelop/Xamarin Studio) 17 | *.userprefs 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | bld/ 27 | [Bb]in/ 28 | [Oo]bj/ 29 | [Ll]og/ 30 | 31 | # Visual Studio 2015 cache/options directory 32 | .vs/ 33 | # Uncomment if you have tasks that create the project's static files in wwwroot 34 | #wwwroot/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # .NET Core 50 | project.lock.json 51 | project.fragment.lock.json 52 | artifacts/ 53 | **/Properties/launchSettings.json 54 | 55 | *_i.c 56 | *_p.c 57 | *_i.h 58 | *.ilk 59 | *.meta 60 | *.obj 61 | *.pch 62 | *.pdb 63 | *.pgc 64 | *.pgd 65 | *.rsp 66 | *.sbr 67 | *.tlb 68 | *.tli 69 | *.tlh 70 | *.tmp 71 | *.tmp_proj 72 | *.log 73 | *.vspscc 74 | *.vssscc 75 | .builds 76 | *.pidb 77 | *.svclog 78 | *.scc 79 | 80 | # Chutzpah Test files 81 | _Chutzpah* 82 | 83 | # Visual C++ cache files 84 | ipch/ 85 | *.aps 86 | *.ncb 87 | *.opendb 88 | *.opensdf 89 | *.sdf 90 | *.cachefile 91 | *.VC.db 92 | *.VC.VC.opendb 93 | 94 | # Visual Studio profiler 95 | *.psess 96 | *.vsp 97 | *.vspx 98 | *.sap 99 | 100 | # TFS 2012 Local Workspace 101 | $tf/ 102 | 103 | # Guidance Automation Toolkit 104 | *.gpState 105 | 106 | # ReSharper is a .NET coding add-in 107 | _ReSharper*/ 108 | *.[Rr]e[Ss]harper 109 | *.DotSettings.user 110 | 111 | # JustCode is a .NET coding add-in 112 | .JustCode 113 | 114 | # TeamCity is a build add-in 115 | _TeamCity* 116 | 117 | # DotCover is a Code Coverage Tool 118 | *.dotCover 119 | 120 | # Visual Studio code coverage results 121 | *.coverage 122 | *.coveragexml 123 | 124 | # NCrunch 125 | _NCrunch_* 126 | .*crunch*.local.xml 127 | nCrunchTemp_* 128 | 129 | # MightyMoose 130 | *.mm.* 131 | AutoTest.Net/ 132 | 133 | # Web workbench (sass) 134 | .sass-cache/ 135 | 136 | # Installshield output folder 137 | [Ee]xpress/ 138 | 139 | # DocProject is a documentation generator add-in 140 | DocProject/buildhelp/ 141 | DocProject/Help/*.HxT 142 | DocProject/Help/*.HxC 143 | DocProject/Help/*.hhc 144 | DocProject/Help/*.hhk 145 | DocProject/Help/*.hhp 146 | DocProject/Help/Html2 147 | DocProject/Help/html 148 | 149 | # Click-Once directory 150 | publish/ 151 | 152 | # Publish Web Output 153 | *.[Pp]ublish.xml 154 | *.azurePubxml 155 | # TODO: Uncomment the next line to ignore your web deploy settings. 156 | # By default, sensitive information, such as encrypted password 157 | # should be stored in the .pubxml.user file. 158 | #*.pubxml 159 | *.pubxml.user 160 | *.publishproj 161 | 162 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 163 | # checkin your Azure Web App publish settings, but sensitive information contained 164 | # in these scripts will be unencrypted 165 | PublishScripts/ 166 | 167 | # NuGet Packages 168 | *.nupkg 169 | # The packages folder can be ignored because of Package Restore 170 | **/packages/* 171 | # except build/, which is used as an MSBuild target. 172 | !**/packages/build/ 173 | # Uncomment if necessary however generally it will be regenerated when needed 174 | #!**/packages/repositories.config 175 | # NuGet v3's project.json files produces more ignorable files 176 | *.nuget.props 177 | *.nuget.targets 178 | 179 | # Microsoft Azure Build Output 180 | csx/ 181 | *.build.csdef 182 | 183 | # Microsoft Azure Emulator 184 | ecf/ 185 | rcf/ 186 | 187 | # Windows Store app package directories and files 188 | AppPackages/ 189 | BundleArtifacts/ 190 | Package.StoreAssociation.xml 191 | _pkginfo.txt 192 | 193 | # Visual Studio cache files 194 | # files ending in .cache can be ignored 195 | *.[Cc]ache 196 | # but keep track of directories ending in .cache 197 | !*.[Cc]ache/ 198 | 199 | # Others 200 | ClientBin/ 201 | ~$* 202 | *~ 203 | *.dbmdl 204 | *.dbproj.schemaview 205 | *.jfm 206 | *.pfx 207 | *.publishsettings 208 | orleans.codegen.cs 209 | 210 | # Since there are multiple workflows, uncomment next line to ignore bower_components 211 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 212 | #bower_components/ 213 | 214 | # RIA/Silverlight projects 215 | Generated_Code/ 216 | 217 | # Backup & report files from converting an old project file 218 | # to a newer Visual Studio version. Backup files are not needed, 219 | # because we have git ;-) 220 | _UpgradeReport_Files/ 221 | Backup*/ 222 | UpgradeLog*.XML 223 | UpgradeLog*.htm 224 | 225 | # SQL Server files 226 | *.mdf 227 | *.ldf 228 | *.ndf 229 | 230 | # Business Intelligence projects 231 | *.rdl.data 232 | *.bim.layout 233 | *.bim_*.settings 234 | 235 | # Microsoft Fakes 236 | FakesAssemblies/ 237 | 238 | # GhostDoc plugin setting file 239 | *.GhostDoc.xml 240 | 241 | # Node.js Tools for Visual Studio 242 | .ntvs_analysis.dat 243 | node_modules/ 244 | 245 | # Typescript v1 declaration files 246 | typings/ 247 | 248 | # Visual Studio 6 build log 249 | *.plg 250 | 251 | # Visual Studio 6 workspace options file 252 | *.opt 253 | 254 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 255 | *.vbw 256 | 257 | # Visual Studio LightSwitch build output 258 | **/*.HTMLClient/GeneratedArtifacts 259 | **/*.DesktopClient/GeneratedArtifacts 260 | **/*.DesktopClient/ModelManifest.xml 261 | **/*.Server/GeneratedArtifacts 262 | **/*.Server/ModelManifest.xml 263 | _Pvt_Extensions 264 | 265 | # Paket dependency manager 266 | .paket/paket.exe 267 | paket-files/ 268 | 269 | # FAKE - F# Make 270 | .fake/ 271 | 272 | # JetBrains Rider 273 | .idea/ 274 | *.sln.iml 275 | 276 | # CodeRush 277 | .cr/ 278 | 279 | # Python Tools for Visual Studio (PTVS) 280 | __pycache__/ 281 | *.pyc 282 | 283 | # Cake - Uncomment if you are using it 284 | # tools/** 285 | # !tools/packages.config 286 | 287 | # Telerik's JustMock configuration file 288 | *.jmconfig 289 | 290 | # BizTalk build output 291 | *.btp.cs 292 | *.btm.cs 293 | *.odx.cs 294 | *.xsd.cs 295 | 296 | ### VisualStudio Patch ### 297 | # By default, sensitive information, such as encrypted password 298 | # should be stored in the .pubxml.user file. 299 | 300 | # End of https://www.gitignore.io/api/visualstudio 301 | 302 | Plugin/GeneratedFiles 303 | Plugin/PropertySheet.props 304 | -------------------------------------------------------------------------------- /IDA_ClassInformer.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}") = "PlugIn", "Plugin\IDA_ClassInformer_PlugIn.vcxproj", "{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug64|x64 = Debug64|x64 12 | Release|x64 = Release|x64 13 | Release64|x64 = Release64|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug|x64.ActiveCfg = Debug|x64 17 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug|x64.Build.0 = Debug|x64 18 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug64|x64.ActiveCfg = Debug64|x64 19 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug64|x64.Build.0 = Debug64|x64 20 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release|x64.ActiveCfg = Release|x64 21 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release|x64.Build.0 = Release|x64 22 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release64|x64.ActiveCfg = Release64|x64 23 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release64|x64.Build.0 = Release64|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /Plugin/ClassInformerRes.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | banner.png 4 | icon.png 5 | completed.ogg 6 | checkbox-checked.png 7 | progress-style.qss 8 | style.qss 9 | view-style.qss 10 | 11 | 12 | -------------------------------------------------------------------------------- /Plugin/Class_Informer.txt: -------------------------------------------------------------------------------- 1 | 2 | Class Informer: 3 | =========================================================== 4 | IDA Pro class vftable finder, namer, fixer, lister plug-in. 5 | Version 2.6, July 2018 6 | By Sirmabus 7 | 8 | https://sourceforge.net/projects/classinformer/ 9 | http://www.macromonkey.com/bb/index.php/topic,13.0.html 10 | 11 | --------------------------------------------------------- 12 | Scans MSVC target IDBs for vftables with C++ RTTI data. 13 | Places structures, names, labels, and comments to class vftables 14 | (Virtual Function Table) to aid reverse engineering. 15 | Also further assists by defining and associating known data structures. 16 | Creates a list window for browsing by object name. 17 | 18 | RTTI ("Run-Time Type Identification"): 19 | http://en.wikipedia.org/wiki/RTTI 20 | 21 | It's currently targeted for Microsoft Visual C++ complied binaries only. 22 | Unpredictable results if used on other targets. 23 | 24 | Based off article by Igor Skochinsky: 25 | http://www.openrce.org/articles/full_view/23 26 | Updated 27 | http://www.hexblog.com/wp-content/uploads/2012/06/ 28 | Recon-2012-Skochinsky-Compiler-Internals.pdf 29 | 30 | 31 | -- [Install] -------------------------------------------- 32 | Copy the plug-in to your IDA Pro "plugins" directory. 33 | Then edit your "..\plugins\plugins.cfg" to setup with a hotkey. 34 | 35 | IE: Add these two lines: 36 | ; Sirmabus "Class Informer" plug-in 37 | Class-Informer IDA_ClassInformer_PlugIn.plw Alt-2 0 38 | 39 | See IDA documentation for more on installing and using plug-ins. 40 | 41 | 42 | -- [How to run it] -------------------------------------- 43 | Invoke as usual in IDA with an assigned hot key, or through IDA's 44 | "Edit->Plugins" menu. 45 | 46 | Dialog Options: 47 | "Place structures": Uncheck this if you don't want RTTI data structures to be 48 | defined and placed; instead individual data elements will be cleaned up and 49 | placed with additional comments. 50 | 51 | "Process static initializers & terminators": If unchecked the processing of 52 | static ctor and dtor tables will be skipped. 53 | 54 | "Overwrite anterior comments": Check if you want existing anterior (above) 55 | comments be erased and overwritten. Class Informer will place separation and 56 | information comments above vftables, etc. Default unchecked. 57 | 58 | "Audio on completion": Uncheck this if you don't want any audio completion 59 | sound. 60 | 61 | On completion a list window will come up showing any found vftables and 62 | relevant class information. 63 | Lines with multiple inheritance that are not the main class will be colored 64 | gray. 65 | Click on a line to jump to it's vftable. 66 | 67 | 68 | Example list output: 69 | 0046769C 077 CEdit:CWnd, CCmdTarget, CObject; (SI) 70 | 71 | This is: vftable address, method count, and class hierarchy ended with some 72 | additional class info. 73 | To make things easier to read, all known type names are considered to be a 74 | "class" unless explicitly proceeded with "struct" to indicate "structure" type. 75 | 76 | The addition info at the end: 77 | "(SI)" single inheritance hierarchy, "(MI)" multiple inheritance, 78 | "(VI)" virtual inheritance, or "(MI VI)" multiple virtual inheritance. 79 | 80 | 81 | -- [Design] --------------------------------------------- 82 | 83 | I read Igor Skochinsky's excellent article: 84 | "Reversing Microsoft Visual C++". And ran some his IDC accompanying scripts. 85 | I was amazed at how well it worked on identifying vftables with a gold mine of 86 | type information and how it helped clean up an IDB by defining data structures. 87 | 88 | But the scripts had several problems and I wanted to put it into a plug-in 89 | anyhow for speed, flexibility, and to build as a general test bed for class 90 | information and research. 91 | 92 | I originally I had in mind some sort of automatic object member naming. 93 | But after doing real world tests I found it wasn't so useful. 94 | 95 | For my RE work I really just need to see these classes by name, and then where 96 | to find them for closer examination. Then adding automatic fixing and labeling 97 | of ctor and dtor tables is a bonus. 98 | 99 | As of version 2.0 switched to a different RTTI finding/scanning scheme. 100 | No longer scanning and locating vftables first. Now "Complete Object Locator" 101 | are located directly. This leads to more accuracy; less vftables are missed. 102 | 103 | 104 | -- [Thanks and Appreciation] ---------------------------- 105 | 106 | To Igor Skochinsky for the RTTI information and inspiration. 107 | To "sh!ft" for the source code to his version, and ideas that lead to the new 108 | improved scanning scheme. 109 | To "jlnsrk" for the reversed 64 bit RTTI version information. 110 | To Chris Eagle for mentioning Class Informer in his book: 111 | "The IDA Pro Book: The Unofficial Guide to the World's Most Popular 112 | Disassembler" 113 | 114 | 115 | -- [History] -------------------------------------------- 116 | 117 | 2.6 - 1) Updated to IDA SDK 7.1 118 | 119 | 2.5 - 1) Updated to IDA 7 and MSVC 2017. 120 | Some of the changes for this: 121 | Doesn't place types/structs, nor names or comments if they already exist. 122 | Now the scanning role is more of looking for and fixing things IDA might have missed. 123 | 2) Now catches a rare secondary case where an assumed member function is unresolved bytes to 124 | increase the accuracy of vftable member count scanning. 125 | 126 | 2.4 - 1) Now scans all "DATA" type segments. Before would only scan the first 127 | ".data" and ".rdata" segments. 128 | 2) Added segment select option to plug-in dialog. 129 | 130 | 2.2 - 1) Updated to IDA SDK 6.9 and MSVC 2015. 131 | 132 | 2.1 - 1) Removed the "IDA updating, please wait.." wait for IDA to update thing 133 | at the end of processing to fix an ocassional hang. 134 | 2) Updated to IDA SDK 6.8 version. 135 | 136 | 2.0 - A complete overhaul of the entire plug-in. 137 | 1) Updated namings to better match that of Microsoft's internals. 138 | 2) Moved custom type creation out of the init() call; now gets created 139 | only on the first run and only if the "Place structures" option is 140 | checked. 141 | 3) Descriptive comments are now placed on C/C++ initializer and 142 | terminator table start and end points. 143 | 4) The UI is now a custom Qt one with "material design" elements. 144 | 5) Added a 64bit (32bit IDA's "__E64__") version. 145 | 6) The RTCI (rare MS MFC type) support was removed. 146 | 7) Now locates vftables by RTTI "Complete Object Locator" structures 147 | directly. 148 | 8) Updated to IDA SDK 6.7 version. 149 | 9) No longer has a default hotkey. Set your own using "plugins.cfg". 150 | 10) Updated and improved the static ctor/dtor processing. 151 | 152 | 1.06 - 1) Added persistent vftable list storage. 153 | 2) Removed the many unnecessary "autoWait()" calls that caused a bit 154 | of a slow down. 155 | 3) Fixed broken and updated some custom UI elements. 156 | 4) Fixed the multi-segment select feature for the non-QT version and 157 | added a working setup for the QT version too. For QT, after desired 158 | segments are selected right click on the list and do "Select" 159 | followed by the "Okay" button. 160 | 5) Added the ".data" segment to the default data search since vftables 161 | are often located there (in addition to ".rdata"). 162 | 163 | 1.05 - 1) The problem with the plug-in not being ready on invocation was fixed 164 | by returning PLUGIN_KEEP on init to stay resident. 165 | 2) The fix in 1.04 didn't quite do it for structure placement problems. 166 | In particular there remains a run on problem in IDA when marking some 167 | areas "unknown"; these "do_unknown()" calls have been removed and 168 | each structure element is individually placed one by one before 169 | attempting to place the actual assorted structures. 170 | 171 | 1.04 - 1) Now ensures RTTI type name strings are set. 172 | 173 | 1.03 - 1) Added check and warning message for invalid start and end addresses 174 | with "_initterm" type static/global ctor & dtor tables. 175 | Would cause a negative count run-on condition that could trample over 176 | a large data area. 177 | 2) UI customizations auto-disabled when using IDA Qt version. 178 | 3) Current IDA view is refreshed on completion to show changes. 179 | 4) Fixed a stall that could result from repeated failed attempts at an 180 | RTTI type placement. Plus fixed the pattern for these so they could 181 | be properly placed. 182 | 183 | 1.02 - 1) Added user code and data segment selector. 184 | Allows user to select multiple data and code segments instead of the 185 | default of ".text" and ".rdata" by name. 186 | For those rare executable targets that have multiple code sections, 187 | and, or, unpacked executables with mixed segments, etc. 188 | 2) Added config option for verbose output to the debugger channel. 189 | 3) Improved overall processing speed. 190 | 4) Since there can multiple instances of the same class or structure, 191 | and IDA names must be unique all duplicate names are now serialized. 192 | More things labeled, and no more "duplicate name" warning spam. 193 | Note: Effects only label names, commented names are not altered 194 | 5) Updated to IDA SDK 5.5 195 | 6) Added links to Sirmabus IDA plug-ins support forum. 196 | 197 | 1.01 - 1) No longer pops up an error and exits IDA when an incompatible IDB is 198 | loaded. Just displays a "not loaded" log message now. 199 | 2) Fixed IDA tab page update issue. 200 | 3) Now built with IDA SDK 5.4, and tested with IDA 5.4. 201 | 4) Fixed incorrect string placement in the RTTI type info struct. 202 | Now the structures are right which make a cleaner DB. 203 | This was a major bottleneck that caused the structure placement to be 204 | about 36x slower, now only about 1x. 205 | 5) Fixed some misspellings. 206 | 207 | -- [TODO] ----------------------------------------------- 208 | 1) Add support for more compilers and platforms. 209 | 2) Add distinction for "pre-terminators" and C/C++ _initterm type tables. 210 | 3) Fix cases where _initterm() are register calls. 211 | 212 | Find a problem? Please make a ticket here: 213 | https://sourceforge.net/p/classinformer/tickets/ 214 | 215 | 216 | -- [License] ----------------------------------------------- 217 | http://www.opensource.org/licenses/mit-license.php 218 | The MIT License (MIT) 219 | Copyright(c) 2009 to present Sirmabus. 220 | 221 | Permission is hereby granted, free of charge, to any person obtaining a copy 222 | of this software and associated documentation files (the "Software"), to deal 223 | in the Software without restriction, including without limitation the rights 224 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 225 | copies of the Software, and to permit persons to whom the Software is 226 | furnished to do so, subject to the following conditions: 227 | 228 | The above copyright notice and this permission notice shall be included in 229 | all copies or substantial portions of the Software. 230 | 231 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 232 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 233 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 234 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 235 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 236 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 237 | THE SOFTWARE. 238 | -------------------------------------------------------------------------------- /Plugin/IDA_ClassInformer_PlugIn.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug64 6 | Win32 7 | 8 | 9 | Debug64 10 | x64 11 | 12 | 13 | Debug 14 | Win32 15 | 16 | 17 | Debug 18 | x64 19 | 20 | 21 | Release64 22 | Win32 23 | 24 | 25 | Release64 26 | x64 27 | 28 | 29 | Release 30 | Win32 31 | 32 | 33 | Release 34 | x64 35 | 36 | 37 | 38 | PlugIn 39 | Qt4VSv1.0 40 | {DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE} 41 | 8.1 42 | 43 | 44 | 45 | DynamicLibrary 46 | v140 47 | false 48 | NotSet 49 | 50 | 51 | DynamicLibrary 52 | v140 53 | false 54 | NotSet 55 | 56 | 57 | DynamicLibrary 58 | v140 59 | false 60 | NotSet 61 | 62 | 63 | DynamicLibrary 64 | v140 65 | false 66 | NotSet 67 | 68 | 69 | DynamicLibrary 70 | v140 71 | false 72 | NotSet 73 | 74 | 75 | DynamicLibrary 76 | v140 77 | false 78 | NotSet 79 | 80 | 81 | DynamicLibrary 82 | v140 83 | false 84 | NotSet 85 | 86 | 87 | DynamicLibrary 88 | v140 89 | false 90 | NotSet 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | <_ProjectFileVersion>12.0.30501.0 138 | 139 | 140 | $(SolutionDir)Plugin\$(Configuration)\ 141 | $(OutDir) 142 | true 143 | false 144 | false 145 | .pLW 146 | IDA_ClassInformer_PlugIn 147 | 148 | 149 | true 150 | false 151 | false 152 | .dll 153 | IDA_ClassInformer_PlugIn 154 | 155 | 156 | $(SolutionDir)Plugin\$(Configuration)\ 157 | $(OutDir) 158 | true 159 | false 160 | false 161 | .P64 162 | IDA_ClassInformer_PlugIn 163 | 164 | 165 | true 166 | false 167 | false 168 | .dll 169 | IDA_ClassInformer_PlugIn64 170 | 171 | 172 | $(SolutionDir)Plugin\$(Configuration)\ 173 | $(OutDir) 174 | true 175 | false 176 | false 177 | .pLW 178 | IDA_ClassInformer_PlugIn 179 | 180 | 181 | true 182 | false 183 | false 184 | .dll 185 | IDA_ClassInformer_PlugIn 186 | 187 | 188 | $(SolutionDir)Plugin\$(Configuration)\ 189 | $(OutDir) 190 | true 191 | false 192 | false 193 | .P64 194 | IDA_ClassInformer_PlugIn 195 | 196 | 197 | true 198 | false 199 | false 200 | .dll 201 | IDA_ClassInformer_PlugIn64 202 | 203 | 204 | 205 | NDEBUG;%(PreprocessorDefinitions) 206 | true 207 | true 208 | Win32 209 | .\Release/IDA_RTTI_Informer_PlugIn.tlb 210 | 211 | 212 | 213 | Full 214 | AnySuitable 215 | true 216 | Speed 217 | true 218 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 219 | WIN32;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions) 220 | true 221 | MultiThreadedDLL 222 | false 223 | false 224 | NotSet 225 | NotUsing 226 | NoListing 227 | $(IntDir) 228 | $(IntDir) 229 | $(IntDir)vc$(PlatformToolsetVersion).pdb 230 | Level3 231 | true 232 | Cdecl 233 | Async 234 | 235 | 236 | NDEBUG;%(PreprocessorDefinitions) 237 | 0x0409 238 | 239 | 240 | /EXPORT:PLUGIN %(AdditionalOptions) 241 | ida.lib;Winmm.lib;%(AdditionalDependencies) 242 | $(OutDir)$(TargetFileName) 243 | true 244 | $(IDADIR)\idasdk\lib\x86_win_vc_32;$(IDADIR)\idasdk\lib\x86_win_qt;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;%(AdditionalLibraryDirectories) 245 | 246 | Windows 247 | true 248 | UseLinkTimeCodeGeneration 249 | false 250 | 251 | 252 | MachineX86 253 | true 254 | 255 | 256 | true 257 | $(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc 258 | 259 | 260 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 261 | 262 | 263 | 264 | 265 | NDEBUG;%(PreprocessorDefinitions) 266 | true 267 | true 268 | .\Release/IDA_RTTI_Informer_PlugIn.tlb 269 | 270 | 271 | 272 | 273 | Full 274 | AnySuitable 275 | true 276 | Speed 277 | true 278 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk70\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 279 | __X64__;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions) 280 | true 281 | MultiThreadedDLL 282 | false 283 | false 284 | NotSet 285 | NotUsing 286 | NoListing 287 | $(IntDir) 288 | $(IntDir) 289 | $(IntDir)vc$(PlatformToolsetVersion).pdb 290 | Level3 291 | true 292 | Cdecl 293 | Async 294 | 295 | 296 | NDEBUG;%(PreprocessorDefinitions) 297 | 0x0409 298 | 299 | 300 | /EXPORT:PLUGIN %(AdditionalOptions) 301 | ida.lib;Winmm.lib;SupportLib.lib;SupportLib.LiB;WaitBoxEx64.lib;IdaOggPlayer.LiB;%(AdditionalDependencies) 302 | $(OutDir)$(TargetFileName) 303 | true 304 | $(IDADIR)\idasdk70\lib\x64_win_vc_32;$(IDADIR)\idasdk70\lib\x64_win_qt;$(QTDIR)\lib;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib 305 | 306 | 307 | Windows 308 | true 309 | UseLinkTimeCodeGeneration 310 | false 311 | 312 | 313 | 314 | 315 | true 316 | 317 | 318 | true 319 | $(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc 320 | 321 | 322 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 323 | 324 | 325 | 326 | 327 | NDEBUG;%(PreprocessorDefinitions) 328 | true 329 | true 330 | Win32 331 | .\Release/IDA_RTTI_Informer_PlugIn.tlb 332 | 333 | 334 | 335 | 336 | Full 337 | AnySuitable 338 | true 339 | Speed 340 | true 341 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 342 | __EA64__;WIN32;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions) 343 | true 344 | MultiThreadedDLL 345 | false 346 | false 347 | NotSet 348 | NotUsing 349 | NoListing 350 | $(IntDir) 351 | $(IntDir) 352 | $(IntDir)vc$(PlatformToolsetVersion).pdb 353 | Level3 354 | true 355 | Cdecl 356 | Async 357 | 358 | 359 | NDEBUG;%(PreprocessorDefinitions) 360 | 0x0409 361 | 362 | 363 | /EXPORT:PLUGIN %(AdditionalOptions) 364 | ida.lib;Winmm.lib;%(AdditionalDependencies) 365 | $(OutDir)$(TargetFileName) 366 | true 367 | $(IDADIR)\idasdk\lib\x86_win_vc_64;$(IDADIR)\idasdk\lib\x86_win_qt;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;%(AdditionalLibraryDirectories) 368 | 369 | 370 | Windows 371 | true 372 | UseLinkTimeCodeGeneration 373 | false 374 | 375 | 376 | 377 | 378 | MachineX86 379 | true 380 | 381 | 382 | true 383 | $(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc 384 | 385 | 386 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 387 | 388 | 389 | 390 | 391 | NDEBUG;%(PreprocessorDefinitions) 392 | true 393 | true 394 | .\Release/IDA_RTTI_Informer_PlugIn.tlb 395 | 396 | 397 | 398 | 399 | Full 400 | AnySuitable 401 | true 402 | Speed 403 | true 404 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk70\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 405 | __EA64__;__X64__;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions) 406 | true 407 | MultiThreadedDLL 408 | false 409 | false 410 | NotSet 411 | NotUsing 412 | NoListing 413 | $(IntDir) 414 | $(IntDir) 415 | $(IntDir)vc$(PlatformToolsetVersion).pdb 416 | Level3 417 | true 418 | Cdecl 419 | Async 420 | 421 | 422 | NDEBUG;%(PreprocessorDefinitions) 423 | 0x0409 424 | 425 | 426 | /EXPORT:PLUGIN %(AdditionalOptions) 427 | ida.lib;Winmm.lib;SupportLib64.LiB;WaitBoxEx64.lib;IdaOggPlayer64.LiB;SegSelect64.LiB;%(AdditionalDependencies) 428 | $(OutDir)$(TargetFileName) 429 | true 430 | $(IDADIR)\idasdk70\lib\x64_win_vc_64;$(IDADIR)\idasdk70\lib\x64_win_qt;$(QTDIR)\lib;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib 431 | 432 | 433 | Windows 434 | true 435 | UseLinkTimeCodeGeneration 436 | false 437 | 438 | 439 | 440 | 441 | true 442 | 443 | 444 | true 445 | $(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc 446 | 447 | 448 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 449 | 450 | 451 | 452 | 453 | _DEBUG;%(PreprocessorDefinitions) 454 | true 455 | true 456 | Win32 457 | .\Debug/IDA_RTTI_Informer_PlugIn.tlb 458 | 459 | 460 | 461 | Disabled 462 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 463 | _DEVMODE;_DEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions) 464 | false 465 | EnableFastChecks 466 | MultiThreadedDebugDLL 467 | NotUsing 468 | $(IntDir) 469 | $(IntDir) 470 | $(IntDir)vc$(PlatformToolsetVersion).pdb 471 | Level3 472 | true 473 | EditAndContinue 474 | Cdecl 475 | Async 476 | 477 | 478 | _DEBUG;%(PreprocessorDefinitions) 479 | 0x0409 480 | 481 | 482 | /EXPORT:PLUGIN %(AdditionalOptions) 483 | ida.lib;Winmm.lib;%(AdditionalDependencies) 484 | $(OutDir)$(TargetFileName) 485 | true 486 | $(IDADIR)\idasdk\lib\x86_win_vc_32;$(IDADIR)\idasdk\lib\x86_win_qt;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;%(AdditionalLibraryDirectories) 487 | true 488 | 489 | Windows 490 | false 491 | 492 | 493 | MachineX86 494 | 495 | 496 | true 497 | $(SolutionDir)Debug\IDA_RTTI_Informer_PlugIn.bsc 498 | 499 | 500 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 501 | 502 | 503 | 504 | 505 | _DEBUG;%(PreprocessorDefinitions) 506 | true 507 | true 508 | .\Debug/IDA_RTTI_Informer_PlugIn.tlb 509 | 510 | 511 | 512 | 513 | Disabled 514 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk70\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 515 | _DEVMODE;_DEBUG;__X64__;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;__X64__;%(PreprocessorDefinitions) 516 | false 517 | EnableFastChecks 518 | MultiThreadedDebugDLL 519 | NotUsing 520 | $(IntDir) 521 | $(IntDir) 522 | $(IntDir)vc$(PlatformToolsetVersion).pdb 523 | Level3 524 | true 525 | ProgramDatabase 526 | Cdecl 527 | Async 528 | 529 | 530 | _DEBUG;%(PreprocessorDefinitions) 531 | 0x0409 532 | 533 | 534 | /EXPORT:PLUGIN %(AdditionalOptions) 535 | ida.lib;Winmm.lib;SupportLibD.LiB;WaitBoxExD64.lib;IdaOggPlayerD.LiB;%(AdditionalDependencies) 536 | $(OutDir)$(TargetFileName) 537 | true 538 | $(IDADIR)\idasdk70\lib\x64_win_vc_32;$(IDADIR)\idasdk70\lib\x64_win_qt;$(QTDIR)\lib;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalLibraryDirectories) 539 | true 540 | 541 | 542 | Windows 543 | false 544 | 545 | 546 | 547 | 548 | 549 | 550 | true 551 | $(SolutionDir)Debug\IDA_RTTI_Informer_PlugIn.bsc 552 | 553 | 554 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 555 | 556 | 557 | 558 | 559 | _DEBUG;%(PreprocessorDefinitions) 560 | true 561 | true 562 | Win32 563 | .\Debug/IDA_RTTI_Informer_PlugIn.tlb 564 | 565 | 566 | 567 | 568 | Disabled 569 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 570 | _DEVMODE;__EA64__;_DEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions) 571 | false 572 | EnableFastChecks 573 | MultiThreadedDebugDLL 574 | NotUsing 575 | $(IntDir) 576 | $(IntDir) 577 | $(IntDir)vc$(PlatformToolsetVersion).pdb 578 | Level3 579 | true 580 | EditAndContinue 581 | Cdecl 582 | Async 583 | 584 | 585 | _DEBUG;%(PreprocessorDefinitions) 586 | 0x0409 587 | 588 | 589 | /EXPORT:PLUGIN %(AdditionalOptions) 590 | ida.lib;Winmm.lib;%(AdditionalDependencies) 591 | $(OutDir)$(TargetFileName) 592 | true 593 | $(IDADIR)\idasdk\lib\x86_win_vc_64;$(IDADIR)\idasdk\lib\x86_win_qt;$(IDASUPPORT)\IDA_WaitEx;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;%(AdditionalLibraryDirectories) 594 | true 595 | 596 | 597 | Windows 598 | false 599 | 600 | 601 | 602 | 603 | MachineX86 604 | 605 | 606 | true 607 | $(SolutionDir)Debug\IDA_RTTI_Informer_PlugIn.bsc 608 | 609 | 610 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 611 | 612 | 613 | 614 | 615 | _DEBUG;%(PreprocessorDefinitions) 616 | true 617 | true 618 | .\Debug/IDA_RTTI_Informer_PlugIn.tlb 619 | 620 | 621 | 622 | 623 | Disabled 624 | .;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDADIR)\idasdk70\include;$(QTDIR)\include;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib;%(AdditionalIncludeDirectories) 625 | _DEVMODE;__EA64__;_DEBUG;__X64__;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions) 626 | false 627 | EnableFastChecks 628 | MultiThreadedDebugDLL 629 | NotUsing 630 | $(IntDir) 631 | $(IntDir) 632 | $(IntDir)vc$(PlatformToolsetVersion).pdb 633 | Level3 634 | true 635 | ProgramDatabase 636 | Cdecl 637 | Async 638 | 639 | 640 | _DEBUG;%(PreprocessorDefinitions) 641 | 0x0409 642 | 643 | 644 | /EXPORT:PLUGIN %(AdditionalOptions) 645 | ida.lib;Winmm.lib;SupportLibD64.LiB;WaitBoxExD64.lib;IdaOggPlayerD64.LiB;SegSelect64D.LiB;%(AdditionalDependencies) 646 | $(OutDir)$(TargetFileName) 647 | true 648 | $(IDADIR)\idasdk70\lib\x64_win_vc_64;$(IDADIR)\idasdk70\lib\x64_win_qt;$(QTDIR)\lib;$(IDASUPPORT)\IDA_WaitBoxEx-7.0;$(IDASUPPORT)\IDA_SegmentSelect;$(IDASUPPORT)\IDA_OggPlayer;$(IDASUPPORT)\SupportLib 649 | true 650 | 651 | 652 | Windows 653 | false 654 | 655 | 656 | 657 | 658 | 659 | 660 | true 661 | $(SolutionDir)Debug\IDA_RTTI_Informer_PlugIn.bsc 662 | 663 | 664 | copy "$(OutDir)$(TargetFileName)" "$(IDADIR)\plugins" 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | Performing Custom Build Tools 678 | Performing Custom Build Tools 679 | Performing Custom Build Tools 680 | Performing Custom Build Tools 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | Performing Custom Build Tools 706 | Performing Custom Build Tools 707 | Performing Custom Build Tools 708 | Performing Custom Build Tools 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | Performing Custom Build Tools 736 | Performing Custom Build Tools 737 | Performing Custom Build Tools 738 | Performing Custom Build Tools 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | Performing Custom Build Tools 764 | Performing Custom Build Tools 765 | Performing Custom Build Tools 766 | Performing Custom Build Tools 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | Performing Custom Build Tools 794 | Performing Custom Build Tools 795 | Performing Custom Build Tools 796 | Performing Custom Build Tools 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | Performing Custom Build Tools 822 | Performing Custom Build Tools 823 | Performing Custom Build Tools 824 | Performing Custom Build Tools 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | Performing Custom Build Tools 852 | Performing Custom Build Tools 853 | Performing Custom Build Tools 854 | Performing Custom Build Tools 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | Performing Custom Build Tools 880 | Performing Custom Build Tools 881 | Performing Custom Build Tools 882 | Performing Custom Build Tools 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | true 904 | true 905 | true 906 | true 907 | true 908 | true 909 | 910 | 911 | true 912 | true 913 | true 914 | true 915 | true 916 | true 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | true 938 | true 939 | true 940 | true 941 | true 942 | true 943 | 944 | 945 | true 946 | true 947 | true 948 | true 949 | true 950 | true 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | Performing Custom Build Tools 968 | Performing Custom Build Tools 969 | Performing Custom Build Tools 970 | Performing Custom Build Tools 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | Performing Custom Build Tools 996 | Performing Custom Build Tools 997 | Performing Custom Build Tools 998 | Performing Custom Build Tools 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | Performing Custom Build Tools 1026 | Performing Custom Build Tools 1027 | Performing Custom Build Tools 1028 | Performing Custom Build Tools 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | Performing Custom Build Tools 1054 | Performing Custom Build Tools 1055 | Performing Custom Build Tools 1056 | Performing Custom Build Tools 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | Performing Custom Build Tools 1084 | Performing Custom Build Tools 1085 | Performing Custom Build Tools 1086 | Performing Custom Build Tools 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | Performing Custom Build Tools 1112 | Performing Custom Build Tools 1113 | Performing Custom Build Tools 1114 | Performing Custom Build Tools 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | Performing Custom Build Tools 1142 | Performing Custom Build Tools 1143 | Performing Custom Build Tools 1144 | Performing Custom Build Tools 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | Performing Custom Build Tools 1170 | Performing Custom Build Tools 1171 | Performing Custom Build Tools 1172 | Performing Custom Build Tools 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | 1184 | 1185 | 1186 | 1187 | 1188 | 1189 | 1190 | 1191 | 1192 | 1193 | 1194 | 1195 | 1196 | 1197 | 1198 | 1199 | Performing Custom Build Tools 1200 | Performing Custom Build Tools 1201 | Performing Custom Build Tools 1202 | Performing Custom Build Tools 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | Performing Custom Build Tools 1228 | Performing Custom Build Tools 1229 | Performing Custom Build Tools 1230 | Performing Custom Build Tools 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | Performing Custom Build Tools 1258 | Performing Custom Build Tools 1259 | Performing Custom Build Tools 1260 | Performing Custom Build Tools 1261 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 1274 | 1275 | 1276 | 1277 | 1278 | 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | Performing Custom Build Tools 1286 | Performing Custom Build Tools 1287 | Performing Custom Build Tools 1288 | Performing Custom Build Tools 1289 | 1290 | 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | 1304 | 1305 | 1306 | 1307 | 1308 | 1309 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1310 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1311 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1312 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1313 | Uic%27ing %(Identity)... 1314 | Uic%27ing %(Identity)... 1315 | Uic%27ing %(Identity)... 1316 | Uic%27ing %(Identity)... 1317 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1318 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1319 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1320 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1321 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1322 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1323 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1324 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1325 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1326 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1327 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1328 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 1329 | Uic%27ing %(Identity)... 1330 | Uic%27ing %(Identity)... 1331 | Uic%27ing %(Identity)... 1332 | Uic%27ing %(Identity)... 1333 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1334 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1335 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1336 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 1337 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1338 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1339 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1340 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 1341 | 1342 | 1343 | 1344 | 1345 | 1346 | Moc%27ing MainDialog.h... 1347 | Moc%27ing MainDialog.h... 1348 | Moc%27ing MainDialog.h... 1349 | Moc%27ing MainDialog.h... 1350 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1351 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1352 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1353 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1354 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_DEVMODE -D_DEBUG -DWIN32 -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1355 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_DEVMODE -D_DEBUG -DWIN32 -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1356 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_DEVMODE -D__EA64__ -D_DEBUG -DWIN32 -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1357 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_DEVMODE -D__EA64__ -D_DEBUG -DWIN32 -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1358 | Moc%27ing MainDialog.h... 1359 | Moc%27ing MainDialog.h... 1360 | Moc%27ing MainDialog.h... 1361 | Moc%27ing MainDialog.h... 1362 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1363 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1364 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1365 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 1366 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DWIN32 -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1367 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DWIN32 -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1368 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D__EA64__ -DWIN32 -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1369 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D__EA64__ -DWIN32 -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -D_CRT_SECURE_NO_WARNINGS -DMATERIAL_DESIGN_STYLE -D_VC80_UPGRADE=0x0600 -D_WINDLL "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(IDADIR)\idasdk\include" "-I$(QTDIR)\include" "-I$(IDASUPPORT)\IDA_WaitEx" "-I$(IDASUPPORT)\IDA_SegmentSelect" "-I$(IDASUPPORT)\IDA_OggPlayer" "-I$(IDASUPPORT)\SupportLib" 1370 | $(QTDIR)\bin\moc.exe;%(FullPath) 1371 | $(QTDIR)\bin\moc.exe;%(FullPath) 1372 | $(QTDIR)\bin\moc.exe;%(FullPath) 1373 | $(QTDIR)\bin\moc.exe;%(FullPath) 1374 | $(QTDIR)\bin\moc.exe;%(FullPath) 1375 | $(QTDIR)\bin\moc.exe;%(FullPath) 1376 | $(QTDIR)\bin\moc.exe;%(FullPath) 1377 | $(QTDIR)\bin\moc.exe;%(FullPath) 1378 | 1379 | 1380 | 1381 | 1382 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1383 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1384 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1385 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1386 | Rcc%27ing %(Identity)... 1387 | Rcc%27ing %(Identity)... 1388 | Rcc%27ing %(Identity)... 1389 | Rcc%27ing %(Identity)... 1390 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1391 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1392 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1393 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1394 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1395 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1396 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1397 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1398 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1399 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1400 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1401 | %(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs) 1402 | Rcc%27ing %(Identity)... 1403 | Rcc%27ing %(Identity)... 1404 | Rcc%27ing %(Identity)... 1405 | Rcc%27ing %(Identity)... 1406 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1407 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1408 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1409 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 1410 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1411 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1412 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1413 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 1414 | 1415 | 1416 | 1417 | 1418 | true 1419 | true 1420 | true 1421 | true 1422 | true 1423 | true 1424 | true 1425 | true 1426 | 1427 | 1428 | 1429 | 1430 | 1431 | 1432 | 1433 | true 1434 | true 1435 | true 1436 | true 1437 | true 1438 | true 1439 | true 1440 | true 1441 | 1442 | 1443 | true 1444 | true 1445 | true 1446 | true 1447 | true 1448 | true 1449 | true 1450 | true 1451 | 1452 | 1453 | true 1454 | true 1455 | true 1456 | true 1457 | true 1458 | true 1459 | true 1460 | true 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | -------------------------------------------------------------------------------- /Plugin/IDA_ClassInformer_PlugIn.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {a9876874-6172-4c9f-9d7e-e37acb380d0b} 6 | 7 | 8 | {457050d4-f1f3-4a27-972f-11271f76b0de} 9 | 10 | 11 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3} 12 | ui 13 | true 14 | 15 | 16 | {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} 17 | moc;h;cpp 18 | true 19 | 20 | 21 | {dd7ba64d-d074-493d-9850-868de31096d7} 22 | cpp;moc 23 | False 24 | 25 | 26 | {e0c522c9-a6a4-40e2-a4d6-fc62cb3e5aed} 27 | cpp;moc 28 | False 29 | 30 | 31 | {7df04027-bd87-43d2-b942-a438fb7cabc3} 32 | cpp;moc 33 | False 34 | 35 | 36 | {08b1d19d-ae87-4e19-a17b-645dacc30448} 37 | cpp;moc 38 | False 39 | 40 | 41 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 42 | qrc;* 43 | false 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Generated Files\Debug64 53 | 54 | 55 | Generated Files\Debug 56 | 57 | 58 | Generated Files\Release 59 | 60 | 61 | Generated Files\Release64 62 | 63 | 64 | Generated Files 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | Misc 73 | 74 | 75 | Doc 76 | 77 | 78 | Doc 79 | 80 | 81 | Doc 82 | 83 | 84 | Doc 85 | 86 | 87 | Doc 88 | 89 | 90 | Doc 91 | 92 | 93 | Form Files 94 | 95 | 96 | 97 | Resource Files 98 | 99 | 100 | 101 | 102 | Generated Files 103 | 104 | 105 | 106 | 107 | Resource Files 108 | 109 | 110 | Resource Files 111 | 112 | 113 | Resource Files 114 | 115 | 116 | Resource Files 117 | 118 | 119 | 120 | 121 | Resource Files 122 | 123 | 124 | Resource Files 125 | 126 | 127 | Resource Files 128 | 129 | 130 | -------------------------------------------------------------------------------- /Plugin/Main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcx/classinformer-ida7/2a07f0ce48498d4066c8caeee499460d9328ec82/Plugin/Main.cpp -------------------------------------------------------------------------------- /Plugin/Main.h: -------------------------------------------------------------------------------- 1 | 2 | // **************************************************************************** 3 | // File: Main.h 4 | // Desc: 5 | // 6 | // **************************************************************************** 7 | 8 | extern void fixEa(ea_t ea); 9 | extern void fixDword(ea_t eaAddress); 10 | extern void fixFunction(ea_t eaFunc); 11 | extern void setUnknown(ea_t ea, int size); 12 | extern BOOL getVerifyEa(ea_t ea, ea_t &rValue); 13 | extern BOOL hasAnteriorComment(ea_t ea); 14 | extern void killAnteriorComments(ea_t ea); 15 | extern int addStrucMember(struc_t *sptr, char *name, ea_t offset, flags_t flag, opinfo_t *type, asize_t nbytes); 16 | extern void addTableEntry(UINT flags, ea_t vft, int methodCount, LPCSTR format, ...); 17 | extern BOOL getPlainTypeName(__in LPCSTR mangled, __out_bcount(MAXSTR) LPSTR outStr); 18 | extern void setName(ea_t ea, __in LPCSTR name); 19 | extern void setComment(ea_t ea, LPCSTR comment, BOOL rptble); 20 | extern void setAnteriorComment(ea_t ea, const char *format, ...); 21 | 22 | // Return TRUE if there is a name at address that is not a dumbly name 23 | inline BOOL hasName(ea_t ea) { return has_name(get_flags(ea)); } 24 | 25 | // Return TRUE if there is a comment at address 26 | inline BOOL hasComment(ea_t ea) { return has_cmt(get_flags(ea)); } 27 | 28 | 29 | // Get IDA 32 bit value with verification 30 | template BOOL getVerify32(ea_t eaPtr, T &rValue) 31 | { 32 | // Location valid? 33 | if (is_loaded(eaPtr)) 34 | { 35 | // Get 32bit value 36 | rValue = (T) get_32bit(eaPtr); 37 | return(TRUE); 38 | } 39 | 40 | return(FALSE); 41 | } 42 | 43 | // Get address/pointer value 44 | inline ea_t getEa(ea_t ea) 45 | { 46 | #ifndef __EA64__ 47 | return((ea_t) get_32bit(ea)); 48 | #else 49 | return((ea_t) get_64bit(ea)); 50 | #endif 51 | } 52 | 53 | 54 | // Returns TRUE if ea_t sized value flags 55 | inline BOOL isEa(flags_t f) 56 | { 57 | #ifndef __EA64__ 58 | return(is_dword(f)); 59 | #else 60 | return(is_qword(f)); 61 | #endif 62 | } 63 | 64 | extern BOOL optionPlaceStructs; 65 | -------------------------------------------------------------------------------- /Plugin/MainDialog.cpp: -------------------------------------------------------------------------------- 1 | 2 | // **************************************************************************** 3 | // File: MainDialog.cpp 4 | // Desc: Main Dialog 5 | // 6 | // **************************************************************************** 7 | #include "stdafx.h" 8 | #include "MainDialog.h" 9 | 10 | #include 11 | 12 | 13 | MainDialog::MainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments **segs) : QDialog(QApplication::activeWindow(), 0) 14 | { 15 | Ui::MainCIDialog::setupUi(this); 16 | setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); 17 | buttonBox->addButton("CONTINUE", QDialogButtonBox::AcceptRole); 18 | buttonBox->addButton("CANCEL", QDialogButtonBox::RejectRole); 19 | 20 | #define INITSTATE(obj,state) obj->setCheckState((state == TRUE) ? Qt::Checked : Qt::Unchecked); 21 | INITSTATE(checkBox1, optionPlaceStructs); 22 | INITSTATE(checkBox2, optionProcessStatic); 23 | INITSTATE(checkBox3, optionAudioOnDone); 24 | #undef INITSTATE 25 | 26 | // Apply style sheet 27 | QFile file(STYLE_PATH "style.qss"); 28 | if (file.open(QFile::ReadOnly | QFile::Text)) 29 | setStyleSheet(QTextStream(&file).readAll()); 30 | 31 | this->segs = segs; 32 | } 33 | 34 | // On choose segments 35 | void MainDialog::segmentSelect() 36 | { 37 | *segs = SegSelect::select((SegSelect::DATA_HINT | SegSelect::RDATA_HINT), "Choose segments to scan"); 38 | } 39 | 40 | // Do main dialog, return TRUE if canceled 41 | BOOL doMainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments **segs) 42 | { 43 | BOOL result = TRUE; 44 | MainDialog *dlg = new MainDialog(optionPlaceStructs, optionProcessStatic, optionAudioOnDone, segs); 45 | if (dlg->exec()) 46 | { 47 | #define CHECKSTATE(obj,var) var = dlg->obj->isChecked() 48 | CHECKSTATE(checkBox1, optionPlaceStructs); 49 | CHECKSTATE(checkBox2, optionProcessStatic); 50 | CHECKSTATE(checkBox3, optionAudioOnDone); 51 | #undef CHECKSTATE 52 | result = FALSE; 53 | } 54 | delete dlg; 55 | return(result); 56 | } -------------------------------------------------------------------------------- /Plugin/MainDialog.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "stdafx.h" 5 | #include 6 | #include 7 | 8 | #include "ui_dialog.h" 9 | 10 | class MainDialog : public QDialog, public Ui::MainCIDialog 11 | { 12 | Q_OBJECT 13 | public: 14 | MainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments **segs); 15 | 16 | private: 17 | SegSelect::segments **segs; 18 | 19 | private slots: 20 | void segmentSelect(); 21 | }; 22 | 23 | // Do main dialog, return TRUE if canceled 24 | BOOL doMainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments **segs); 25 | -------------------------------------------------------------------------------- /Plugin/PropertySheet.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | $(IDADIR) 11 | true 12 | 13 | 14 | $(QTDIR) 15 | true 16 | 17 | 18 | $(IDASUPPORT) 19 | 20 | 21 | -------------------------------------------------------------------------------- /Plugin/RTTI.cpp: -------------------------------------------------------------------------------- 1 | 2 | // **************************************************************************** 3 | // File: RTTI.cpp 4 | // Desc: Run-Time Type Information (RTTI) support 5 | // 6 | // **************************************************************************** 7 | #include "stdafx.h" 8 | #include "Main.h" 9 | #include "RTTI.h" 10 | #include "Vftable.h" 11 | 12 | // const Name::`vftable' 13 | static LPCSTR FORMAT_RTTI_VFTABLE = "??_7%s6B@"; 14 | static LPCSTR FORMAT_RTTI_VFTABLE_PREFIX = "??_7"; 15 | // type 'RTTI Type Descriptor' 16 | static LPCSTR FORMAT_RTTI_TYPE = "??_R0?%s@8"; 17 | // 'RTTI Base Class Descriptor at (a,b,c,d)' 18 | static LPCSTR FORMAT_RTTI_BCD = "??_R1%s%s%s%s%s8"; 19 | // `RTTI Base Class Array' 20 | static LPCSTR FORMAT_RTTI_BCA = "??_R2%s8"; 21 | // 'RTTI Class Hierarchy Descriptor' 22 | static LPCSTR FORMAT_RTTI_CHD = "??_R3%s8"; 23 | // 'RTTI Complete Object Locator' 24 | static LPCSTR FORMAT_RTTI_COL = "??_R4%s6B@"; 25 | static LPCSTR FORMAT_RTTI_COL_PREFIX = "??_R4"; 26 | 27 | // Skip type_info tag for class/struct mangled name strings 28 | #define SKIP_TD_TAG(_str) ((_str) + SIZESTR(".?Ax")) 29 | 30 | // Class name list container 31 | struct bcdInfo 32 | { 33 | char m_name[496]; 34 | UINT m_attribute; 35 | RTTI::PMD m_pmd; 36 | }; 37 | typedef qvector bcdList; 38 | 39 | namespace RTTI 40 | { 41 | void getBCDInfo(ea_t col, __out bcdList &nameList, __out UINT &numBaseClasses); 42 | }; 43 | 44 | 45 | typedef std::unordered_map stringMap; 46 | static stringMap stringCache; 47 | static eaSet tdSet; 48 | static eaSet chdSet; 49 | static eaSet bcdSet; 50 | 51 | void RTTI::freeWorkingData() 52 | { 53 | stringCache.clear(); 54 | tdSet.clear(); 55 | chdSet.clear(); 56 | bcdSet.clear(); 57 | } 58 | 59 | // Mangle number for labeling 60 | static LPSTR mangleNumber(UINT number, __out_bcount(64) LPSTR buffer) 61 | { 62 | // 63 | // 0 = A@ 64 | // X = X-1 (1 <= X <= 10) 65 | // -X = ? (X - 1) 66 | // 0x0..0xF = 'A'..'P' 67 | 68 | // Can only get unsigned inputs 69 | int num = *((PINT) &number); 70 | if(num == 0) 71 | return("A@"); 72 | else 73 | { 74 | int sign = 0; 75 | if(num < 0) 76 | { 77 | sign = 1; 78 | num = -num; 79 | } 80 | 81 | if(num <= 10) 82 | { 83 | _snprintf_s(buffer, 64, (64 - 1), "%s%d", (sign ? "?" : ""), (num - 1)); 84 | return(buffer); 85 | } 86 | else 87 | { 88 | // Count digits 89 | char buffer2[64] = {0}; 90 | int count = sizeof(buffer2); 91 | 92 | while((num > 0) && (count > 0)) 93 | { 94 | buffer2[sizeof(buffer2) - count] = ('A' + (num % 16)); 95 | num = (num / 16); 96 | count--; 97 | }; 98 | 99 | if(count == 0) 100 | msg(" *** mangleNumber() overflow! ***"); 101 | 102 | _snprintf_s(buffer, 64, (64-1), "%s%s@", (sign ? "?" : ""), buffer2); 103 | return(buffer); 104 | } 105 | } 106 | } 107 | 108 | 109 | // Return a short label indicating the CHD inheritance type by attributes 110 | // TODO: Consider CHD_AMBIGUOUS? 111 | static LPCSTR attributeLabel(UINT attributes) 112 | { 113 | if ((attributes & 3) == RTTI::CHD_MULTINH) 114 | return("[MI]"); 115 | else 116 | if ((attributes & 3) == RTTI::CHD_VIRTINH) 117 | return("[VI]"); 118 | else 119 | if ((attributes & 3) == (RTTI::CHD_MULTINH | RTTI::CHD_VIRTINH)) 120 | return("[MI VI]"); 121 | else 122 | return(""); 123 | } 124 | 125 | 126 | // Add RTTI definitions to IDA 127 | // Structure type IDs 128 | static tid_t s_type_info_ID = 1; 129 | static tid_t s_ClassHierarchyDescriptor_ID = 2; 130 | static tid_t s_PMD_ID = 3; 131 | static tid_t s_BaseClassDescriptor_ID = 4; 132 | static tid_t s_CompleteObjectLocator_ID = 5; 133 | 134 | // Create structure definition w/comment 135 | static struc_t *addStruct(__out tid_t &id, __in LPCSTR name, LPCSTR comment) 136 | { 137 | struc_t *structPtr = NULL; 138 | 139 | // If it exists get current def else create it 140 | id = get_struc_id(name); 141 | if (id == BADADDR) 142 | id = add_struc(BADADDR, name); 143 | if (id != BADADDR) 144 | structPtr = get_struc(id); 145 | 146 | if (structPtr) 147 | { 148 | // Clear the old one out if it exists and set the comment 149 | int dd = del_struc_members(structPtr, 0, MAXADDR); 150 | dd = dd; // for debugging 151 | bool rr = set_struc_cmt(id, comment, true); 152 | rr = rr; 153 | } 154 | else 155 | msg("** addStruct(\"%s\") failed!\n", name); 156 | 157 | return(structPtr); 158 | } 159 | 160 | void RTTI::addDefinitionsToIda() 161 | { 162 | // Member type info for 32bit offset types 163 | opinfo_t mtoff; 164 | ZeroMemory(&mtoff, sizeof(refinfo_t)); 165 | #ifndef __EA64__ 166 | mtoff.ri.flags = REF_OFF32; 167 | #define EAOFFSET (off_flag() | dword_flag()) 168 | #else 169 | mtoff.ri.flags = REF_OFF64; 170 | #define EAOFFSET (off_flag() | qword_flag()) 171 | #endif 172 | mtoff.ri.target = BADADDR; 173 | struc_t *structPtr; 174 | 175 | // Add structure member 176 | #define ADD_MEMBER(_flags, _mtoff, TYPE, _member) \ 177 | { \ 178 | TYPE _type; \ 179 | (void)_type; \ 180 | if(add_struc_member(structPtr, #_member, (ea_t )offsetof(TYPE, _member), (_flags), _mtoff, (asize_t) sizeof(_type._member)) != 0) \ 181 | msg(" ** ADD_MEMBER(): %s failed! %d, %d **\n", #_member, offsetof(TYPE, _member), sizeof(_type._member)); \ 182 | } 183 | 184 | // IDA 7 has a definition for this now 185 | s_type_info_ID = get_struc_id("TypeDescriptor"); 186 | if (s_type_info_ID == BADADDR) 187 | { 188 | msg("** Failed to load the IDA TypeDescriptor type, generating one **\n"); 189 | 190 | if (structPtr = addStruct(s_type_info_ID, "type_info", "RTTI std::type_info class (#classinformer)")) 191 | { 192 | ADD_MEMBER(EAOFFSET, &mtoff, RTTI::type_info, vfptr); 193 | ADD_MEMBER(dword_flag(), NULL, RTTI::type_info, _M_data); 194 | 195 | // Name string zero size 196 | opinfo_t mt; 197 | ZeroMemory(&mt, sizeof(refinfo_t)); 198 | if (addStrucMember(structPtr, "_M_d_name", offsetof(RTTI::type_info, _M_d_name), strlit_flag(), &mt, 0) != 0) 199 | msg("** addDefinitionsToIda(): _M_d_name failed! \n"); 200 | } 201 | } 202 | 203 | // Must come before the following "_RTTIBaseClassDescriptor" 204 | if (structPtr = addStruct(s_PMD_ID, "_PMD", "RTTI Base class descriptor displacement container (#classinformer)")) 205 | { 206 | ADD_MEMBER(dword_flag(), NULL, RTTI::PMD, mdisp); 207 | ADD_MEMBER(dword_flag(), NULL, RTTI::PMD, pdisp); 208 | ADD_MEMBER(dword_flag(), NULL, RTTI::PMD, vdisp); 209 | } 210 | 211 | if (structPtr = addStruct(s_ClassHierarchyDescriptor_ID, "_RTTIClassHierarchyDescriptor", "RTTI Class Hierarchy Descriptor (#classinformer)")) 212 | { 213 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTIClassHierarchyDescriptor, signature); 214 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTIClassHierarchyDescriptor, attributes); 215 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTIClassHierarchyDescriptor, numBaseClasses); 216 | #ifndef __EA64__ 217 | ADD_MEMBER(EAOFFSET, &mtoff, RTTI::_RTTIClassHierarchyDescriptor, baseClassArray); 218 | #else 219 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTIClassHierarchyDescriptor, baseClassArray); 220 | #endif 221 | } 222 | 223 | if (structPtr = addStruct(s_BaseClassDescriptor_ID, "_RTTIBaseClassDescriptor", "RTTI Base Class Descriptor (#classinformer)")) 224 | { 225 | #ifndef __EA64__ 226 | ADD_MEMBER(EAOFFSET, &mtoff, RTTI::_RTTIBaseClassDescriptor, typeDescriptor); 227 | #else 228 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTIBaseClassDescriptor, typeDescriptor); 229 | #endif 230 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTIBaseClassDescriptor, numContainedBases); 231 | opinfo_t mt; 232 | ZeroMemory(&mt, sizeof(refinfo_t)); 233 | mt.tid = s_PMD_ID; 234 | ADD_MEMBER(stru_flag(), &mt, RTTI::_RTTIBaseClassDescriptor, pmd); 235 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTIBaseClassDescriptor, attributes); 236 | } 237 | 238 | if(structPtr = addStruct(s_CompleteObjectLocator_ID, "_RTTICompleteObjectLocator", "RTTI Complete Object Locator (#classinformer)")) 239 | { 240 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTICompleteObjectLocator, signature); 241 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTICompleteObjectLocator, offset); 242 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTICompleteObjectLocator, cdOffset); 243 | #ifndef __EA64__ 244 | ADD_MEMBER(EAOFFSET, &mtoff, RTTI::_RTTICompleteObjectLocator, typeDescriptor); 245 | ADD_MEMBER(EAOFFSET, &mtoff, RTTI::_RTTICompleteObjectLocator, classDescriptor); 246 | #else 247 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTICompleteObjectLocator, typeDescriptor); 248 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTICompleteObjectLocator, classDescriptor); 249 | ADD_MEMBER(dword_flag(), NULL, RTTI::_RTTICompleteObjectLocator, objectBase); 250 | #endif 251 | } 252 | 253 | #undef ADD_MEMBER 254 | } 255 | 256 | // Version 1.05, manually set fields and then try to place the struct 257 | // If it fails at least the fields should be set 258 | // 2.5: IDA 7 now has RTTI support; only place structs if don't exist at address 259 | // Returns TRUE if structure was placed, else it was already set 260 | static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BOOL bHasChd = FALSE) 261 | { 262 | #define putDword(ea) create_dword(ea, sizeof(DWORD)) 263 | #ifndef __EA64__ 264 | #define putEa(ea) create_dword(ea, sizeof(ea_t)) 265 | #else 266 | #define putEa(ea) create_qword(ea, sizeof(ea_t)) 267 | #endif 268 | 269 | if(tid == s_type_info_ID) 270 | { 271 | if (!hasName(ea)) 272 | { 273 | _ASSERT(typeName != NULL); 274 | UINT nameLen = (UINT)(strlen(typeName) + 1); 275 | UINT structSize = (offsetof(RTTI::type_info, _M_d_name) + nameLen); 276 | 277 | // Place struct 278 | setUnknown(ea, structSize); 279 | BOOL result = FALSE; 280 | if (optionPlaceStructs) 281 | result = create_struct(ea, structSize, s_type_info_ID); 282 | if (!result) 283 | { 284 | putEa(ea + offsetof(RTTI::type_info, vfptr)); 285 | putEa(ea + offsetof(RTTI::type_info, _M_data)); 286 | 287 | create_strlit((ea + offsetof(RTTI::type_info, _M_d_name)), nameLen, STRTYPE_C); 288 | } 289 | 290 | // sh!ft: End should be aligned 291 | ea_t end = (ea + offsetof(RTTI::type_info, _M_d_name) + nameLen); 292 | if (end % 4) 293 | create_align(end, (4 - (end % 4)), 0); 294 | 295 | return TRUE; 296 | } 297 | } 298 | else 299 | if (tid == s_ClassHierarchyDescriptor_ID) 300 | { 301 | if (!hasName(ea)) 302 | { 303 | setUnknown(ea, sizeof(RTTI::_RTTIClassHierarchyDescriptor)); 304 | BOOL result = FALSE; 305 | if (optionPlaceStructs) 306 | result = create_struct(ea, sizeof(RTTI::_RTTIClassHierarchyDescriptor), s_ClassHierarchyDescriptor_ID); 307 | if (!result) 308 | { 309 | putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, signature)); 310 | putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, attributes)); 311 | putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, numBaseClasses)); 312 | #ifndef __EA64__ 313 | putEa(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, baseClassArray)); 314 | #else 315 | putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, baseClassArray)); 316 | #endif 317 | } 318 | 319 | return TRUE; 320 | } 321 | } 322 | else 323 | if(tid == s_PMD_ID) 324 | { 325 | if (!hasName(ea)) 326 | { 327 | setUnknown(ea, sizeof(RTTI::PMD)); 328 | BOOL result = FALSE; 329 | if (optionPlaceStructs) 330 | result = create_struct(ea, sizeof(RTTI::PMD), s_PMD_ID); 331 | if (!result) 332 | { 333 | putDword(ea + offsetof(RTTI::PMD, mdisp)); 334 | putDword(ea + offsetof(RTTI::PMD, pdisp)); 335 | putDword(ea + offsetof(RTTI::PMD, vdisp)); 336 | } 337 | 338 | return TRUE; 339 | } 340 | } 341 | else 342 | if(tid == s_CompleteObjectLocator_ID) 343 | { 344 | if (!hasName(ea)) 345 | { 346 | setUnknown(ea, sizeof(RTTI::_RTTICompleteObjectLocator)); 347 | BOOL result = FALSE; 348 | if (optionPlaceStructs) 349 | result = create_struct(ea, sizeof(RTTI::_RTTICompleteObjectLocator), s_CompleteObjectLocator_ID); 350 | if (!result) 351 | { 352 | putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, signature)); 353 | putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, offset)); 354 | putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, cdOffset)); 355 | 356 | #ifndef __EA64__ 357 | putEa(ea + offsetof(RTTI::_RTTICompleteObjectLocator, typeDescriptor)); 358 | putEa(ea + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor)); 359 | #else 360 | putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, typeDescriptor)); 361 | putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor)); 362 | putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase)); 363 | #endif 364 | } 365 | 366 | return TRUE; 367 | } 368 | } 369 | else 370 | if (tid == s_BaseClassDescriptor_ID) 371 | { 372 | // Recursive 373 | tryStructRTTI(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, pmd), s_PMD_ID); 374 | 375 | if (!hasName(ea)) 376 | { 377 | setUnknown(ea, sizeof(RTTI::_RTTIBaseClassDescriptor)); 378 | 379 | BOOL result = FALSE; 380 | if (optionPlaceStructs) 381 | result = create_struct(ea, sizeof(RTTI::_RTTIBaseClassDescriptor), s_BaseClassDescriptor_ID); 382 | if (!result) 383 | { 384 | #ifndef __EA64__ 385 | putEa(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, typeDescriptor)); 386 | #else 387 | putDword(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, typeDescriptor)); 388 | #endif 389 | 390 | putDword(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, numContainedBases)); 391 | putDword(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, attributes)); 392 | if (bHasChd) 393 | { 394 | //_RTTIClassHierarchyDescriptor *classDescriptor; *X64 int32 offset 395 | #ifndef __EA64__ 396 | putEa(ea + (offsetof(RTTI::_RTTIBaseClassDescriptor, attributes) + sizeof(UINT))); 397 | #else 398 | putDword(ea + (offsetof(RTTI::_RTTIBaseClassDescriptor, attributes) + sizeof(UINT))); 399 | #endif 400 | } 401 | } 402 | 403 | return TRUE; 404 | } 405 | } 406 | else 407 | { 408 | _ASSERT(FALSE); 409 | } 410 | 411 | return FALSE; 412 | } 413 | 414 | 415 | // Read ASCII string from IDB at address 416 | static int getIdaString(ea_t ea, __out LPSTR buffer, int bufferSize) 417 | { 418 | buffer[0] = 0; 419 | 420 | // Return cached name if it exists 421 | stringMap::iterator it = stringCache.find(ea); 422 | if (it != stringCache.end()) 423 | { 424 | LPCSTR str = it->second.c_str(); 425 | int len = (int) strlen(str); 426 | if (len > bufferSize) 427 | len = bufferSize; 428 | strncpy_s(buffer, MAXSTR, str, len); 429 | return len; 430 | } 431 | else 432 | { 433 | // Read string at ea if it exists 434 | int len = (int) get_max_strlit_length(ea, STRTYPE_C, ALOPT_IGNHEADS); 435 | if (len > 0) 436 | { 437 | // Length includes terminator 438 | if (len > bufferSize) 439 | len = bufferSize; 440 | 441 | qstring str; 442 | int len2 = get_strlit_contents(&str, ea, len, STRTYPE_C); 443 | if (len2 > 0) 444 | { 445 | // Length with out terminator 446 | if (len2 > bufferSize) 447 | len2 = bufferSize; 448 | 449 | // Cache it 450 | memcpy(buffer, str.c_str(), len2); 451 | buffer[len2] = 0; 452 | stringCache[ea] = buffer; 453 | } 454 | else 455 | len = 0; 456 | } 457 | 458 | return len ; 459 | } 460 | } 461 | 462 | 463 | // --------------------------- Type descriptor --------------------------- 464 | 465 | // Get type name into a buffer 466 | // type_info assumed to be valid 467 | int RTTI::type_info::getName(ea_t typeInfo, __out LPSTR buffer, int bufferSize) 468 | { 469 | return(getIdaString(typeInfo + offsetof(type_info, _M_d_name), buffer, bufferSize)); 470 | } 471 | 472 | // A valid type_info/TypeDescriptor at pointer? 473 | BOOL RTTI::type_info::isValid(ea_t typeInfo) 474 | { 475 | // TRUE if we've already seen it 476 | if (tdSet.find(typeInfo) != tdSet.end()) 477 | return(TRUE); 478 | 479 | if (is_loaded(typeInfo)) 480 | { 481 | // Verify what should be a vftable 482 | ea_t ea = getEa(typeInfo + offsetof(type_info, vfptr)); 483 | if (is_loaded(ea)) 484 | { 485 | // _M_data should be NULL statically 486 | ea_t _M_data = BADADDR; 487 | if (getVerifyEa((typeInfo + offsetof(type_info, _M_data)), _M_data)) 488 | { 489 | if (_M_data == 0) 490 | return(isTypeName(typeInfo + offsetof(type_info, _M_d_name))); 491 | } 492 | } 493 | } 494 | 495 | return(FALSE); 496 | } 497 | 498 | // Returns TRUE if known typename at address 499 | BOOL RTTI::type_info::isTypeName(ea_t name) 500 | { 501 | // Should start with a period 502 | if (get_byte(name) == '.') 503 | { 504 | // Read the rest of the possible name string 505 | char buffer[MAXSTR]; 506 | if (getIdaString(name, buffer, SIZESTR(buffer))) 507 | { 508 | // Should be valid if it properly demangles 509 | if (LPSTR s = __unDName(NULL, buffer+1 /*skip the '.'*/, 0, mallocWrap, free, (UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY))) 510 | { 511 | free(s); 512 | return(TRUE); 513 | } 514 | } 515 | } 516 | return(FALSE); 517 | } 518 | 519 | // Put struct and place name at address 520 | void RTTI::type_info::tryStruct(ea_t typeInfo) 521 | { 522 | // Only place once per address 523 | if (tdSet.find(typeInfo) != tdSet.end()) 524 | return; 525 | else 526 | tdSet.insert(typeInfo); 527 | 528 | // Get type name 529 | char name[MAXSTR]; 530 | int nameLen = getName(typeInfo, name, SIZESTR(name)); 531 | 532 | tryStructRTTI(typeInfo, s_type_info_ID, name); 533 | 534 | if (nameLen > 0) 535 | { 536 | if (!hasName(typeInfo)) 537 | { 538 | // Set decorated name/label 539 | char name2[MAXSTR]; 540 | _snprintf_s(name2, sizeof(name2), SIZESTR(name2), FORMAT_RTTI_TYPE, (name + 2)); 541 | setName(typeInfo, name2); 542 | } 543 | } 544 | else 545 | { 546 | _ASSERT(FALSE); 547 | } 548 | } 549 | 550 | 551 | // --------------------------- Complete Object Locator --------------------------- 552 | 553 | // Return TRUE if address is a valid RTTI structure 554 | BOOL RTTI::_RTTICompleteObjectLocator::isValid(ea_t col) 555 | { 556 | if (is_loaded(col)) 557 | { 558 | // Check signature 559 | UINT signature = -1; 560 | if (getVerify32((col + offsetof(_RTTICompleteObjectLocator, signature)), signature)) 561 | { 562 | #ifndef __EA64__ 563 | if (signature == 0) 564 | { 565 | // Check valid type_info 566 | ea_t typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor)); 567 | if (RTTI::type_info::isValid(typeInfo)) 568 | { 569 | ea_t classDescriptor = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor)); 570 | if (RTTI::_RTTIClassHierarchyDescriptor::isValid(classDescriptor)) 571 | { 572 | //msg(EAFORMAT" " EAFORMAT " " EAFORMAT " \n", col, typeInfo, classDescriptor); 573 | return(TRUE); 574 | } 575 | } 576 | } 577 | #else 578 | if (signature == 1) 579 | { 580 | // TODO: Can any of these be zero and still be valid? 581 | UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase)); 582 | if (objectLocator != 0) 583 | { 584 | UINT tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor)); 585 | if (tdOffset != 0) 586 | { 587 | UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor)); 588 | if (cdOffset != 0) 589 | { 590 | ea_t colBase = (col - (UINT64)objectLocator); 591 | 592 | ea_t typeInfo = (colBase + (UINT64)tdOffset); 593 | if (RTTI::type_info::isValid(typeInfo)) 594 | { 595 | ea_t classDescriptor = (colBase + (UINT64) cdOffset); 596 | if (RTTI::_RTTIClassHierarchyDescriptor::isValid(classDescriptor, colBase)) 597 | { 598 | //msg(EAFORMAT" " EAFORMAT " " EAFORMAT " \n", col, typeInfo, classDescriptor); 599 | return(TRUE); 600 | } 601 | } 602 | } 603 | } 604 | } 605 | } 606 | #endif 607 | } 608 | } 609 | 610 | return(FALSE); 611 | } 612 | 613 | // Same as above but from an already validated type_info perspective 614 | #ifndef __EA64__ 615 | BOOL RTTI::_RTTICompleteObjectLocator::isValid2(ea_t col) 616 | { 617 | // 'signature' should be zero 618 | UINT signature = -1; 619 | if (getVerify32((col + offsetof(_RTTICompleteObjectLocator, signature)), signature)) 620 | { 621 | if (signature == 0) 622 | { 623 | // Verify CHD 624 | ea_t classDescriptor = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor)); 625 | if (classDescriptor && (classDescriptor != BADADDR)) 626 | return(RTTI::_RTTIClassHierarchyDescriptor::isValid(classDescriptor)); 627 | } 628 | } 629 | 630 | return(FALSE); 631 | } 632 | #endif 633 | 634 | // Place full COL hierarchy structures if they don't already exist 635 | BOOL RTTI::_RTTICompleteObjectLocator::tryStruct(ea_t col) 636 | { 637 | // If it doesn't have a name, IDA's analyzer missed it 638 | if (!hasName(col)) 639 | { 640 | #if 0 641 | qstring buf; 642 | idaFlags2String(get_flags(col), buf); 643 | msg(EAFORMAT " fix COL (%s)\n", col, buf.c_str()); 644 | #endif 645 | 646 | tryStructRTTI(col, s_CompleteObjectLocator_ID); 647 | 648 | #ifndef __EA64__ 649 | // Put type_def 650 | ea_t typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor)); 651 | type_info::tryStruct(typeInfo); 652 | 653 | // Place CHD hierarchy 654 | ea_t classDescriptor = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor)); 655 | _RTTIClassHierarchyDescriptor::tryStruct(classDescriptor); 656 | #else 657 | UINT tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor)); 658 | UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor)); 659 | UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase)); 660 | ea_t colBase = (col - (UINT64)objectLocator); 661 | 662 | ea_t typeInfo = (colBase + (UINT64)tdOffset); 663 | type_info::tryStruct(typeInfo); 664 | 665 | ea_t classDescriptor = (colBase + (UINT64)cdOffset); 666 | _RTTIClassHierarchyDescriptor::tryStruct(classDescriptor, colBase); 667 | 668 | // Set absolute address comments 669 | ea_t ea = (col + offsetof(RTTI::_RTTICompleteObjectLocator, typeDescriptor)); 670 | if (!hasComment(ea)) 671 | { 672 | char buffer[64]; 673 | sprintf_s(buffer, sizeof(buffer), "0x" EAFORMAT, typeInfo); 674 | setComment(ea, buffer, TRUE); 675 | } 676 | 677 | ea = (col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor)); 678 | if (!hasComment(ea)) 679 | { 680 | char buffer[64]; 681 | sprintf_s(buffer, sizeof(buffer), "0x" EAFORMAT, classDescriptor); 682 | setComment(ea, buffer, TRUE); 683 | } 684 | #endif 685 | 686 | return TRUE; 687 | } 688 | 689 | return FALSE; 690 | } 691 | 692 | 693 | // --------------------------- Base Class Descriptor --------------------------- 694 | 695 | // Return TRUE if address is a valid BCD 696 | BOOL RTTI::_RTTIBaseClassDescriptor::isValid(ea_t bcd, ea_t colBase64) 697 | { 698 | // TRUE if we've already seen it 699 | if (bcdSet.find(bcd) != bcdSet.end()) 700 | return(TRUE); 701 | 702 | if (is_loaded(bcd)) 703 | { 704 | // Check attributes flags first 705 | UINT attributes = -1; 706 | if (getVerify32((bcd + offsetof(_RTTIBaseClassDescriptor, attributes)), attributes)) 707 | { 708 | // Valid flags are the lower byte only 709 | if ((attributes & 0xFFFFFF00) == 0) 710 | { 711 | // Check for valid type_info 712 | #ifndef __EA64__ 713 | return(RTTI::type_info::isValid(getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)))); 714 | #else 715 | UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); 716 | ea_t typeInfo = (colBase64 + (UINT64) tdOffset); 717 | return(RTTI::type_info::isValid(typeInfo)); 718 | #endif 719 | } 720 | } 721 | } 722 | 723 | return(FALSE); 724 | } 725 | 726 | // Put BCD structure at address 727 | void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LPSTR baseClassName, ea_t colBase64) 728 | { 729 | // Only place it once 730 | if (bcdSet.find(bcd) != bcdSet.end()) 731 | { 732 | // Seen already, just return type name 733 | #ifndef __EA64__ 734 | ea_t typeInfo = getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); 735 | #else 736 | UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); 737 | ea_t typeInfo = (colBase64 + (UINT64) tdOffset); 738 | #endif 739 | 740 | char buffer[MAXSTR]; 741 | type_info::getName(typeInfo, buffer, SIZESTR(buffer)); 742 | strcpy_s(baseClassName, sizeof(buffer), SKIP_TD_TAG(buffer)); 743 | return; 744 | } 745 | else 746 | bcdSet.insert(bcd); 747 | 748 | if (is_loaded(bcd)) 749 | { 750 | UINT attributes = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes)); 751 | tryStructRTTI(bcd, s_BaseClassDescriptor_ID, NULL, ((attributes & BCD_HASPCHD) > 0)); 752 | 753 | // Has appended CHD? 754 | if (attributes & BCD_HASPCHD) 755 | { 756 | // yes, process it 757 | ea_t chdOffset = (bcd + (offsetof(_RTTIBaseClassDescriptor, attributes) + sizeof(UINT))); 758 | 759 | #ifndef __EA64__ 760 | fixEa(chdOffset); 761 | ea_t chd = getEa(chdOffset); 762 | #else 763 | fixDword(chdOffset); 764 | UINT chdOffset32 = get_32bit(chdOffset); 765 | ea_t chd = (colBase64 + (UINT64) chdOffset32); 766 | 767 | if (!hasComment(chdOffset)) 768 | { 769 | char buffer[64]; 770 | sprintf_s(buffer, sizeof(buffer), "0x" EAFORMAT, chd); 771 | setComment(chdOffset, buffer, TRUE); 772 | } 773 | #endif 774 | 775 | if (is_loaded(chd)) 776 | _RTTIClassHierarchyDescriptor::tryStruct(chd, colBase64); 777 | else 778 | _ASSERT(FALSE); 779 | } 780 | 781 | // Place type_info struct 782 | #ifndef __EA64__ 783 | ea_t typeInfo = getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); 784 | #else 785 | UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); 786 | ea_t typeInfo = (colBase64 + (UINT64)tdOffset); 787 | #endif 788 | type_info::tryStruct(typeInfo); 789 | 790 | // Get raw type/class name 791 | char buffer[MAXSTR]; 792 | type_info::getName(typeInfo, buffer, SIZESTR(buffer)); 793 | strcpy_s(baseClassName, sizeof(buffer), SKIP_TD_TAG(buffer)); 794 | 795 | if (!optionPlaceStructs && attributes) 796 | { 797 | // Place attributes comment 798 | ea_t ea = (bcd + offsetof(_RTTIBaseClassDescriptor, attributes)); 799 | if (!hasComment(ea)) 800 | { 801 | qstring s(""); 802 | BOOL b = 0; 803 | #define ATRIBFLAG(_flag) { if (attributes & _flag) { if (b) s += " | "; s += #_flag; b = 1; } } 804 | ATRIBFLAG(BCD_NOTVISIBLE); 805 | ATRIBFLAG(BCD_AMBIGUOUS); 806 | ATRIBFLAG(BCD_PRIVORPROTINCOMPOBJ); 807 | ATRIBFLAG(BCD_PRIVORPROTBASE); 808 | ATRIBFLAG(BCD_VBOFCONTOBJ); 809 | ATRIBFLAG(BCD_NONPOLYMORPHIC); 810 | ATRIBFLAG(BCD_HASPCHD); 811 | #undef ATRIBFLAG 812 | setComment(ea, s.c_str(), TRUE); 813 | } 814 | } 815 | 816 | // Give it a label 817 | if (!hasName(bcd)) 818 | { 819 | // Name::`RTTI Base Class Descriptor at (0, -1, 0, 0)' 820 | ZeroMemory(buffer, sizeof(buffer)); 821 | char buffer1[64] = { 0 }, buffer2[64] = { 0 }, buffer3[64] = { 0 }, buffer4[64] = { 0 }; 822 | _snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), FORMAT_RTTI_BCD, 823 | mangleNumber(get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp))), buffer1), 824 | mangleNumber(get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp))), buffer2), 825 | mangleNumber(get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp))), buffer3), 826 | mangleNumber(attributes, buffer4), 827 | baseClassName); 828 | 829 | setName(bcd, buffer); 830 | } 831 | } 832 | else 833 | _ASSERT(FALSE); 834 | } 835 | 836 | 837 | // --------------------------- Class Hierarchy Descriptor --------------------------- 838 | 839 | // Return true if address is a valid CHD structure 840 | BOOL RTTI::_RTTIClassHierarchyDescriptor::isValid(ea_t chd, ea_t colBase64) 841 | { 842 | // TRUE if we've already seen it 843 | if (chdSet.find(chd) != chdSet.end()) 844 | return(TRUE); 845 | 846 | if (is_loaded(chd)) 847 | { 848 | // signature should be zero statically 849 | UINT signature = -1; 850 | if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, signature)), signature)) 851 | { 852 | if (signature == 0) 853 | { 854 | // Check attributes flags 855 | UINT attributes = -1; 856 | if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)), attributes)) 857 | { 858 | // Valid flags are the lower nibble only 859 | if ((attributes & 0xFFFFFFF0) == 0) 860 | { 861 | // Should have at least one base class 862 | UINT numBaseClasses = 0; 863 | if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses)), numBaseClasses)) 864 | { 865 | if (numBaseClasses >= 1) 866 | { 867 | // Check the first BCD entry 868 | #ifndef __EA64__ 869 | ea_t baseClassArray = getEa(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); 870 | #else 871 | UINT baseClassArrayOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); 872 | ea_t baseClassArray = (colBase64 + (UINT64) baseClassArrayOffset); 873 | #endif 874 | 875 | if (is_loaded(baseClassArray)) 876 | { 877 | #ifndef __EA64__ 878 | ea_t baseClassDescriptor = getEa(baseClassArray); 879 | return(RTTI::_RTTIBaseClassDescriptor::isValid(baseClassDescriptor)); 880 | #else 881 | ea_t baseClassDescriptor = (colBase64 + (UINT64) get_32bit(baseClassArray)); 882 | return(RTTI::_RTTIBaseClassDescriptor::isValid(baseClassDescriptor, colBase64)); 883 | #endif 884 | } 885 | } 886 | } 887 | } 888 | } 889 | } 890 | } 891 | } 892 | 893 | return(FALSE); 894 | } 895 | 896 | 897 | // Put CHD structure at address 898 | void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, ea_t colBase64) 899 | { 900 | // Only place it once per address 901 | if (chdSet.find(chd) != chdSet.end()) 902 | return; 903 | else 904 | chdSet.insert(chd); 905 | 906 | if (is_loaded(chd)) 907 | { 908 | // Place CHD 909 | tryStructRTTI(chd, s_ClassHierarchyDescriptor_ID); 910 | 911 | // Place attributes comment 912 | UINT attributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); 913 | if (!optionPlaceStructs && attributes) 914 | { 915 | ea_t ea = (chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); 916 | if (!hasComment(ea)) 917 | { 918 | qstring s(""); 919 | BOOL b = 0; 920 | #define ATRIBFLAG(_flag) { if (attributes & _flag) { if (b) s += " | "; s += #_flag; b = 1; } } 921 | ATRIBFLAG(CHD_MULTINH); 922 | ATRIBFLAG(CHD_VIRTINH); 923 | ATRIBFLAG(CHD_AMBIGUOUS); 924 | #undef ATRIBFLAG 925 | setComment(ea, s.c_str(), TRUE); 926 | } 927 | } 928 | 929 | // ---- Place BCD's ---- 930 | UINT numBaseClasses = 0; 931 | if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses)), numBaseClasses)) 932 | { 933 | // Get pointer 934 | #ifndef __EA64__ 935 | ea_t baseClassArray = getEa(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); 936 | #else 937 | UINT baseClassArrayOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); 938 | ea_t baseClassArray = (colBase64 + (UINT64) baseClassArrayOffset); 939 | 940 | ea_t ea = (chd + offsetof(RTTI::_RTTIClassHierarchyDescriptor, baseClassArray)); 941 | if (!hasComment(ea)) 942 | { 943 | char buffer[MAXSTR]; 944 | _snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), "0x" EAFORMAT, baseClassArray); 945 | setComment(ea, buffer, TRUE); 946 | } 947 | #endif 948 | 949 | if (baseClassArray && (baseClassArray != BADADDR)) 950 | { 951 | // Create offset string based on input digits 952 | #ifndef __EA64__ 953 | char format[32]; 954 | if(numBaseClasses > 1) 955 | { 956 | int digits = (int) strlen(_itoa(numBaseClasses, format, 10)); 957 | if (digits > 1) 958 | _snprintf_s(format, sizeof(format), SIZESTR(format), " BaseClass[%%0%dd]", digits); 959 | else 960 | strcpy_s(format, sizeof(format), " BaseClass[%d]"); 961 | } 962 | #else 963 | char format[128]; 964 | if (numBaseClasses > 1) 965 | { 966 | int digits = (int) strlen(_itoa(numBaseClasses, format, 10)); 967 | if (digits > 1) 968 | _snprintf_s(format, sizeof(format), SIZESTR(format), " BaseClass[%%0%dd] 0x%%016I64X", digits); 969 | else 970 | strcpy_s(format, sizeof(format), " BaseClass[%d] 0x%016I64X"); 971 | } 972 | #endif 973 | 974 | for (UINT i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(UINT)) // sizeof(ea_t) 975 | { 976 | #ifndef __EA64__ 977 | fixEa(baseClassArray); 978 | 979 | // Add index comment to to it 980 | if (!hasComment(baseClassArray)) 981 | { 982 | if (numBaseClasses == 1) 983 | setComment(baseClassArray, " BaseClass", FALSE); 984 | else 985 | { 986 | char ptrComent[MAXSTR]; 987 | _snprintf_s(ptrComent, sizeof(ptrComent), SIZESTR(ptrComent), format, i); 988 | setComment(baseClassArray, ptrComent, false); 989 | } 990 | } 991 | 992 | // Place BCD struct, and grab the base class name 993 | char baseClassName[MAXSTR]; 994 | _RTTIBaseClassDescriptor::tryStruct(getEa(baseClassArray), baseClassName); 995 | #else 996 | fixDword(baseClassArray); 997 | UINT bcOffset = get_32bit(baseClassArray); 998 | ea_t bcd = (colBase64 + (UINT64)bcOffset); 999 | 1000 | // Add index comment to to it 1001 | if (!hasComment(baseClassArray)) 1002 | { 1003 | if (numBaseClasses == 1) 1004 | { 1005 | char buffer[MAXSTR]; 1006 | sprintf_s(buffer, sizeof(buffer), " BaseClass 0x" EAFORMAT, bcd); 1007 | setComment(baseClassArray, buffer, FALSE); 1008 | } 1009 | else 1010 | { 1011 | char buffer[MAXSTR]; 1012 | _snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), format, i, bcd); 1013 | setComment(baseClassArray, buffer, false); 1014 | } 1015 | } 1016 | 1017 | // Place BCD struct, and grab the base class name 1018 | char baseClassName[MAXSTR]; 1019 | _RTTIBaseClassDescriptor::tryStruct(bcd, baseClassName, colBase64); 1020 | #endif 1021 | 1022 | // Now we have the base class name, name and label some things 1023 | if (i == 0) 1024 | { 1025 | // Set array name 1026 | if (!hasName(baseClassArray)) 1027 | { 1028 | // ??_R2A@@8 = A::`RTTI Base Class Array' 1029 | char mangledName[MAXSTR]; 1030 | _snprintf_s(mangledName, sizeof(mangledName), SIZESTR(mangledName), FORMAT_RTTI_BCA, baseClassName); 1031 | setName(baseClassArray, mangledName); 1032 | } 1033 | 1034 | // Add a spacing comment line above us 1035 | if (!hasAnteriorComment(baseClassArray)) 1036 | setAnteriorComment(baseClassArray, ""); 1037 | 1038 | // Set CHD name 1039 | if (!hasName(chd)) 1040 | { 1041 | // A::`RTTI Class Hierarchy Descriptor' 1042 | char mangledName[MAXSTR]; 1043 | _snprintf_s(mangledName, sizeof(mangledName), SIZESTR(mangledName), FORMAT_RTTI_CHD, baseClassName); 1044 | setName(chd, mangledName); 1045 | } 1046 | } 1047 | } 1048 | 1049 | // Make following DWORD if it's bytes are zeros 1050 | if (numBaseClasses > 0) 1051 | { 1052 | if (is_loaded(baseClassArray)) 1053 | if (get_32bit(baseClassArray) == 0) 1054 | fixDword(baseClassArray); 1055 | } 1056 | } 1057 | else 1058 | _ASSERT(FALSE); 1059 | } 1060 | else 1061 | _ASSERT(FALSE); 1062 | } 1063 | else 1064 | _ASSERT(FALSE); 1065 | } 1066 | 1067 | 1068 | // --------------------------- Vftable --------------------------- 1069 | 1070 | 1071 | // Get list of base class descriptor info 1072 | static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT &numBaseClasses) 1073 | { 1074 | numBaseClasses = 0; 1075 | 1076 | #ifndef __EA64__ 1077 | ea_t chd = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor)); 1078 | #else 1079 | UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor)); 1080 | UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase)); 1081 | ea_t colBase = (col - (UINT64) objectLocator); 1082 | ea_t chd = (colBase + (UINT64) cdOffset); 1083 | #endif 1084 | 1085 | if(chd) 1086 | { 1087 | if (numBaseClasses = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses))) 1088 | { 1089 | list.resize(numBaseClasses); 1090 | 1091 | // Get pointer 1092 | #ifndef __EA64__ 1093 | ea_t baseClassArray = getEa(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); 1094 | #else 1095 | UINT bcaOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); 1096 | ea_t baseClassArray = (colBase + (UINT64) bcaOffset); 1097 | #endif 1098 | 1099 | if(baseClassArray && (baseClassArray != BADADDR)) 1100 | { 1101 | for(UINT i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(UINT)) // sizeof(ea_t) 1102 | { 1103 | #ifndef __EA64__ 1104 | // Get next BCD 1105 | ea_t bcd = getEa(baseClassArray); 1106 | 1107 | // Get type name 1108 | ea_t typeInfo = getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); 1109 | #else 1110 | UINT bcdOffset = get_32bit(baseClassArray); 1111 | ea_t bcd = (colBase + (UINT64) bcdOffset); 1112 | 1113 | UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); 1114 | ea_t typeInfo = (colBase + (UINT64) tdOffset); 1115 | #endif 1116 | bcdInfo *bi = &list[i]; 1117 | type_info::getName(typeInfo, bi->m_name, SIZESTR(bi->m_name)); 1118 | 1119 | // Add info to list 1120 | UINT mdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp))); 1121 | UINT pdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp))); 1122 | UINT vdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp))); 1123 | // As signed int 1124 | bi->m_pmd.mdisp = *((PINT) &mdisp); 1125 | bi->m_pmd.pdisp = *((PINT) &pdisp); 1126 | bi->m_pmd.vdisp = *((PINT) &vdisp); 1127 | bi->m_attribute = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes)); 1128 | 1129 | //msg(" BN: [%d] \"%s\", ATB: %04X\n", i, szBuffer1, get_32bit((ea_t) &pBCD->attributes)); 1130 | //msg(" mdisp: %d, pdisp: %d, vdisp: %d, attributes: %04X\n", *((PINT) &mdisp), *((PINT) &pdisp), *((PINT) &vdisp), attributes); 1131 | } 1132 | } 1133 | } 1134 | } 1135 | } 1136 | 1137 | 1138 | // Process RTTI vftable info 1139 | // Returns TRUE if if vftable and wasn't named on entry 1140 | BOOL RTTI::processVftable(ea_t vft, ea_t col) 1141 | { 1142 | BOOL result = FALSE; 1143 | 1144 | #ifdef __EA64__ 1145 | UINT tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor)); 1146 | UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase)); 1147 | ea_t colBase = (col - (UINT64) objectLocator); 1148 | ea_t typeInfo = (colBase + (UINT64) tdOffset); 1149 | #endif 1150 | 1151 | // Verify and fix if vftable exists here 1152 | vftable::vtinfo vi; 1153 | if (vftable::getTableInfo(vft, vi)) 1154 | { 1155 | //msg(EAFORMAT " - " EAFORMAT " c: %d\n", vi.start, vi.end, vi.methodCount); 1156 | 1157 | // Get COL type name 1158 | #ifndef __EA64__ 1159 | ea_t typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor)); 1160 | ea_t chd = get_32bit(col + offsetof(_RTTICompleteObjectLocator, classDescriptor)); 1161 | #else 1162 | UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor)); 1163 | ea_t chd = (colBase + (UINT64) cdOffset); 1164 | #endif 1165 | 1166 | char colName[MAXSTR]; 1167 | type_info::getName(typeInfo, colName, SIZESTR(colName)); 1168 | char demangledColName[MAXSTR]; 1169 | getPlainTypeName(colName, demangledColName); 1170 | 1171 | UINT chdAttributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); 1172 | UINT offset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, offset)); 1173 | 1174 | // Parse BCD info 1175 | bcdList list; 1176 | UINT numBaseClasses; 1177 | getBCDInfo(col, list, numBaseClasses); 1178 | 1179 | BOOL sucess = FALSE, isTopLevel = FALSE; 1180 | qstring cmt; 1181 | 1182 | // ======= Simple or no inheritance 1183 | if ((offset == 0) && ((chdAttributes & (CHD_MULTINH | CHD_VIRTINH)) == 0)) 1184 | { 1185 | // Set the vftable name 1186 | if (!hasName(vft)) 1187 | { 1188 | result = TRUE; 1189 | 1190 | // Decorate raw name as a vftable. I.E. const Name::`vftable' 1191 | char decorated[MAXSTR]; 1192 | _snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_VFTABLE, SKIP_TD_TAG(colName)); 1193 | setName(vft, decorated); 1194 | } 1195 | 1196 | // Set COL name. I.E. const Name::`RTTI Complete Object Locator' 1197 | if (!hasName(col)) 1198 | { 1199 | char decorated[MAXSTR]; 1200 | _snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_COL, SKIP_TD_TAG(colName)); 1201 | setName(col, decorated); 1202 | } 1203 | 1204 | // Build object hierarchy string 1205 | int placed = 0; 1206 | if (numBaseClasses > 1) 1207 | { 1208 | // Parent 1209 | char plainName[MAXSTR]; 1210 | getPlainTypeName(list[0].m_name, plainName); 1211 | cmt.sprnt("%s%s: ", ((list[0].m_name[3] == 'V') ? "" : "struct "), plainName); 1212 | placed++; 1213 | isTopLevel = ((strcmp(list[0].m_name, colName) == 0) ? TRUE : FALSE); 1214 | 1215 | // Child object hierarchy 1216 | for (UINT i = 1; i < numBaseClasses; i++) 1217 | { 1218 | // Append name 1219 | getPlainTypeName(list[i].m_name, plainName); 1220 | cmt.cat_sprnt("%s%s, ", ((list[i].m_name[3] == 'V') ? "" : "struct "), plainName); 1221 | placed++; 1222 | } 1223 | 1224 | // Nix the ending ',' for the last one 1225 | if (placed > 1) 1226 | cmt.remove((cmt.length() - 2), 2); 1227 | } 1228 | else 1229 | { 1230 | // Plain, no inheritance object(s) 1231 | cmt.sprnt("%s%s: ", ((colName[3] == 'V') ? "" : "struct "), demangledColName); 1232 | isTopLevel = TRUE; 1233 | } 1234 | 1235 | if (placed > 1) 1236 | cmt += ';'; 1237 | 1238 | sucess = TRUE; 1239 | } 1240 | // ======= Multiple inheritance, and, or, virtual inheritance hierarchies 1241 | else 1242 | { 1243 | bcdInfo *bi = NULL; 1244 | int index = 0; 1245 | 1246 | // Must be the top level object for the type 1247 | if (offset == 0) 1248 | { 1249 | _ASSERT(strcmp(colName, list[0].m_name) == 0); 1250 | bi = &list[0]; 1251 | isTopLevel = TRUE; 1252 | } 1253 | else 1254 | { 1255 | // Get our object BCD level by matching COL offset to displacement 1256 | for (UINT i = 0; i < numBaseClasses; i++) 1257 | { 1258 | if (list[i].m_pmd.mdisp == offset) 1259 | { 1260 | bi = &list[i]; 1261 | index = i; 1262 | break; 1263 | } 1264 | } 1265 | 1266 | // If not found in list, use the first base object instead 1267 | if (!bi) 1268 | { 1269 | //msg("** " EAFORMAT " MI COL class offset: %X(%d) not in BCD.\n", vft, offset, offset); 1270 | for (UINT i = 0; i < numBaseClasses; i++) 1271 | { 1272 | if (list[i].m_pmd.pdisp != -1) 1273 | { 1274 | bi = &list[i]; 1275 | index = i; 1276 | break; 1277 | } 1278 | } 1279 | } 1280 | } 1281 | 1282 | if (bi) 1283 | { 1284 | // Top object level layout 1285 | int placed = 0; 1286 | if (isTopLevel) 1287 | { 1288 | // Set the vft name 1289 | if (!hasName(vft)) 1290 | { 1291 | result = TRUE; 1292 | 1293 | char decorated[MAXSTR]; 1294 | _snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_VFTABLE, SKIP_TD_TAG(colName)); 1295 | setName(vft, decorated); 1296 | } 1297 | 1298 | // COL name 1299 | if (!hasName(col)) 1300 | { 1301 | char decorated[MAXSTR]; 1302 | _snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_COL, SKIP_TD_TAG(colName)); 1303 | setName(col, decorated); 1304 | } 1305 | 1306 | // Build hierarchy string starting with parent 1307 | char plainName[MAXSTR]; 1308 | getPlainTypeName(list[0].m_name, plainName); 1309 | cmt.sprnt("%s%s: ", ((list[0].m_name[3] == 'V') ? "" : "struct "), plainName); 1310 | placed++; 1311 | 1312 | // Concatenate forward child hierarchy 1313 | for (UINT i = 1; i < numBaseClasses; i++) 1314 | { 1315 | getPlainTypeName(list[i].m_name, plainName); 1316 | cmt.cat_sprnt("%s%s, ", ((list[i].m_name[3] == 'V') ? "" : "struct "), plainName); 1317 | placed++; 1318 | } 1319 | if (placed > 1) 1320 | cmt.remove((cmt.length() - 2), 2); 1321 | } 1322 | else 1323 | { 1324 | // Combine COL and CHD name 1325 | char combinedName[MAXSTR]; 1326 | _snprintf_s(combinedName, sizeof(combinedName), SIZESTR(combinedName), "%s6B%s@", SKIP_TD_TAG(colName), SKIP_TD_TAG(bi->m_name)); 1327 | 1328 | // Set vftable name 1329 | if (!hasName(vft)) 1330 | { 1331 | result = TRUE; 1332 | 1333 | char decorated[MAXSTR]; 1334 | strcpy(decorated, FORMAT_RTTI_VFTABLE_PREFIX); 1335 | strncat_s(decorated, MAXSTR, combinedName, (MAXSTR - (1 + SIZESTR(FORMAT_RTTI_VFTABLE_PREFIX)))); 1336 | setName(vft, decorated); 1337 | } 1338 | 1339 | // COL name 1340 | if (!hasName((ea_t) col)) 1341 | { 1342 | char decorated[MAXSTR]; 1343 | strcpy(decorated, FORMAT_RTTI_COL_PREFIX); 1344 | strncat_s(decorated, MAXSTR, combinedName, (MAXSTR - (1 + SIZESTR(FORMAT_RTTI_COL_PREFIX)))); 1345 | setName((ea_t) col, decorated); 1346 | } 1347 | 1348 | // Build hierarchy string starting with parent 1349 | char plainName[MAXSTR]; 1350 | getPlainTypeName(bi->m_name, plainName); 1351 | cmt.sprnt("%s%s: ", ((bi->m_name[3] == 'V') ? "" : "struct "), plainName); 1352 | placed++; 1353 | 1354 | // Concatenate forward child hierarchy 1355 | if (++index < (int) numBaseClasses) 1356 | { 1357 | for (; index < (int) numBaseClasses; index++) 1358 | { 1359 | getPlainTypeName(list[index].m_name, plainName); 1360 | cmt.cat_sprnt("%s%s, ", ((list[index].m_name[3] == 'V') ? "" : "struct "), plainName); 1361 | placed++; 1362 | } 1363 | if (placed > 1) 1364 | cmt.remove((cmt.length() - 2), 2); 1365 | } 1366 | 1367 | /* 1368 | Experiment, maybe better this way to show before and after to show it's location in the hierarchy 1369 | // Concatenate reverse child hierarchy 1370 | if (--index >= 0) 1371 | { 1372 | for (; index >= 0; index--) 1373 | { 1374 | getPlainTypeName(list[index].m_name, plainName); 1375 | cmt.cat_sprnt("%s%s, ", ((list[index].m_name[3] == 'V') ? "" : "struct "), plainName); 1376 | placed++; 1377 | } 1378 | if (placed > 1) 1379 | cmt.remove((cmt.length() - 2), 2); 1380 | } 1381 | */ 1382 | } 1383 | 1384 | if (placed > 1) 1385 | cmt += ';'; 1386 | 1387 | sucess = TRUE; 1388 | } 1389 | else 1390 | msg(EAFORMAT" ** Couldn't find a BCD for MI/VI hierarchy!\n", vft); 1391 | } 1392 | 1393 | if (sucess) 1394 | { 1395 | // Store entry 1396 | addTableEntry(((chdAttributes & 0xF) | ((isTopLevel == TRUE) ? RTTI::IS_TOP_LEVEL : 0)), vft, vi.methodCount, "%s@%s", demangledColName, cmt.c_str()); 1397 | 1398 | // Add a separating comment above RTTI COL 1399 | ea_t colPtr = (vft - sizeof(ea_t)); 1400 | fixEa(colPtr); 1401 | //cmt.cat_sprnt(" %s O: %d, A: %d (#classinformer)", attributeLabel(chdAttributes, numBaseClasses), offset, chdAttributes); 1402 | cmt.cat_sprnt(" %s (#classinformer)", attributeLabel(chdAttributes)); 1403 | if (!hasAnteriorComment(colPtr)) 1404 | setAnteriorComment(colPtr, "\n; %s %s", ((colName[3] == 'V') ? "class" : "struct"), cmt.c_str()); 1405 | 1406 | //vftable::processMembers(plainName, vft, end); 1407 | } 1408 | } 1409 | else 1410 | // Usually a typedef reference to a COL, not a vftable 1411 | { 1412 | #if 0 1413 | qstring tmp; 1414 | idaFlags2String(get_flags(vft), tmp); 1415 | msg(EAFORMAT" ** Vftable attached to this COL, error? (%s)\n", vft, tmp.c_str()); 1416 | #endif 1417 | 1418 | // Just set COL name 1419 | if (!hasName(col)) 1420 | { 1421 | #ifndef __EA64__ 1422 | ea_t typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor)); 1423 | #endif 1424 | char colName[MAXSTR]; 1425 | type_info::getName(typeInfo, colName, SIZESTR(colName)); 1426 | 1427 | char decorated[MAXSTR]; 1428 | _snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_COL, SKIP_TD_TAG(colName)); 1429 | setName(col, decorated); 1430 | } 1431 | } 1432 | 1433 | return result; 1434 | } 1435 | -------------------------------------------------------------------------------- /Plugin/RTTI.h: -------------------------------------------------------------------------------- 1 | 2 | // **************************************************************************** 3 | // File: RTTI.h 4 | // Desc: Run-Time Type Information (RTTI) support 5 | // 6 | // **************************************************************************** 7 | #pragma once 8 | 9 | namespace RTTI 10 | { 11 | #pragma pack(push, 1) 12 | 13 | // std::type_info class representation 14 | struct type_info 15 | { 16 | ea_t vfptr; // type_info class vftable 17 | ea_t _M_data; // NULL until loaded at runtime 18 | char _M_d_name[1]; // Mangled name (prefix: .?AV=classes, .?AU=structs) 19 | 20 | static BOOL isValid(ea_t typeInfo); 21 | static BOOL isTypeName(ea_t name); 22 | static int getName(ea_t typeInfo, __out LPSTR bufffer, int bufferSize); 23 | static void tryStruct(ea_t typeInfo); 24 | }; 25 | const UINT MIN_TYPE_INFO_SIZE = (offsetof(type_info, _M_d_name) + sizeof(".?AVx")); 26 | typedef type_info _TypeDescriptor; 27 | typedef type_info _RTTITypeDescriptor; 28 | 29 | // Base class "Pointer to Member Data" 30 | struct PMD 31 | { 32 | int mdisp; // 00 Member displacement 33 | int pdisp; // 04 Vftable displacement 34 | int vdisp; // 08 Displacement inside vftable 35 | }; 36 | 37 | // Describes all base classes together with information to derived class access dynamically 38 | // attributes flags 39 | const UINT BCD_NOTVISIBLE = 0x01; 40 | const UINT BCD_AMBIGUOUS = 0x02; 41 | const UINT BCD_PRIVORPROTINCOMPOBJ = 0x04; 42 | const UINT BCD_PRIVORPROTBASE = 0x08; 43 | const UINT BCD_VBOFCONTOBJ = 0x10; 44 | const UINT BCD_NONPOLYMORPHIC = 0x20; 45 | const UINT BCD_HASPCHD = 0x40; 46 | 47 | struct _RTTIBaseClassDescriptor 48 | { 49 | #ifndef __EA64__ 50 | ea_t typeDescriptor; // 00 Type descriptor of the class 51 | #else 52 | UINT typeDescriptor; // 00 Type descriptor of the class *X64 int32 offset 53 | #endif 54 | UINT numContainedBases; // 04 Number of nested classes following in the Base Class Array 55 | PMD pmd; // 08 Pointer-to-member displacement info 56 | UINT attributes; // 14 Flags 57 | // 18 When attributes & BCD_HASPCHD 58 | //_RTTIClassHierarchyDescriptor *classDescriptor; *X64 int32 offset 59 | 60 | static BOOL isValid(ea_t bcd, ea_t colBase64 = NULL); 61 | static void tryStruct(ea_t bcd, __out_bcount(MAXSTR) LPSTR baseClassName, ea_t colBase64 = NULL); 62 | }; 63 | 64 | // "Class Hierarchy Descriptor" describes the inheritance hierarchy of a class; shared by all COLs for the class 65 | // attributes flags 66 | const UINT CHD_MULTINH = 0x01; // Multiple inheritance 67 | const UINT CHD_VIRTINH = 0x02; // Virtual inheritance 68 | const UINT CHD_AMBIGUOUS = 0x04; // Ambiguous inheritance 69 | 70 | /* 71 | struct _RTTIBaseClassArray 72 | { 73 | _RTTIBaseClassDescriptor *arrayOfBaseClassDescriptors[]; 74 | }; 75 | */ 76 | 77 | struct _RTTIClassHierarchyDescriptor 78 | { 79 | UINT signature; // 00 Zero until loaded 80 | UINT attributes; // 04 Flags 81 | UINT numBaseClasses; // 08 Number of classes in the following 'baseClassArray' 82 | #ifndef __EA64__ 83 | ea_t baseClassArray; // 0C _RTTIBaseClassArray* 84 | #else 85 | UINT baseClassArray; // 0C *X64 int32 offset to _RTTIBaseClassArray* 86 | #endif 87 | 88 | static BOOL isValid(ea_t chd, ea_t colBase64 = NULL); 89 | static void tryStruct(ea_t chd, ea_t colBase64 = NULL); 90 | }; 91 | 92 | // "Complete Object Locator" location of the complete object from a specific vftable pointer 93 | struct _RTTICompleteObjectLocator 94 | { 95 | UINT signature; // 00 32bit zero, 64bit one, until loaded 96 | UINT offset; // 04 Offset of this vftable in the complete class 97 | UINT cdOffset; // 08 Constructor displacement offset 98 | #ifndef __EA64__ 99 | ea_t typeDescriptor; // 0C (type_info *) of the complete class 100 | ea_t classDescriptor; // 10 (_RTTIClassHierarchyDescriptor *) Describes inheritance hierarchy 101 | #else 102 | UINT typeDescriptor; // 0C (type_info *) of the complete class *X64 int32 offset 103 | UINT classDescriptor; // 10 (_RTTIClassHierarchyDescriptor *) Describes inheritance hierarchy *X64 int32 offset 104 | UINT objectBase; // 14 Object base offset (base = ptr col - objectBase) 105 | #endif 106 | 107 | static BOOL isValid(ea_t col); 108 | #ifndef __EA64__ 109 | static BOOL isValid2(ea_t col); 110 | #endif 111 | static BOOL tryStruct(ea_t col); 112 | }; 113 | #pragma pack(pop) 114 | 115 | const WORD IS_TOP_LEVEL = 0x8000; 116 | 117 | void freeWorkingData(); 118 | void addDefinitionsToIda(); 119 | BOOL processVftable(ea_t eaTable, ea_t col); 120 | } 121 | 122 | -------------------------------------------------------------------------------- /Plugin/StdAfx.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #define WIN32_LEAN_AND_MEAN 5 | #define WINVER 0x0601 // _WIN32_WINNT_WIN7 6 | #define _WIN32_WINNT 0x0601 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma intrinsic(memset, memcpy, strcat, strcmp, strcpy, strlen, abs, fabs, labs, atan, atan2, tan, sqrt, sin, cos) 17 | 18 | // IDA libs 19 | #define USE_DANGEROUS_FUNCTIONS 20 | #define USE_STANDARD_FILE_FUNCTIONS 21 | #define NO_OBSOLETE_FUNCS 22 | // Nix the many warning about int type conversions 23 | #pragma warning(push) 24 | #pragma warning(disable:4244) 25 | #pragma warning(disable:4267) 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #pragma warning(pop) 35 | 36 | // Qt libs 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | // IDA SDK Qt libs 47 | #pragma comment(lib, "Qt5Core.lib") 48 | #pragma comment(lib, "Qt5Gui.lib") 49 | #pragma comment(lib, "Qt5Widgets.lib") 50 | 51 | // QT_NO_UNICODE_LITERAL must be defined (best in preprocessor setting) 52 | // So Qt doesn't a static string pool that will cause IDA to crash on unload 53 | #ifndef QT_NO_UNICODE_LITERAL 54 | # error QT_NO_UNICODE_LITERAL must be defined to avoid Qt string crashes 55 | #endif 56 | 57 | #include 58 | #include "undname.h" 59 | 60 | #include 61 | #include 62 | 63 | typedef qlist eaList; 64 | typedef std::unordered_set eaSet; 65 | typedef std::unordered_map eaRefMap; // address & ref count 66 | 67 | //#define STYLE_PATH "C:/Projects/IDA Pro Work/IDA_ClassInformer_PlugIn/Plugin/" 68 | #define STYLE_PATH ":/classinf/" 69 | 70 | #define MY_VERSION MAKEWORD(5, 2) // Low, high, convention: 0 to 99 71 | -------------------------------------------------------------------------------- /Plugin/Vftable.cpp: -------------------------------------------------------------------------------- 1 | 2 | // **************************************************************************** 3 | // File: Vftable.cpp 4 | // Desc: Virtual function table parsing support 5 | // 6 | // **************************************************************************** 7 | #include "stdafx.h" 8 | #include "Main.h" 9 | #include "Vftable.h" 10 | #include "RTTI.h" 11 | 12 | /* 13 | namespace vftable 14 | { 15 | int tryKnownMember(LPCTSTR name, ea_t eaMember); 16 | }; 17 | */ 18 | 19 | // Attempt to get information of and fix vftable at address 20 | // Return TRUE along with info if valid vftable parsed at address 21 | BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) 22 | { 23 | // Start of a vft should have an xref and a name (auto, or user, etc). 24 | // Ideal flags 32bit: FF_DWRD, FF_0OFF, FF_REF, FF_NAME, FF_DATA, FF_IVL 25 | //dumpFlags(ea); 26 | flags_t flags = get_flags(ea); 27 | if(has_xref(flags) && has_any_name(flags) && (isEa(flags) || is_unknown(flags))) 28 | { 29 | ZeroMemory(&info, sizeof(vtinfo)); 30 | 31 | // Get raw (auto-generated mangled, or user named) vft name 32 | //if (!get_name(BADADDR, ea, info.name, SIZESTR(info.name))) 33 | // msg(EAFORMAT" ** vftable::getTableInfo(): failed to get raw name!\n", ea); 34 | 35 | // Determine the vft's method count 36 | ea_t start = info.start = ea; 37 | while (TRUE) 38 | { 39 | // Should be an ea_t sized offset to a function here (could be unknown if dirty IDB) 40 | // Ideal flags for 32bit: FF_DWRD, FF_0OFF, FF_REF, FF_NAME, FF_DATA, FF_IVL 41 | //dumpFlags(ea); 42 | flags_t indexFlags = get_flags(ea); 43 | if (!(isEa(indexFlags) || is_unknown(indexFlags))) 44 | { 45 | //msg(" ******* 1\n"); 46 | break; 47 | } 48 | 49 | // Look at what this (assumed vftable index) points too 50 | ea_t memberPtr = getEa(ea); 51 | if (!(memberPtr && (memberPtr != BADADDR))) 52 | { 53 | // vft's often have a trailing zero ea_t (alignment, or?), fix it 54 | if (memberPtr == 0) 55 | fixEa(ea); 56 | 57 | //msg(" ******* 2\n"); 58 | break; 59 | } 60 | 61 | // Should see code for a good vft method here, but it could be dirty 62 | flags_t flags = get_flags(memberPtr); 63 | if (!(is_code(flags) || is_unknown(flags))) 64 | { 65 | // New for version 2.5: there are rare cases where IDA hasn't fix unresolved bytes 66 | // So except if the member pointer is in a code segment as a 2nd chance 67 | if (segment_t *s = getseg(memberPtr)) 68 | { 69 | if (s->type != SEG_CODE) 70 | { 71 | //msg(" ******* 3\n"); 72 | break; 73 | } 74 | } 75 | else 76 | { 77 | //msg(" ******* 3.5\n"); 78 | break; 79 | } 80 | } 81 | 82 | 83 | if (ea != start) 84 | { 85 | // If we see a ref after first index it's probably the beginning of the next vft or something else 86 | if (has_xref(indexFlags)) 87 | { 88 | //msg(" ******* 4\n"); 89 | break; 90 | } 91 | 92 | // If we see a COL here it must be the start of another vftable 93 | if (RTTI::_RTTICompleteObjectLocator::isValid(memberPtr)) 94 | { 95 | //msg(" ******* 5\n"); 96 | break; 97 | } 98 | } 99 | 100 | // As needed fix ea_t pointer, and, or, missing code and function def here 101 | fixEa(ea); 102 | fixFunction(memberPtr); 103 | 104 | ea += sizeof(ea_t); 105 | }; 106 | 107 | // Reached the presumed end of it 108 | if ((info.methodCount = ((ea - start) / sizeof(ea_t))) > 0) 109 | { 110 | info.end = ea; 111 | //msg(" vftable: "EAFORMAT"-"EAFORMAT", methods: %d\n", rtInfo.eaStart, rtInfo.eaEnd, rtInfo.uMethods); 112 | return(TRUE); 113 | } 114 | } 115 | 116 | //dumpFlags(ea); 117 | return(FALSE); 118 | } 119 | 120 | 121 | // Get relative jump target address 122 | /* 123 | static ea_t getRelJmpTarget(ea_t eaAddress) 124 | { 125 | BYTE bt = get_byte(eaAddress); 126 | if(bt == 0xEB) 127 | { 128 | bt = get_byte(eaAddress + 1); 129 | if(bt & 0x80) 130 | return(eaAddress + 2 - ((~bt & 0xFF) + 1)); 131 | else 132 | return(eaAddress + 2 + bt); 133 | } 134 | else 135 | if(bt == 0xE9) 136 | { 137 | UINT dw = get_32bit(eaAddress + 1); 138 | if(dw & 0x80000000) 139 | return(eaAddress + 5 - (~dw + 1)); 140 | else 141 | return(eaAddress + 5 + dw); 142 | } 143 | else 144 | return(BADADDR); 145 | } 146 | */ 147 | 148 | /* 149 | #define SN_constructor 1 150 | #define SN_destructor 2 151 | #define SN_vdestructor 3 152 | #define SN_scalardtr 4 153 | #define SN_vectordtr 5 154 | */ 155 | 156 | // Try to identify and place known class member types 157 | /* 158 | int vftable::tryKnownMember(LPCTSTR name, ea_t eaMember) 159 | { 160 | int iType = 0; 161 | 162 | #define IsPattern(Address, Pattern) (find_binary(Address, Address+(SIZESTR(Pattern)/2), Pattern, 16, (SEARCH_DOWN | SEARCH_NOBRK | SEARCH_NOSHOW)) == Address) 163 | 164 | if(eaMember && (eaMember != BADADDR)) 165 | { 166 | // Skip if it already has a name 167 | flags_t flags = get_flags((ea_t) eaMember); 168 | if(!has_name(flags) || has_dummy_name(flags)) 169 | { 170 | // Should be code 171 | if(is_code(flags)) 172 | { 173 | ea_t eaAddress = eaMember; 174 | 175 | // E9 xx xx xx xx jmp xxxxxxx 176 | BYTE Byte = get_byte(eaAddress); 177 | if((Byte == 0xE9) ||(Byte == 0xEB)) 178 | { 179 | return(tryKnownMember(name, getRelJmpTarget(eaAddress))); 180 | } 181 | else 182 | if(IsPattern(eaAddress, " ")) 183 | { 184 | 185 | } 186 | } 187 | else 188 | msg(" "EAFORMAT" ** Not code at this member! **\n", eaMember); 189 | } 190 | } 191 | 192 | return(iType); 193 | } 194 | */ 195 | 196 | /* 197 | TODO: On hold for now. 198 | Do we really care about detected ctors and dtors? 199 | Is it helpful vs the problems of naming member functions? 200 | */ 201 | 202 | 203 | // Process vftable member functions 204 | /* 205 | // TODO: Just try the fix missing function code 206 | void vftable::processMembers(LPCTSTR lpszName, ea_t eaStart, ea_t eaEnd) 207 | { 208 | //msg(" "EAFORMAT" to "EAFORMAT"\n", eaStart, eaEnd); 209 | 210 | ea_t eaAddress = eaStart; 211 | 212 | while(eaAddress < eaEnd) 213 | { 214 | ea_t eaMember; 215 | if(GetVerify32_t(eaAddress, eaMember)) 216 | { 217 | // Missing/bad code? 218 | if(!get_func(eaMember)) 219 | { 220 | //msg(" "EAFORMAT" ** No member function here! **\n", eaMember); 221 | fixFunction(eaMember); 222 | } 223 | 224 | tryKnownMember(lpszName, eaMember); 225 | } 226 | else 227 | msg(" "EAFORMAT" ** Failed to read member pointer! **\n", eaAddress); 228 | 229 | eaAddress += 4; 230 | }; 231 | } 232 | */ -------------------------------------------------------------------------------- /Plugin/Vftable.h: -------------------------------------------------------------------------------- 1 | 2 | // **************************************************************************** 3 | // File: Vftable.h 4 | // Desc: Virtual function table parsing support 5 | // 6 | // **************************************************************************** 7 | #pragma once 8 | 9 | namespace vftable 10 | { 11 | // vftable info container 12 | struct vtinfo 13 | { 14 | ea_t start, end; 15 | int methodCount; 16 | //char name[MAXSTR]; 17 | }; 18 | 19 | BOOL getTableInfo(ea_t ea, vtinfo &info); 20 | 21 | // Returns TRUE if mangled name indicates a vftable 22 | inline BOOL isValid(LPCSTR name){ return(*((PDWORD) name) == 0x375F3F3F /*"??_7"*/); } 23 | 24 | // Identify and name common member functions 25 | //void processMembers(LPCTSTR name, ea_t eaStart, ea_t eaEnd); 26 | } 27 | -------------------------------------------------------------------------------- /Plugin/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcx/classinformer-ida7/2a07f0ce48498d4066c8caeee499460d9328ec82/Plugin/banner.png -------------------------------------------------------------------------------- /Plugin/checkbox-checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcx/classinformer-ida7/2a07f0ce48498d4066c8caeee499460d9328ec82/Plugin/checkbox-checked.png -------------------------------------------------------------------------------- /Plugin/completed.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcx/classinformer-ida7/2a07f0ce48498d4066c8caeee499460d9328ec82/Plugin/completed.ogg -------------------------------------------------------------------------------- /Plugin/dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainCIDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 292 10 | 311 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 292 22 | 311 23 | 24 | 25 | 26 | 27 | 292 28 | 311 29 | 30 | 31 | 32 | Class Informer 33 | 34 | 35 | 36 | :/classinf/icon.png:/classinf/icon.png 37 | 38 | 39 | 40 | 41 | 42 | true 43 | 44 | 45 | 46 | 47 | 120 48 | 272 49 | 156 50 | 24 51 | 52 | 53 | 54 | Qt::Horizontal 55 | 56 | 57 | QDialogButtonBox::NoButton 58 | 59 | 60 | false 61 | 62 | 63 | 64 | 65 | 66 | 15 67 | 94 68 | 121 69 | 17 70 | 71 | 72 | 73 | 74 | Noto Sans 75 | 10 76 | 77 | 78 | 79 | 80 | 81 | 82 | Place structures 83 | 84 | 85 | 86 | 87 | 88 | 15 89 | 122 90 | 256 91 | 17 92 | 93 | 94 | 95 | 96 | Noto Sans 97 | 10 98 | 99 | 100 | 101 | 102 | 103 | 104 | Process static initializers && terminators 105 | 106 | 107 | 108 | 109 | 110 | 15 111 | 148 112 | 151 113 | 17 114 | 115 | 116 | 117 | 118 | Noto Sans 119 | 10 120 | 121 | 122 | 123 | 124 | 125 | 126 | Audio on completion 127 | 128 | 129 | 130 | 131 | 132 | 15 133 | 225 134 | 141 135 | 16 136 | 137 | 138 | 139 | 140 | Noto Sans 141 | 10 142 | 143 | 144 | 145 | QFrame::Sunken 146 | 147 | 148 | <a href="http://www.macromonkey.com/bb/index.php/topic,13.0.html" style="color:#AA00FF;">Class Informer Fourm</a> 149 | 150 | 151 | Qt::AutoText 152 | 153 | 154 | true 155 | 156 | 157 | 158 | 159 | 160 | 0 161 | 0 162 | 292 163 | 74 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | Qt::PlainText 174 | 175 | 176 | :/classinf/banner.png 177 | 178 | 179 | Qt::NoTextInteraction 180 | 181 | 182 | 183 | 184 | 185 | 225 186 | 44 187 | 61 188 | 24 189 | 190 | 191 | 192 | 193 | Noto Sans 194 | 9 195 | 196 | 197 | 198 | 199 | 200 | 201 | Version: 2.6 202 | By Sirmabus 203 | 204 | 205 | Qt::PlainText 206 | 207 | 208 | Qt::NoTextInteraction 209 | 210 | 211 | 212 | 213 | 214 | 15 215 | 186 216 | 129 217 | 27 218 | 219 | 220 | 221 | 222 | Noto Sans 223 | 10 224 | 225 | 226 | 227 | <html><head/><body><p>Optionally select wich segments to scan for strings.</p></body></html> 228 | 229 | 230 | SELECT SEGMENTS 231 | 232 | 233 | false 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | buttonBox 244 | accepted() 245 | MainCIDialog 246 | accept() 247 | 248 | 249 | 248 250 | 254 251 | 252 | 253 | 157 254 | 274 255 | 256 | 257 | 258 | 259 | buttonBox 260 | rejected() 261 | MainCIDialog 262 | reject() 263 | 264 | 265 | 316 266 | 260 267 | 268 | 269 | 286 270 | 274 271 | 272 | 273 | 274 | 275 | pushButton1 276 | pressed() 277 | MainCIDialog 278 | segmentSelect() 279 | 280 | 281 | 79 282 | 228 283 | 284 | 285 | 145 286 | 169 287 | 288 | 289 | 290 | 291 | 292 | segmentSelect() 293 | 294 | 295 | -------------------------------------------------------------------------------- /Plugin/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcx/classinformer-ida7/2a07f0ce48498d4066c8caeee499460d9328ec82/Plugin/icon.png -------------------------------------------------------------------------------- /Plugin/progress-style.qss: -------------------------------------------------------------------------------- 1 | 2 | QWidget 3 | { 4 | color: #C0C0C0; 5 | background-color: #303030; 6 | 7 | font-family: Noto Sans, Tahoma; 8 | font-size: 13px; 9 | font-style: normal; 10 | } 11 | 12 | QPushButton 13 | { 14 | font-weight: bold; 15 | padding: 7px; 16 | min-width: 37px; 17 | border-style: none; 18 | } 19 | QPushButton:hover 20 | { 21 | background-color: #4A4A4A; 22 | } 23 | QPushButton:pressed 24 | { 25 | background-color: #595959; 26 | } 27 | QPushButton:focus 28 | { 29 | background-color: #4A4A4A; 30 | } 31 | 32 | QProgressBar 33 | { 34 | background-color: #4E4E4E; 35 | border-style: none; 36 | } 37 | QProgressBar::chunk 38 | { 39 | background-color: #AB47BC; 40 | } 41 | -------------------------------------------------------------------------------- /Plugin/style.qss: -------------------------------------------------------------------------------- 1 | 2 | /* Class Informer Stylesheet by Sirmabus */ 3 | /* Rev 1.0 Feb 22, 2015 */ 4 | /* Dark theme, with some Google Material Design elements in mind */ 5 | 6 | /* Parent */ 7 | QWidget 8 | { 9 | color: #E0E0E0; 10 | background-color: #303030; 11 | 12 | font-family: Noto Sans, Tahoma; 13 | font-size: 13px; 14 | font-style: normal; 15 | } 16 | 17 | /* Push buttons */ 18 | /* MD flat style */ 19 | QPushButton 20 | { 21 | color: #FFF176; 22 | font-weight: bold; 23 | padding: 7px; 24 | min-width: 37px; 25 | border-style: none; 26 | } 27 | QPushButton:hover 28 | { 29 | background-color: #4A4A4A; 30 | } 31 | QPushButton:pressed 32 | { 33 | background-color: #595959; 34 | } 35 | QPushButton:focus 36 | { 37 | background-color: #4A4A4A; 38 | } 39 | 40 | /* Option push button */ 41 | QPushButton#pushButton1 42 | { 43 | color: #CE93D8; 44 | background-color: #3F3F3D; 45 | } 46 | QPushButton#pushButton1:hover 47 | { 48 | background-color: #505050; 49 | } 50 | QPushButton#pushButton1:pressed 51 | { 52 | background-color: #5F5F5D; 53 | } 54 | 55 | QDialogButtonBox 56 | { 57 | /* MD typeically has the cancel/reject button first */ 58 | button-layout: 1; 59 | } 60 | 61 | /* Version label */ 62 | QLabel#versionLabel 63 | { 64 | color: #AB47BC; 65 | font-size: 10px; 66 | background-color: transparent; 67 | } 68 | 69 | /* Hyperlink */ 70 | /* The actual link color is set inside the link text, see UI file */ 71 | QLabel#linkLabel 72 | { 73 | height: 50px; 74 | } 75 | /* Despite what the Qt docs says ':hover' works, albeit limited control */ 76 | QLabel#linkLabel:hover 77 | { 78 | background-color: #4A4A4A; 79 | } 80 | 81 | QCheckBox::indicator 82 | { 83 | background-color: #303030; 84 | border: 2px solid #E4E4E4; 85 | border-radius: 1px; 86 | width: 10px; 87 | height: 10px; 88 | } 89 | QCheckBox::indicator:checked 90 | { 91 | border: 2px solid #CE93D8; 92 | border-radius: 1px; 93 | width: 10px; 94 | height: 10px; 95 | image: url(:/classinf/checkbox-checked.png); 96 | 97 | } 98 | QCheckBox::hover 99 | { 100 | background-color: #4A4A4A; 101 | } 102 | QCheckBox::indicator:unchecked:hover 103 | { 104 | background-color: #4A4A4A; 105 | } 106 | 107 | /* ---- For char set select dialog ---- */ 108 | 109 | QHeaderView 110 | { 111 | border-top: 0px; 112 | border-bottom: 3px solid #C8C8C8; 113 | } 114 | QHeaderView::section 115 | { 116 | height: 23px; 117 | 118 | font-family: Noto Sans,Consolas; 119 | font-weight: bold; 120 | 121 | color: #FFFFFF; 122 | background-color: #9575CD; 123 | border: 0px; 124 | } 125 | 126 | QTableView 127 | { 128 | font-family: Noto Sans,Consolas; 129 | color: #404040; 130 | background-color: #FDFDFD; 131 | selection-color: #404040; 132 | selection-background-color: #FDFDFD; 133 | } 134 | 135 | /* QTableView seperator line */ 136 | QTableWidget::item 137 | { 138 | border-bottom: 1px solid #EEEEEE; 139 | } 140 | -------------------------------------------------------------------------------- /Plugin/undname.h: -------------------------------------------------------------------------------- 1 | 2 | // Access to CRT C++ demangler/undecorator function 3 | #pragma once 4 | 5 | // Online: http://demangler.com/ 6 | 7 | typedef PVOID (__cdecl * _Alloc)(UINT); 8 | typedef void (__cdecl * _Free)(PVOID); 9 | 10 | const UINT UNDNAME_COMPLETE = 0x00000; // Enable full undecoration 11 | const UINT UNDNAME_NO_LEADING_UNDERSCORES = 0x00001; // Remove leading underscores from MS extended keywords 12 | const UINT UNDNAME_NO_MS_KEYWORDS = 0x00002; // Disable expansion of MS extended keywords 13 | const UINT UNDNAME_NO_FUNCTION_RETURNS = 0x00004; // Disable expansion of return type for primary declaration 14 | const UINT UNDNAME_NO_ALLOCATION_MODEL = 0x00008; // Disable expansion of the declaration model 15 | const UINT UNDNAME_NO_ALLOCATION_LANGUAGE = 0x00010; // Disable expansion of the declaration language specifier 16 | const UINT UNDNAME_NO_MS_THISTYPE = 0x00020; // Disable expansion of MS keywords on the 'this' type for primary declaration 17 | const UINT UNDNAME_NO_CV_THISTYPE = 0x00040; // Disable expansion of CV modifiers on the 'this' type for primary declaration 18 | const UINT UNDNAME_NO_THISTYPE = 0x00060; // Disable all modifiers on the 'this' type 19 | const UINT UNDNAME_NO_ACCESS_SPECIFIERS = 0x00080; // Disable expansion of access specifiers for members 20 | const UINT UNDNAME_NO_THROW_SIGNATURES = 0x00100; // Disable expansion of 'throw-signatures' for functions and pointers to functions 21 | const UINT UNDNAME_NO_MEMBER_TYPE = 0x00200; // Disable expansion of 'static' or 'virtual'ness of members 22 | const UINT UNDNAME_NO_RETURN_UDT_MODEL = 0x00400; // Disable expansion of MS model for UDT returns 23 | const UINT UNDNAME_32_BIT_DECODE = 0x00800; // Undecorate 32-bit decorated names 24 | const UINT UNDNAME_NAME_ONLY = 0x01000; // Crack only the name for primary declaration; return just [scope::]name. Does expand template params 25 | const UINT UNDNAME_TYPE_ONLY = 0x02000; // Input is just a type encoding; compose an abstract declarator 26 | const UINT UNDNAME_HAVE_PARAMETERS = 0x04000; // The real templates parameters are available 27 | const UINT UNDNAME_NO_ECSU = 0x08000; // Suppress enum/class/struct/union 28 | const UINT UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000; // Suppress check for IsValidIdentChar 29 | 30 | inline PVOID mallocWrap(UINT size) { return malloc((UINT) size); } 31 | 32 | /* 33 | To supply a buffer to use use 'buffer' and 'sizeBuffer', else for a allocated buffer 34 | 'buffer' = NULL, 'sizeBuffer' = 0, and use the return string. 35 | Call Free on the return result when done with the string. 36 | Note: CRT documentation error, the Allocator and Free must be supplied regardless if supplied or allocation buffer method desired. 37 | */ 38 | // https://www.winehq.org/pipermail/wine-patches/2004-January/009183.html 39 | extern "C" LPSTR __cdecl __unDName(__out LPSTR buffer, __in LPCSTR name, int sizeBuffer, _Alloc allocator, _Free _free, UINT flags); -------------------------------------------------------------------------------- /Plugin/view-style.qss: -------------------------------------------------------------------------------- 1 | 2 | /* Make the table easier to read */ 3 | QHeaderView 4 | { 5 | font-family: Noto Sans,Consolas; 6 | font-weight: 100; 7 | font-size: 12px; 8 | } 9 | QTableView 10 | { 11 | font-family: Noto Sans,Consolas; 12 | font-weight: 100; 13 | font-size: 14px; 14 | } 15 | 16 | /* Color the status bar */ 17 | QStatusBar 18 | { 19 | color: #F0F0F0; 20 | background-color: #9575CD; 21 | } 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ClassInformer for IDA 7.0 2 | 3 | Originally by sirmabus, backported to IDA 7.0. For IDA 7.1, the orignal author has released an [official build](https://sourceforge.net/projects/classinformer/). Unforunately for those of us who are too broke to afford it we need 7.0 :P 4 | 5 | Compiled binaries over at the [Releases](../../releases). **If it crashes, use the Debug build and provide a crashdump and crash log! Otherwise I can't fix the issue** 6 | 7 | # How to compile it 8 | 9 | The process for compiling classinformer can be involved. To streamline the dependency collection process three macros are in place: 10 | 1. $(IDADIR) 11 | 2. $(QTDIR) 12 | 3. $(IDASUPPORT) 13 | 14 | To set the paths, go to the Property Manager tab in Solution Explorer, and edit PropertySheet. 15 | It's not important which configuration you edit PropertySheet in, they all use the same file. 16 | Then go to Common Properties -> User Macros and set up macros to paths like below: 17 | 18 | ### $(IDADIR) 19 | This should be your IDA root directory (the directory containing ida.exe). 20 | Put your IDA SDK directory (idasdk70) into this directory. 21 | So your directory structure may look something like: 22 | 23 | ``` 24 | C:\Program Files\IDA 7.0 $(IDADIR) 25 | +--- idasdk70 26 | +--- include 27 | +--- lib 28 | +--- ida.exe 29 | +--- ida64.exe 30 | ``` 31 | 32 | ### $(QTDIR) 33 | You need a QT SDK installation to pregenerate the gui files. 34 | Your directory structure may look something like: 35 | 36 | ``` 37 | C:\Program FIles\Qt\qt-5.6.0-x64-msvc2015\5.6\msvc2015_64 38 | +--- bin 39 | +--- lib 40 | +--- include 41 | ``` 42 | 43 | ### $(IDASUPPORT) 44 | You need some support libraries that sirmabus wrote, ported for IDA 7. 45 | Setup a directory to hold all of these libraries: 46 | ``` 47 | idasupport 48 | +--- IDA_SegmentSelect (https://github.com/ecx86/IDA7-SegmentSelect) 49 | +--- IDA_OggPlayer (https://github.com/ecx86/IDA7-OggPlayer) 50 | +--- IDA_WaitBoxEx-7.0 (https://github.com/dude719/IDA_WaitBoxEx-7.0) 51 | +--- SupportLib (https://github.com/ecx86/IDA7-SupportLib) 52 | ``` 53 | Each of these repositories should have the Release .lib precompiled for you. 54 | If they are not, you can compile them using a process similar to the one used to compile this project. 55 | 56 | After your paths are setup, you are ready to compile. 57 | Use Release for the ida.exe plugin, and Release64 for the ida64.exe plugin. 58 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /property:Platform=x64 /property:Configuration=Debug /t:Clean,Build 2 | "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /property:Platform=x64 /property:Configuration=Debug64 /t:Clean,Build 3 | "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /property:Platform=x64 /property:Configuration=Release /t:Clean,Build 4 | "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /property:Platform=x64 /property:Configuration=Release64 /t:Clean,Build 5 | pause 6 | --------------------------------------------------------------------------------