Showing preview only (626K chars total). The displayed content is truncated. Use the JSON API for full output.
Repository: herosi/classinformer
Branch: main
Commit: 3342afe4ed49
Files: 97
Total size: 597.6 KB
Directory structure:
gitextract_80tmnr81/
├── .gitignore
├── README.md
├── classinformer-code/
│ ├── IDA_ClassInformer.sln
│ ├── Plugin/
│ │ ├── ClassInformerRes.qrc
│ │ ├── Class_Informer.txt
│ │ ├── IDA_ClassInformer_PlugIn.vcxproj
│ │ ├── IDA_ClassInformer_PlugIn.vcxproj.filters
│ │ ├── IDA_ClassInformer_PlugIn.vcxproj.user
│ │ ├── Main.cpp
│ │ ├── Main.h
│ │ ├── MainDialog.cpp
│ │ ├── MainDialog.h
│ │ ├── PropertySheet.props
│ │ ├── RTTI.cpp
│ │ ├── RTTI.h
│ │ ├── StdAfx.h
│ │ ├── Vftable.cpp
│ │ ├── Vftable.h
│ │ ├── completed.ogg
│ │ ├── dialog.ui
│ │ ├── progress-style.qss
│ │ ├── style.qss
│ │ ├── undname.h
│ │ └── view-style.qss
│ └── README.md
└── ida-support-library-code/
├── IDA_OggPlayer/
│ ├── IDA_OggPlayer.sln
│ ├── IDA_OggPlayer.vcxproj
│ ├── IDA_OggPlayer.vcxproj.filters
│ ├── IDA_OggPlayer.vcxproj.user
│ ├── IdaOgg.cpp
│ ├── IdaOgg.h
│ ├── IdaOggPlayer.LiB
│ ├── IdaOggPlayer.pdb
│ ├── IdaOggPlayer64.LiB
│ ├── IdaOggPlayer64.pdb
│ ├── IdaOggPlayer64D.LiB
│ ├── IdaOggPlayer64D.pdb
│ ├── IdaOggPlayerD.LiB
│ ├── IdaOggPlayerD.pdb
│ ├── PropertySheet.props
│ ├── original README.md
│ ├── stb_vorbis.cpp
│ ├── stb_vorbis.h
│ └── stb_vorbis.txt
├── IDA_SegmentSelect/
│ ├── IDA_SegmentSelect.sln
│ ├── Lib/
│ │ ├── PropertySheet.props
│ │ ├── SegSelect.cpp
│ │ ├── SegSelect.h
│ │ ├── SegSelectRes.qrc
│ │ ├── SegmentDialog.h
│ │ ├── SegmentDialog.ui
│ │ ├── lib.vcxproj
│ │ ├── lib.vcxproj.filters
│ │ └── lib.vcxproj.user
│ ├── SegSelect.LiB
│ ├── SegSelect.h
│ ├── SegSelect64.LiB
│ ├── SegSelect64D.LiB
│ └── SegSelectD.LiB
├── IDA_WaitEx/
│ ├── IDA_WaitBoxEx.sln
│ ├── IDA_WaitBoxEx.txt
│ ├── Lib/
│ │ ├── MyQProgressDialog.h
│ │ ├── PropertySheet.props
│ │ ├── WaitBoxEx.cpp
│ │ ├── WaitBoxEx.h
│ │ ├── WinTaskProgress.cpp
│ │ ├── WinTaskProgress.h
│ │ ├── lib.vcxproj
│ │ ├── lib.vcxproj.filters
│ │ └── lib.vcxproj.user
│ ├── Plugin Example/
│ │ ├── Plugin Example.vcxproj
│ │ ├── Plugin Example.vcxproj.filters
│ │ ├── Plugin Example.vcxproj.user
│ │ └── WaitBoxEx_Example.cpp
│ ├── WaitBoxEx.LiB
│ ├── WaitBoxEx.h
│ ├── WaitBoxEx.pdb
│ ├── WaitBoxEx64.LiB
│ ├── WaitBoxEx64.pdb
│ ├── WaitBoxExD.LiB
│ ├── WaitBoxExD.pdb
│ ├── WaitBoxExD64.LiB
│ ├── WaitBoxExD64.pdb
│ ├── WaitBoxExMd.LiB
│ ├── WaitBoxExMd.pdb
│ ├── WaitBoxExMd64.LiB
│ ├── WaitBoxExMd64.pdb
│ ├── WaitBoxExMdD.LiB
│ ├── WaitBoxExMdD.pdb
│ ├── WaitBoxExMdD64.LiB
│ └── WaitBoxExMdD64.pdb
├── README.md
└── SupportLib/
├── SupportLib.sln
├── SupportLib.vcxproj
├── SupportLib.vcxproj.user
├── Utility.cpp
└── Utility.h
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.vs
classinformer-code/x64/
classinformer-code/Plugin/x64/
classinformer-code/Plugin/GeneratedFiles
================================================
FILE: README.md
================================================
# Class Informer
Use the original classinformer (See the URL below).
https://github.com/kweatherman/IDA_ClassInformer_PlugIn
The original author, Kevin Weatherman aka "Sirmabus", now released the plugin for IDA 9 on the URL above.
So the puprose of this repositry is now over!
It's time to archive this repositry.
---------------------------------
IDA Class Informer plugin for IDA Pro 9 and 8. It is just a ported version of the [original classinformer](https://sourceforge.net/projects/classinformer/) to work on IDA 8 and 9. Therefore, I will not actively develop it. If you want to improve it, send the PR to me. Do not open an issue for improvement requests.
- This plugin has been tested with IDA Pro `9.1`, `9.0 SP1`, `9.0`, `8.4 SP2`, `8.2 SP1` and `8.0` on both 32-bit and 64-bit versions.
- ***IMPORTANT!!!*** IDA Pro 9.0 ***beta*** is NOT supported. Use released versions.
- IDA Pro 7.x cannot load this plugin. Use [the original one](https://sourceforge.net/projects/classinformer/).
- **This plugin only supports parsing MSVC++'s RTTI on PE formatted binaries for x86, x64, ARM and ARM64 for Windows.** I WILL NOT support GCC's RTTI and other architectures.
- For IDA 9, you just need to install `ClassInformer64.dll`.
- For IDA 8, you need to install both `ClassInformer_IDA8x64.dll` and `ClassInformer_IDA8x.dll`.
- If you have both IDA 8 and 9 on your machine, copy them to the IDA's directories according to the versions, or copy all dlls into `%IDAUSR%\plugins`.
- If you do not know about IDAUSR, see [this blog post](https://hex-rays.com/blog/igors-tip-of-the-week-33-idas-user-directory-idausr).
## Download
- You can download compiled binaries from the [Releases](../../releases) section.
================================================
FILE: classinformer-code/IDA_ClassInformer.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35122.118
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugIn", "Plugin\IDA_ClassInformer_PlugIn.vcxproj", "{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug64|x64 = Debug64|x64
Release_IDA8x|x64 = Release_IDA8x|x64
Release|x64 = Release|x64
Release64_IDA8x|x64 = Release64_IDA8x|x64
Release64|x64 = Release64|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug|x64.ActiveCfg = Debug|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug|x64.Build.0 = Debug|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug64|x64.ActiveCfg = Debug64|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Debug64|x64.Build.0 = Debug64|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release_IDA8x|x64.ActiveCfg = Release_IDA8x|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release_IDA8x|x64.Build.0 = Release_IDA8x|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release|x64.ActiveCfg = Release|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release64_IDA8x|x64.ActiveCfg = Release64_IDA8x|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release64_IDA8x|x64.Build.0 = Release64_IDA8x|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release64|x64.ActiveCfg = Release64|x64
{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}.Release64|x64.Build.0 = Release64|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {77D3BE15-1509-4763-B26C-456ED1078906}
Qt5Version = 5.6.0
EndGlobalSection
EndGlobal
================================================
FILE: classinformer-code/Plugin/ClassInformerRes.qrc
================================================
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/classinf">
<file>banner.png</file>
<file>icon.png</file>
<file>completed.ogg</file>
<file>checkbox-checked.png</file>
<file>progress-style.qss</file>
<file>style.qss</file>
<file>view-style.qss</file>
</qresource>
</RCC>
================================================
FILE: classinformer-code/Plugin/Class_Informer.txt
================================================
Class Informer for IDA 9:
===========================================================
IDA Pro class vftable finder, namer, fixer, lister plug-in.
Version 2.92, March 2025
By Rohitab Batra and Hiroshi Suzuki
https://github.com/herosi/classinformer
Version 2.9, August 2024
By Rohitab Batra
https://github.com/rohitab/ClassInformer
Source code is backwards compatible with IDA 8 and 7.
Version 2.8 was the initial release with support for IDA 9.
Class Informer for IDA 8:
===========================================================
IDA Pro class vftable finder, namer, fixer, lister plug-in.
Version 2.7, January 2023
By Hiroshi Suzuki (By Sirmabus originally)
https://github.com/herosi/classinformer/
I tested on ida 8.2.
Original:
https://sourceforge.net/projects/classinformer/
http://www.macromonkey.com/bb/index.php/topic,13.0.html
---------------------------------------------------------
Scans MSVC target IDBs for vftables with C++ RTTI data.
Places structures, names, labels, and comments to class vftables
(Virtual Function Table) to aid reverse engineering.
Also further assists by defining and associating known data structures.
Creates a list window for browsing by object name.
RTTI ("Run-Time Type Identification"):
http://en.wikipedia.org/wiki/RTTI
It's currently targeted for Microsoft Visual C++ complied binaries only.
Unpredictable results if used on other targets.
Based off article by Igor Skochinsky:
http://www.openrce.org/articles/full_view/23
Updated
http://www.hexblog.com/wp-content/uploads/2012/06/
Recon-2012-Skochinsky-Compiler-Internals.pdf
-- [Install] --------------------------------------------
Copy the plug-in to your IDA Pro "plugins" directory.
Then edit your "..\plugins\plugins.cfg" to setup with a hotkey.
IE: Add these two lines:
; Sirmabus "Class Informer" plug-in
Class-Informer IDA_ClassInformer_PlugIn.plw Alt-2 0
See IDA documentation for more on installing and using plug-ins.
-- [How to run it] --------------------------------------
Invoke as usual in IDA with an assigned hot key, or through IDA's
"Edit->Plugins" menu.
Dialog Options:
"Place structures": Uncheck this if you don't want RTTI data structures to be
defined and placed; instead individual data elements will be cleaned up and
placed with additional comments.
"Process static initializers & terminators": If unchecked the processing of
static ctor and dtor tables will be skipped.
"Overwrite anterior comments": Check if you want existing anterior (above)
comments be erased and overwritten. Class Informer will place separation and
information comments above vftables, etc. Default unchecked.
"Audio on completion": Uncheck this if you don't want any audio completion
sound.
On completion a list window will come up showing any found vftables and
relevant class information.
Lines with multiple inheritance that are not the main class will be colored
gray.
Click on a line to jump to it's vftable.
Example list output:
0046769C 077 CEdit:CWnd, CCmdTarget, CObject; (SI)
This is: vftable address, method count, and class hierarchy ended with some
additional class info.
To make things easier to read, all known type names are considered to be a
"class" unless explicitly proceeded with "struct" to indicate "structure" type.
The addition info at the end:
"(SI)" single inheritance hierarchy, "(MI)" multiple inheritance,
"(VI)" virtual inheritance, or "(MI VI)" multiple virtual inheritance.
-- [Design] ---------------------------------------------
I read Igor Skochinsky's excellent article:
"Reversing Microsoft Visual C++". And ran some his IDC accompanying scripts.
I was amazed at how well it worked on identifying vftables with a gold mine of
type information and how it helped clean up an IDB by defining data structures.
But the scripts had several problems and I wanted to put it into a plug-in
anyhow for speed, flexibility, and to build as a general test bed for class
information and research.
I originally I had in mind some sort of automatic object member naming.
But after doing real world tests I found it wasn't so useful.
For my RE work I really just need to see these classes by name, and then where
to find them for closer examination. Then adding automatic fixing and labeling
of ctor and dtor tables is a bonus.
As of version 2.0 switched to a different RTTI finding/scanning scheme.
No longer scanning and locating vftables first. Now "Complete Object Locator"
are located directly. This leads to more accuracy; less vftables are missed.
-- [Thanks and Appreciation] ----------------------------
To Igor Skochinsky for the RTTI information and inspiration.
To "sh!ft" for the source code to his version, and ideas that lead to the new
improved scanning scheme.
To "jlnsrk" for the reversed 64 bit RTTI version information.
To Chris Eagle for mentioning Class Informer in his book:
"The IDA Pro Book: The Unofficial Guide to the World's Most Popular
Disassembler"
-- [History] --------------------------------------------
2.92- 1) Support ARM64 Windows binaries.
2) Limit only PE formatted binaries.
2.91- 1) Source code is backwards compatible with IDA 8 and 7.
2) This version supports IDA 9 (released versions).
2.7 - 1) Updated to IDA SDK 8.2 and MSVC 2019
2) Updated the plugin form to the new one to work with IDA SDK 8.2
3) Created a plugin to analyze PE32 on IDA 64 (IDA_ClassInformer_PlugIn3264.dlL)
because IDA is currently stopping to use IDA for 32-bit.
4) Linked VC++ runtime statically (/MT*)
5) Changed how to read user macros such as $(IDADIR), $(QTDIR) and $(IDASUPPORT)
that are necessary to build to reading PropertySheet.props.
And I also added $(IDASDK) to manage IDADIR and IDASDK separately.
Change the setting in the file if you have a different environment.
2.6 - 1) Updated to IDA SDK 7.1
2.5 - 1) Updated to IDA 7 and MSVC 2017.
Some of the changes for this:
Doesn't place types/structs, nor names or comments if they already exist.
Now the scanning role is more of looking for and fixing things IDA might have missed.
2) Now catches a rare secondary case where an assumed member function is unresolved bytes to
increase the accuracy of vftable member count scanning.
2.4 - 1) Now scans all "DATA" type segments. Before would only scan the first
".data" and ".rdata" segments.
2) Added segment select option to plug-in dialog.
2.2 - 1) Updated to IDA SDK 6.9 and MSVC 2015.
2.1 - 1) Removed the "IDA updating, please wait.." wait for IDA to update thing
at the end of processing to fix an ocassional hang.
2) Updated to IDA SDK 6.8 version.
2.0 - A complete overhaul of the entire plug-in.
1) Updated namings to better match that of Microsoft's internals.
2) Moved custom type creation out of the init() call; now gets created
only on the first run and only if the "Place structures" option is
checked.
3) Descriptive comments are now placed on C/C++ initializer and
terminator table start and end points.
4) The UI is now a custom Qt one with "material design" elements.
5) Added a 64bit (32bit IDA's "__E64__") version.
6) The RTCI (rare MS MFC type) support was removed.
7) Now locates vftables by RTTI "Complete Object Locator" structures
directly.
8) Updated to IDA SDK 6.7 version.
9) No longer has a default hotkey. Set your own using "plugins.cfg".
10) Updated and improved the static ctor/dtor processing.
1.06 - 1) Added persistent vftable list storage.
2) Removed the many unnecessary "autoWait()" calls that caused a bit
of a slow down.
3) Fixed broken and updated some custom UI elements.
4) Fixed the multi-segment select feature for the non-QT version and
added a working setup for the QT version too. For QT, after desired
segments are selected right click on the list and do "Select"
followed by the "Okay" button.
5) Added the ".data" segment to the default data search since vftables
are often located there (in addition to ".rdata").
1.05 - 1) The problem with the plug-in not being ready on invocation was fixed
by returning PLUGIN_KEEP on init to stay resident.
2) The fix in 1.04 didn't quite do it for structure placement problems.
In particular there remains a run on problem in IDA when marking some
areas "unknown"; these "do_unknown()" calls have been removed and
each structure element is individually placed one by one before
attempting to place the actual assorted structures.
1.04 - 1) Now ensures RTTI type name strings are set.
1.03 - 1) Added check and warning message for invalid start and end addresses
with "_initterm" type static/global ctor & dtor tables.
Would cause a negative count run-on condition that could trample over
a large data area.
2) UI customizations auto-disabled when using IDA Qt version.
3) Current IDA view is refreshed on completion to show changes.
4) Fixed a stall that could result from repeated failed attempts at an
RTTI type placement. Plus fixed the pattern for these so they could
be properly placed.
1.02 - 1) Added user code and data segment selector.
Allows user to select multiple data and code segments instead of the
default of ".text" and ".rdata" by name.
For those rare executable targets that have multiple code sections,
and, or, unpacked executables with mixed segments, etc.
2) Added config option for verbose output to the debugger channel.
3) Improved overall processing speed.
4) Since there can multiple instances of the same class or structure,
and IDA names must be unique all duplicate names are now serialized.
More things labeled, and no more "duplicate name" warning spam.
Note: Effects only label names, commented names are not altered
5) Updated to IDA SDK 5.5
6) Added links to Sirmabus IDA plug-ins support forum.
1.01 - 1) No longer pops up an error and exits IDA when an incompatible IDB is
loaded. Just displays a "not loaded" log message now.
2) Fixed IDA tab page update issue.
3) Now built with IDA SDK 5.4, and tested with IDA 5.4.
4) Fixed incorrect string placement in the RTTI type info struct.
Now the structures are right which make a cleaner DB.
This was a major bottleneck that caused the structure placement to be
about 36x slower, now only about 1x.
5) Fixed some misspellings.
-- [TODO] -----------------------------------------------
1) Add support for more compilers and platforms.
2) Add distinction for "pre-terminators" and C/C++ _initterm type tables.
3) Fix cases where _initterm() are register calls.
Find a problem? Please make a ticket here:
https://sourceforge.net/p/classinformer/tickets/
-- [License] -----------------------------------------------
http://www.opensource.org/licenses/mit-license.php
The MIT License (MIT)
Copyright(c) 2009 to present Sirmabus.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: classinformer-code/Plugin/IDA_ClassInformer_PlugIn.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug64|x64">
<Configuration>Debug64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release64_IDA8x|x64">
<Configuration>Release64_IDA8x</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release64|x64">
<Configuration>Release64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release_IDA8x|x64">
<Configuration>Release_IDA8x</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>PlugIn</ProjectName>
<Keyword>QtVS_v304</Keyword>
<ProjectGuid>{DEADBEEF-CAFE-F00D-FEED-C0FFEEC0FFEE}</ProjectGuid>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release64|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="PropertySheet.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="PropertySheet.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="PropertySheet.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="PropertySheet.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release64|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="PropertySheet.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="PropertySheet.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>ClassInformer</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>ClassInformer_IDA8x</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>ClassInformer64</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>ClassInformer_IDA8x64</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>ClassInformer</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>ClassInformer64</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Release/IDA_RTTI_Informer_PlugIn.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDASDK)include;$(QTDIR)include;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;$(IDASUPPORT)SupportLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__X64__;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;MATERIAL_DESIGN_STYLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AssemblerOutput>NoListing</AssemblerOutput>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CallingConvention>Cdecl</CallingConvention>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ida.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(IDASDK)lib\x64_win_vc_32_pro;$(IDASDK)lib\x64_win_vc_32;$(IDASDK)lib\x64_win_qt;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>
</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>
</ImportLibrary>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc</OutputFile>
</Bscmake>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Release/IDA_RTTI_Informer_PlugIn.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDASDK8x)include;$(QTDIR)include;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;$(IDASUPPORT)SupportLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__X64__;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;MATERIAL_DESIGN_STYLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AssemblerOutput>NoListing</AssemblerOutput>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CallingConvention>Cdecl</CallingConvention>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ida.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(IDASDK8x)lib\x64_win_vc_32_pro;$(IDASDK8x)lib\x64_win_vc_32;$(IDASDK8x)lib\x64_win_qt;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>
</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>
</ImportLibrary>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc</OutputFile>
</Bscmake>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Release/IDA_RTTI_Informer_PlugIn.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDASDK)include;$(QTDIR)include;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;$(IDASUPPORT)SupportLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__X64__;__EA64__;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;MATERIAL_DESIGN_STYLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AssemblerOutput>NoListing</AssemblerOutput>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CallingConvention>Cdecl</CallingConvention>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ida.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(IDASDK)lib\x64_win_vc_64_pro;$(IDASDK)lib\x64_win_vc_64;$(IDASDK)lib\x64_win_qt;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>
</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>
</ImportLibrary>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc</OutputFile>
</Bscmake>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Release/IDA_RTTI_Informer_PlugIn.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>.;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDASDK8x)include;$(QTDIR)include;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;$(IDASUPPORT)SupportLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__X64__;__EA64__;NDEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;MATERIAL_DESIGN_STYLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AssemblerOutput>NoListing</AssemblerOutput>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CallingConvention>Cdecl</CallingConvention>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ida.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(IDASDK8x)lib\x64_win_vc_64_pro;$(IDASDK8x)lib\x64_win_vc_64;$(IDASDK8x)lib\x64_win_qt;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>
</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>
</ImportLibrary>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(SolutionDir)Release\IDA_RTTI_Informer_PlugIn.bsc</OutputFile>
</Bscmake>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Debug/IDA_RTTI_Informer_PlugIn.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDASDK)include;$(QTDIR)include;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;$(IDASUPPORT)SupportLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEVMODE;__X64__;_DEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ida.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(IDASDK)lib\x64_win_vc_32_pro;$(IDASDK)lib\x64_win_vc_32;$(IDASDK)lib\x64_win_qt;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>
</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>
</ImportLibrary>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(SolutionDir)Debug\IDA_RTTI_Informer_PlugIn.bsc</OutputFile>
</Bscmake>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TypeLibraryName>.\Debug/IDA_RTTI_Informer_PlugIn.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);$(IDASDK)include;$(QTDIR)include;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;$(IDASUPPORT)SupportLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEVMODE;__EA64__;__X64__;_DEBUG;_WINDOWS;_USRDLL;__NT__;__IDP__;__VC__;QT_NO_DEBUG;QT_NAMESPACE=QT;QT_NO_UNICODE_LITERAL;_CRT_SECURE_NO_WARNINGS;MATERIAL_DESIGN_STYLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ida.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetFileName)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>$(IDASDK)lib\x64_win_vc_64_pro;$(IDASDK)lib\x64_win_vc_64;$(IDASDK)lib\x64_win_qt;$(IDASUPPORT)IDA_WaitEx;$(IDASUPPORT)IDA_SegmentSelect;$(IDASUPPORT)IDA_OggPlayer;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>
</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>
</ImportLibrary>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(SolutionDir)Debug\IDA_RTTI_Informer_PlugIn.bsc</OutputFile>
</Bscmake>
<PostBuildEvent />
</ItemDefinitionGroup>
<ItemGroup>
<CustomBuild Include="RTTI.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="StdAfx.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="undname.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="Vftable.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">Performing Custom Build Tools</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">Performing Custom Build Tools</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(IDASUPPORT)SupportLib\Utility.cpp" />
<ClCompile Include="GeneratedFiles\Debug64\moc_MainDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_MainDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\qrc_ClassInformerRes.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release64\moc_MainDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_MainDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release3264\moc_MainDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="Main.cpp" />
<ClCompile Include="MainDialog.cpp" />
<ClCompile Include="RTTI.cpp" />
<ClCompile Include="Vftable.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="dialog.ui">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">$(QTDIR)bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Uic%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">Uic%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">"$(QTDIR)bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">$(QTDIR)bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">$(QTDIR)bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">$(QTDIR)bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Uic%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">Uic%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">Uic%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">Uic%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">"$(QTDIR)bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">"$(QTDIR)bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">"$(QTDIR)bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(IDASUPPORT)SupportLib\Utility.h" />
<ClInclude Include="GeneratedFiles\ui_dialog.h" />
<ClInclude Include="Main.h" />
<CustomBuild Include="MainDialog.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing MainDialog.h...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">Moc%27ing MainDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_DEVMODE -D__X64__ -D_DEBUG -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"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">"$(QTDIR)bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_DEVMODE -D__EA64__ -D__X64__ -D_DEBUG -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"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing MainDialog.h...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">Moc%27ing MainDialog.h...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">Moc%27ing MainDialog.h...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">Moc%27ing MainDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D__X64__ -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -DMATERIAL_DESIGN_STYLE -D_CRT_SECURE_NO_WARNINGS -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"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">"$(QTDIR)bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D__X64__ -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -DMATERIAL_DESIGN_STYLE -D_CRT_SECURE_NO_WARNINGS -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"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">"$(QTDIR)bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D__X64__ -D__EA64__ -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -DMATERIAL_DESIGN_STYLE -D_CRT_SECURE_NO_WARNINGS -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"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">"$(QTDIR)bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D__X64__ -D__EA64__ -DNDEBUG -D_WINDOWS -D_USRDLL -D__NT__ -D__IDP__ -D__VC__ -DQT_NO_DEBUG -DQT_NAMESPACE=QT -DQT_NO_UNICODE_LITERAL -DMATERIAL_DESIGN_STYLE -D_CRT_SECURE_NO_WARNINGS -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"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">$(QTDIR)bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">$(QTDIR)bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">$(QTDIR)bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">$(QTDIR)bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="ClassInformerRes.qrc">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">%(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Rcc%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">Rcc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">"$(QTDIR)bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">%(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">%(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">%(FullPath);.\banner.png;.\icon.png;.\completed.ogg;.\checkbox-checked.png;.\progress-style.qss;.\style.qss;.\view-style.qss;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Rcc%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">Rcc%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">Rcc%27ing %(Identity)...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">Rcc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">"$(QTDIR)bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">"$(QTDIR)bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">"$(QTDIR)bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="completed.ogg">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
</None>
<None Include="progress-style.qss" />
<None Include="style.qss" />
<None Include="view-style.qss" />
</ItemGroup>
<ItemGroup>
<Image Include="banner.png">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
</Image>
<Image Include="checkbox-checked.png">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
</Image>
<Image Include="icon.png">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">true</ExcludedFromBuild>
</Image>
</ItemGroup>
<ItemGroup>
<Text Include="Class_Informer.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties Qt5Version_x0020_Win32="5.4.1" Qt5Version_x0020_x64="5.6.3" />
</VisualStudio>
</ProjectExtensions>
</Project>
================================================
FILE: classinformer-code/Plugin/IDA_ClassInformer_PlugIn.vcxproj.filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Misc">
<UniqueIdentifier>{a9876874-6172-4c9f-9d7e-e37acb380d0b}</UniqueIdentifier>
</Filter>
<Filter Include="Doc">
<UniqueIdentifier>{457050d4-f1f3-4a27-972f-11271f76b0de}</UniqueIdentifier>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
<ParseFiles>true</ParseFiles>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
<Extensions>moc;h;cpp</Extensions>
<ParseFiles>true</ParseFiles>
</Filter>
<Filter Include="Generated Files\Debug">
<UniqueIdentifier>{dd7ba64d-d074-493d-9850-868de31096d7}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Generated Files\Release">
<UniqueIdentifier>{e0c522c9-a6a4-40e2-a4d6-fc62cb3e5aed}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Generated Files\Debug64">
<UniqueIdentifier>{7df04027-bd87-43d2-b942-a438fb7cabc3}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Generated Files\Release64">
<UniqueIdentifier>{08b1d19d-ae87-4e19-a17b-645dacc30448}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Generated Files\Release3264">
<UniqueIdentifier>{18b1d19d-ae87-4e19-a17b-645dacc30448}</UniqueIdentifier>
<Extensions>cpp;moc</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
<Extensions>qrc;*</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="RTTI.cpp" />
<ClCompile Include="Vftable.cpp" />
<ClCompile Include="MainDialog.cpp" />
<ClCompile Include="GeneratedFiles\Debug64\moc_MainDialog.cpp">
<Filter>Generated Files\Debug64</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_MainDialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_MainDialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release3264\moc_MainDialog.cpp">
<Filter>Generated Files\Release3264</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release64\moc_MainDialog.cpp">
<Filter>Generated Files\Release64</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\qrc_ClassInformerRes.cpp">
<Filter>Generated Files</Filter>
</ClCompile>
<ClCompile Include="Main.cpp" />
<ClCompile Include="$(IDASUPPORT)SupportLib\Utility.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="RTTI.h" />
<CustomBuild Include="StdAfx.h" />
<CustomBuild Include="Vftable.h" />
<CustomBuild Include="undname.h">
<Filter>Misc</Filter>
</CustomBuild>
<CustomBuild Include="dialog.ui">
<Filter>Form Files</Filter>
</CustomBuild>
<CustomBuild Include="MainDialog.h" />
<CustomBuild Include="ClassInformerRes.qrc">
<Filter>Resource Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ClInclude Include="GeneratedFiles\ui_dialog.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="Main.h" />
<ClInclude Include="$(IDASUPPORT)SupportLib\Utility.h">
<Filter>Generated Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="completed.ogg">
<Filter>Resource Files</Filter>
</None>
<None Include="progress-style.qss">
<Filter>Resource Files</Filter>
</None>
<None Include="style.qss">
<Filter>Resource Files</Filter>
</None>
<None Include="view-style.qss">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Image Include="banner.png">
<Filter>Resource Files</Filter>
</Image>
<Image Include="icon.png">
<Filter>Resource Files</Filter>
</Image>
<Image Include="checkbox-checked.png">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Text Include="Class_Informer.txt">
<Filter>Doc</Filter>
</Text>
</ItemGroup>
</Project>
================================================
FILE: classinformer-code/Plugin/IDA_ClassInformer_PlugIn.vcxproj.user
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommand>$(IDADIR)ida.exe </LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">
<LocalDebuggerCommand>$(IDADIR)ida64.exe </LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommand>$(IDADIR)ida.exe </LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_IDA8x|x64'">
<LocalDebuggerCommand>$(IDADIR)ida.exe </LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release64|x64'">
<LocalDebuggerCommand>$(IDADIR)ida64.exe </LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release64_IDA8x|x64'">
<LocalDebuggerCommand>$(IDADIR)ida64.exe </LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(QTDIR)bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>
================================================
FILE: classinformer-code/Plugin/Main.cpp
================================================
// ****************************************************************************
// File: Core.cpp
// Desc: Class Informer
//
// ****************************************************************************
#include "stdafx.h"
#include "Main.h"
#include "Vftable.h"
#include "RTTI.h"
#include "MainDialog.h"
#include <map>
//
#include <WaitBoxEx.h>
#include <IdaOgg.h>
#include <loader.hpp>
typedef std::map<ea_t, std::string> STRMAP;
// Netnode constants
const static char NETNODE_NAME[] = {"$ClassInformer_node"};
const char NN_DATA_TAG = 'A';
const char NN_TABLE_TAG = 'S';
// Our netnode value indexes
enum NETINDX
{
NIDX_VERSION, // ClassInformer version
NIDX_COUNT // Table entry count
};
// VFTable entry container (fits in a netnode MAXSPECSIZE size)
#pragma pack(push, 1)
struct TBLENTRY
{
ea_t vft;
WORD methods;
WORD flags;
WORD strSize;
char str[MAXSPECSIZE - (sizeof(ea_t) + (sizeof(WORD) * 3))]; // Note: IDA MAXSTR = 1024
};
#pragma pack(pop)
// Line background color for non parent/top level hierarchy lines
// TOOD: Assumes text background is white. A way to make these user theme/style color aware?
#define GRAY(v) RGB(v,v,v)
static const bgcolor_t NOT_PARENT_COLOR = GRAY(235);
// === Function Prototypes ===
static BOOL processStaticTables();
static void showEndStats();
static BOOL getRttiData(SegSelect::segments *segList);
// === Data ===
static TIMESTAMP s_startTime = 0;
static HMODULE myModuleHandle = NULL;
static UINT staticCCtorCnt = 0, staticCppCtorCnt = 0, staticCDtorCnt = 0;
static UINT startingFuncCount = 0, staticCtorDtorCnt = 0;
static UINT colCount = 0, missingColsFixed = 0, vftablesFixed = 0;
static BOOL initResourcesOnce = FALSE;
static int chooserIcon = 0;
static netnode *netNode = NULL;
static eaList colList;
// Options
BOOL optionPlaceStructs = TRUE;
BOOL optionPlaceAtNamed = FALSE;
BOOL optionProcessStatic = TRUE;
BOOL optionAudioOnDone = TRUE;
// Bitness of current database
BOOL isDatabase64Bit = TRUE;
static void freeWorkingData()
{
try
{
RTTI::freeWorkingData();
colList.clear();
if (netNode)
{
delete netNode;
netNode = NULL;
}
}
CATCH()
}
struct class_informer_t : public plugmod_t
{
processor_t& ph;
class_informer_t(processor_t& _ph) : ph(_ph) {}
virtual bool idaapi run(size_t arg) override;
virtual void idaapi term();
};
// Initialize
static plugmod_t* idaapi init()
{
// Want the table entry structure to fit the max netnode size
CASSERT(sizeof(TBLENTRY) == 1024);
processor_t& ph = PH;
if (ph.id != PLFM_386 && ph.id != PLFM_ARM)
{
msg("[ClassInformer] WARNING: The binary you loaded is not for x86, x64, ARM nor ARM64. It is not supported (%x)\n", ph.id);
return nullptr; // only for x86, x64, ARM and ARM64
}
if (inf_get_filetype() != f_PE) {
msg("[ClassInformer] WARNING: The binary you loaded is not PE. It is not supported (%x)\n", inf_get_filetype());
return nullptr; // only PE format is allowed
}
return new class_informer_t(ph);
}
// Uninitialize
// Normally doesn't happen as we need to stay resident for the modal windows
void idaapi class_informer_t::term()
{
try
{
OggPlay::endPlay();
freeWorkingData();
if (initResourcesOnce)
{
if (chooserIcon)
{
free_custom_icon(chooserIcon);
chooserIcon = 0;
}
Q_CLEANUP_RESOURCE(ClassInformerRes);
initResourcesOnce = FALSE;
}
}
CATCH()
}
// Init new netnode storage
static void newNetnodeStore()
{
// Kill any existing store data first
netNode->altdel_all(NN_DATA_TAG);
netNode->supdel_all(NN_TABLE_TAG);
// Init defaults
netNode->altset_idx8(NIDX_VERSION, MY_VERSION, NN_DATA_TAG);
netNode->altset_idx8(NIDX_COUNT, 0, NN_DATA_TAG);
}
static WORD getStoreVersion(){ return((WORD)netNode->altval_idx8(NIDX_VERSION, NN_DATA_TAG)); }
static UINT getTableCount(){ return(netNode->altval_idx8(NIDX_COUNT, NN_DATA_TAG)); }
static BOOL setTableCount(UINT count){ return(netNode->altset_idx8(NIDX_COUNT, count, NN_DATA_TAG)); }
static BOOL getTableEntry(TBLENTRY &entry, UINT index){ return(netNode->supval(index, &entry, sizeof(TBLENTRY), NN_TABLE_TAG) > 0); }
static BOOL setTableEntry(TBLENTRY &entry, UINT index){ return(netNode->supset(index, &entry, (offsetof(TBLENTRY, str) + entry.strSize), NN_TABLE_TAG)); }
// Add an entry to the vftable list
void addTableEntry(UINT flags, ea_t vft, int methodCount, LPCTSTR format, ...)
{
TBLENTRY e;
e.vft = vft;
e.methods = methodCount;
e.flags = flags;
va_list vl;
va_start(vl, format);
vsnprintf_s(e.str, sizeof(e.str), SIZESTR(e.str), format, vl);
va_end(vl);
e.strSize = (WORD) (strlen(e.str) + 1);
UINT count = getTableCount();
setTableEntry(e, count);
setTableCount(++count);
}
// RTTI list chooser
static const char LBTITLE[] = { "[Class Informer]" };
static const UINT LBCOLUMNCOUNT = 5;
static const int LBWIDTHS[LBCOLUMNCOUNT] = { (8 | CHCOL_HEX), (4 | CHCOL_DEC), 3, 19, 500 };
static const char *const LBHEADER[LBCOLUMNCOUNT] =
{
"Vftable",
"Methods",
"Flags",
"Type",
"Hierarchy"
};
class rtti_chooser : public chooser_multi_t
{
public:
rtti_chooser() : chooser_multi_t(CH_QFTYP_DEFAULT, LBCOLUMNCOUNT, LBWIDTHS, LBHEADER, LBTITLE)
{
if (isDatabase64Bit)
{
// Setup hex address display to the minimal size needed plus a leading zero
UINT count = getTableCount();
ea_t largestAddres = 0;
for (UINT i = 0; i < count; i++)
{
TBLENTRY e; e.vft = 0;
getTableEntry(e, i);
if (e.vft > largestAddres)
largestAddres = e.vft;
}
char buffer[32];
int digits = (int)strlen(_ui64toa(largestAddres, buffer, 16));
if (++digits > 16) digits = 16;
sprintf_s(addressFormat, sizeof(addressFormat), "%%0%uI64X", digits);
}
else
{
strcpy_s(addressFormat, sizeof(addressFormat), "%08X");
}
// Chooser icon
icon = chooserIcon;
}
virtual const void *get_obj_id(size_t *len) const
{
*len = sizeof(LBTITLE);
return LBTITLE;
}
virtual size_t get_count() const { return (size_t)getTableCount(); }
virtual void get_row(qstrvec_t *cols_, int *icon_, chooser_item_attrs_t *attributes, size_t n) const
{
try
{
if (netNode)
{
// Generate the line
TBLENTRY e;
getTableEntry(e, (UINT)n);
// vft address
qstrvec_t &cols = *cols_;
cols[0].sprnt(addressFormat, e.vft);
// Method count
if (e.methods > 0)
cols[1].sprnt("%u", e.methods); // "%04u"
else
cols[1].sprnt("???");
// Flags
char flags[4];
int pos = 0;
if (e.flags & RTTI::CHD_MULTINH) flags[pos++] = 'M';
if (e.flags & RTTI::CHD_VIRTINH) flags[pos++] = 'V';
if (e.flags & RTTI::CHD_AMBIGUOUS) flags[pos++] = 'A';
flags[pos++] = 0;
cols[2] = flags;
// Type
LPCSTR tag = strchr(e.str, '@');
if (tag)
{
char buffer[sizeof(e.str)];
int pos = (tag - e.str);
if (pos > SIZESTR(buffer)) pos = SIZESTR(buffer);
memcpy(buffer, e.str, pos);
buffer[pos] = 0;
cols[3] = buffer;
++tag;
}
else
{
// Can happen when string is MAXSTR and greater
cols[3] = "??** MAXSTR overflow!";
tag = e.str;
}
// Composition/hierarchy
cols[4] = tag;
//*icon_ = ((e.flags & RTTI::IS_TOP_LEVEL) ? 77 : 191);
*icon_ = 191;
// Indicate entry is not a top/parent level by color
if (!(e.flags & RTTI::IS_TOP_LEVEL))
attributes->color = NOT_PARENT_COLOR;
}
}
CATCH()
}
virtual cbres_t enter(sizevec_t *sel)
{
size_t n = sel->front();
if (n < get_count())
{
TBLENTRY e;
getTableEntry(e, (UINT)n);
jumpto(e.vft);
}
return NOTHING_CHANGED;
}
virtual void closed()
{
freeWorkingData();
}
private:
char addressFormat[32];
};
// find_widget
static QWidget *findChildByClass(QWidgetList &wl, LPCSTR className)
{
foreach(QWidget *w, wl)
if (strcmp(w->metaObject()->className(), className) == 0)
return(w);
return nullptr;
}
// Find widget by title text
// If IDs are constant can use "static QWidget *QWidget::find(WId);"?
void customizeChooseWindow()
{
try
{
QApplication::processEvents();
// Get widget
if (QWidget* dw = (QWidget*)find_widget(LBTITLE))
{
QFile file(STYLE_PATH "view-style.qss");
if (file.open(QFile::ReadOnly | QFile::Text))
dw->setStyleSheet(QTextStream(&file).readAll());
// Get chooser widget
if (QTableView* tv = dw->findChild<QTableView*>(LBTITLE))
{
// Set sort by type name
tv->sortByColumn(3, Qt::AscendingOrder);
// Resize to contents
QHeaderView* header = tv->horizontalHeader();
header->setStretchLastSection(false);
tv->resizeColumnsToContents();
int max_width = (header->width() - tv->columnWidth(0) - tv->columnWidth(1) - tv->columnWidth(2)) / 2;
header->setMaximumSectionSize(max_width);
tv->resizeColumnsToContents();
header->setMaximumSectionSize(-1);
header->setStretchLastSection(true);
UINT count = getTableCount();
for (UINT row = 0; row < count; row++)
tv->setRowHeight(row, 22);
tv->selectRow(0);
}
else
msg("** customizeChooseWindow(): \"QTableView\" not found!\n");
}
else
msg("** customizeChooseWindow(): \"QWidget\" not found!\n");
}
CATCH()
}
bool idaapi class_informer_t::run(size_t arg)
{
try
{
char version[16];
sprintf_s(version, sizeof(version), "%u.%u", HIBYTE(MY_VERSION), LOBYTE(MY_VERSION));
msg("\n>> Class Informer: v: %s, built: %s, By Rohitab Batra and Hiroshi Suzuki (by Sirmabus originally)\n", version, __DATE__);
if (netNode)
{
msg("* Already active. Please close the chooser window first to run it again.\n");
if (TWidget* widget = find_widget(LBTITLE))
{
activate_widget(widget, true);
}
return true;
}
if (!initResourcesOnce)
{
initResourcesOnce = TRUE;
Q_INIT_RESOURCE(ClassInformerRes);
QFile file(STYLE_PATH "icon.png");
if (file.open(QFile::ReadOnly))
{
QByteArray ba = file.readAll();
chooserIcon = load_custom_icon(ba.constData(), ba.size(), "png");
}
}
if(!auto_is_ok())
{
msg("** Class Informer: Must wait for IDA to finish processing before starting plug-in! **\n*** Aborted ***\n\n");
return true;
}
OggPlay::endPlay();
freeWorkingData();
isDatabase64Bit = inf_is_64bit();
startingFuncCount = (UINT) get_func_qty();
colList.clear();
staticCppCtorCnt = staticCCtorCnt = staticCtorDtorCnt = staticCDtorCnt = 0;
missingColsFixed = vftablesFixed = 0;
// Create storage netnode
if(!(netNode = new netnode(NETNODE_NAME, SIZESTR(NETNODE_NAME), TRUE)))
{
QASSERT(66, FALSE);
return true;
}
// Read existing storage if any
UINT tableCount = getTableCount();
WORD storageVersion = getStoreVersion();
BOOL storageExists = (tableCount > 0);
// Ask if we should use storage or process again
if (storageExists)
{
// Version 2.3 didn't change the format
UINT major = HIBYTE(storageVersion), minor = LOBYTE(storageVersion);
if ((major != 2) || (minor < 2))
{
msg("* Storage version mismatch, must rescan *\n");
}
else
storageExists = (ask_yn(1, "TITLE Class Informer \nHIDECANCEL\nUse previously stored result? ") == 1);
}
BOOL aborted = FALSE;
if(!storageExists)
{
newNetnodeStore();
// Only MS Visual C++ targets are supported
comp_t cmp = get_comp(default_compiler());
if (cmp != COMP_MS)
{
msg("** IDA reports target compiler: \"%s\"\n", get_compiler_name(cmp));
int iResult = ask_buttons(NULL, NULL, NULL, 0, "TITLE Class Informer\nHIDECANCEL\nIDA reports this IDB's compiler as: \"%s\" \n\nThis plug-in only understands MS Visual C++ targets.\nRunning it on other targets (like Borland compiled, etc.) will have unpredicted results. \n\nDo you want to continue anyhow?", get_compiler_name(cmp));
if (iResult != 1)
{
msg("- Aborted -\n\n");
freeWorkingData();
return true;
}
}
// Do UI
SegSelect::segments *segList = NULL;
if (doMainDialog(optionPlaceStructs, optionProcessStatic, optionAudioOnDone, &segList))
{
msg("- Canceled -\n\n");
freeWorkingData();
return true;
}
msg("Working..\n");
WaitBox::show("Class Informer", "Please wait..", "url(" STYLE_PATH "progress-style.qss)", STYLE_PATH "icon.png");
WaitBox::updateAndCancelCheck(-1);
s_startTime = getTimeStamp();
// Add structure definitions to IDA once per session
static BOOL createStructsOnce = FALSE;
if (optionPlaceStructs && !createStructsOnce)
{
createStructsOnce = TRUE;
RTTI::addDefinitionsToIda();
}
if(optionProcessStatic)
{
// Process global and static ctor sections
msg("\nProcessing C/C++ ctor & dtor tables..\n");
msg("-------------------------------------------------\n");
if (!(aborted = processStaticTables()))
msg("Processing time: %s.\n", timeString(getTimeStamp() - s_startTime));
}
if (!aborted)
{
// Get RTTI data
if (!(aborted = getRttiData(segList)))
{
// Optionally play completion sound
if (optionAudioOnDone)
{
TIMESTAMP endTime = (getTimeStamp() - s_startTime);
if (endTime > (TIMESTAMP) 2.4)
{
OggPlay::endPlay();
QFile file(STYLE_PATH "completed.ogg");
if (file.open(QFile::ReadOnly))
{
QByteArray ba = file.readAll();
OggPlay::playFromMemory((const PVOID)ba.constData(), ba.size(), TRUE);
}
}
}
showEndStats();
msg("Done.\n\n");
}
}
WaitBox::hide();
refresh_idaview_anyway();
if (aborted)
{
msg("- Aborted -\n\n");
return true;
}
}
// Show list result window
if (!aborted && (getTableCount() > 0))
{
// The chooser allocation will free it's self automatically
rtti_chooser *chooserPtr = new rtti_chooser();
chooserPtr->choose();
customizeChooseWindow();
}
else
{
freeWorkingData();
}
}
CATCH()
return true;
}
// Print out end stats
static void showEndStats()
{
try
{
msg(" \n\n");
msg("=========== Stats ===========\n");
UINT vftableCount = getTableCount();
if (vftablesFixed)
msg(" RTTI vftables: %u, fixed: %u (%.1f%%)\n", vftableCount, vftablesFixed, ((double) vftablesFixed / (double) vftableCount) * 100.0);
else
msg(" RTTI vftables: %u\n", vftableCount);
// Amount of COLs fixed is usually about the same as vftables fixed, but the same COL can be used in multiple vftables
//if(missingColsFixed)
//msg(" COLs fixed: %u of %u (%.1f%%)\n", missingColsFixed, colCount, ((double) missingColsFixed / (double) colCount) * 100.0);
UINT functionsFixed = ((UINT) get_func_qty() - startingFuncCount);
if(functionsFixed)
msg("Functions fixed: %u\n", functionsFixed);
msg("Processing time: %s\n", timeString(getTimeStamp() - s_startTime));
}
CATCH()
}
// ================================================================================================
// Fix/create label and comment C/C++ initializer tables
static void setIntializerTable(ea_t start, ea_t end, BOOL isCpp)
{
try
{
if (UINT count = ((end - start) / EA_SIZE))
{
// Set table elements as pointers
ea_t ea = start;
while (ea <= end)
{
fixEa(ea);
// Might fix missing/messed stubs
if (ea_t func = get_32bit(ea))
fixFunction(func);
ea += EA_SIZE;
};
// Start label
if (!hasName(start))
{
char name[MAXSTR];
if (isCpp)
sprintf_s(name, sizeof(name), "__xc_a_%d", staticCppCtorCnt);
else
sprintf_s(name, sizeof(name), "__xi_a_%d", staticCCtorCnt);
setName(start, name);
}
// End label
if (!hasName(end))
{
char name[MAXSTR];
if (isCpp)
sprintf_s(name, sizeof(name), "__xc_z_%d", staticCppCtorCnt);
else
sprintf_s(name, sizeof(name), "__xi_z_%d", staticCCtorCnt);
setName(end, name);
}
// Comment
// Never overwrite, it might be the segment comment
if (!hasAnteriorComment(start))
{
if (isCpp)
setAnteriorComment(start, "%d C++ static ctors (#classinformer)", count);
else
setAnteriorComment(start, "%d C initializers (#classinformer)", count);
}
else
// Place comment @ address instead
if (!hasComment(start))
{
if (isCpp)
{
char comment[MAXSTR];
sprintf_s(comment, sizeof(comment), "%d C++ static ctors (#classinformer)", count);
setComment(start, comment, TRUE);
}
else
{
char comment[MAXSTR];
sprintf_s(comment, sizeof(comment), "%d C initializers (#classinformer)", count);
setComment(start, comment, TRUE);
}
}
if (isCpp)
staticCppCtorCnt++;
else
staticCCtorCnt++;
}
}
CATCH()
}
// Fix/create label and comment C/C++ terminator tables
static void setTerminatorTable(ea_t start, ea_t end)
{
try
{
if (UINT count = ((end - start) / EA_SIZE))
{
// Set table elements as pointers
ea_t ea = start;
while (ea <= end)
{
fixEa(ea);
// Fix function
if (ea_t func = getEa(ea))
fixFunction(func);
ea += EA_SIZE;
};
// Start label
if (!hasName(start))
{
char name[MAXSTR];
_snprintf_s(name, sizeof(name), SIZESTR(name), "__xt_a_%d", staticCDtorCnt);
setName(start, name);
}
// End label
if (!hasName(end))
{
char name[MAXSTR];
_snprintf_s(name, sizeof(name), SIZESTR(name), "__xt_z_%d", staticCDtorCnt);
setName(end, name);
}
// Comment
// Never overwrite, it might be the segment comment
if (!hasAnteriorComment(start))
setAnteriorComment(start, "%d C terminators (#classinformer)", count);
else
// Place comment @ address instead
if (!hasComment(start))
{
char comment[MAXSTR];
_snprintf_s(comment, sizeof(comment), SIZESTR(comment), "%d C terminators (#classinformer)", count);
setComment(start, comment, TRUE);
}
staticCDtorCnt++;
}
}
CATCH()
}
// "" for when we are uncertain of ctor or dtor type table
static void setCtorDtorTable(ea_t start, ea_t end)
{
try
{
if (UINT count = ((end - start) / EA_SIZE))
{
// Set table elements as pointers
ea_t ea = start;
while (ea <= end)
{
fixEa(ea);
// Fix function
if (ea_t func = getEa(ea))
fixFunction(func);
ea += EA_SIZE;
};
// Start label
if (!hasName(start))
{
char name[MAXSTR];
_snprintf_s(name, sizeof(name), SIZESTR(name), "__x?_a_%d", staticCtorDtorCnt);
setName(start, name);
}
// End label
if (!hasName(end))
{
char name[MAXSTR];
_snprintf_s(name, sizeof(name), SIZESTR(name), "__x?_z_%d", staticCtorDtorCnt);
setName(end, name);
}
// Comment
// Never overwrite, it might be the segment comment
if (!hasAnteriorComment(start))
setAnteriorComment(start, "%d C initializers/terminators (#classinformer)", count);
else
// Place comment @ address instead
if (!hasComment(start))
{
char comment[MAXSTR];
_snprintf_s(comment, sizeof(comment), SIZESTR(comment), "%d C initializers/terminators (#classinformer)", count);
setComment(start, comment, TRUE);
}
staticCtorDtorCnt++;
}
}
CATCH()
}
// Process redister based _initterm()
static void processRegisterInitterm(ea_t start, ea_t end, ea_t call)
{
if ((end != BADADDR) && (start != BADADDR))
{
// Should be in the same segment
if (getseg(start) == getseg(end))
{
if (start > end)
swap_t(start, end);
msg(" " EAFORMAT " to " EAFORMAT " CTOR table.\n", start, end);
setIntializerTable(start, end, TRUE);
if(!hasComment(call))
setComment(call, "_initterm", TRUE);
}
else
msg(" ** Bad address range of " EAFORMAT ", " EAFORMAT " for \"_initterm\" type ** <click address>.\n", start, end);
}
}
static UINT doInittermTable(func_t *func, ea_t start, ea_t end, LPCTSTR name)
{
UINT found = FALSE;
if ((start != BADADDR) && (end != BADADDR))
{
// Should be in the same segment
if (getseg(start) == getseg(end))
{
if (start > end)
swap_t(start, end);
// Try to determine if we are in dtor or ctor section
if (func)
{
qstring qstr;
if (get_long_name(&qstr, func->start_ea) > 0)
{
char funcName[MAXSTR];
strncpy_s(funcName, MAXSTR, qstr.c_str(), (MAXSTR - 1));
_strlwr(funcName);
// Start/ctor?
if (strstr(funcName, "cinit") || strstr(funcName, "tmaincrtstartup") || strstr(funcName, "start"))
{
msg(" " EAFORMAT " to " EAFORMAT " CTOR table.\n", start, end);
setIntializerTable(start, end, TRUE);
found = TRUE;
}
else
// Exit/dtor function?
if (strstr(funcName, "exit"))
{
msg(" " EAFORMAT " to " EAFORMAT " DTOR table.\n", start, end);
setTerminatorTable(start, end);
found = TRUE;
}
}
}
if (!found)
{
// Fall back to generic assumption
msg(" " EAFORMAT " to " EAFORMAT " CTOR/DTOR table.\n", start, end);
setCtorDtorTable(start, end);
found = TRUE;
}
}
else
msg(" ** Miss matched segment table addresses " EAFORMAT ", " EAFORMAT " for \"%s\" type **\n", start, end, name);
}
else
msg(" ** Bad input address range of " EAFORMAT ", " EAFORMAT " for \"%s\" type **\n", start, end, name);
return(found);
}
// Process _initterm function
// Returns TRUE if at least one found
static BOOL processInitterm(ea_t address, LPCTSTR name)
{
msg(EAFORMAT" processInitterm: \"%s\" \n", address, name);
UINT count = 0;
// Walk xrefs
ea_t xref = get_first_fcref_to(address);
while (xref && (xref != BADADDR))
{
msg(" " EAFORMAT " \"%s\" xref.\n", xref, name);
// Should be code
if (is_code(get_flags(xref)))
{
do
{
// The most common are two instruction arguments
// Back up two instructions
ea_t instruction1 = prev_head(xref, 0);
if (instruction1 == BADADDR)
break;
ea_t instruction2 = prev_head(instruction1, 0);
if (instruction2 == BADADDR)
break;
// Bail instructions are past the function start now
func_t *func = get_func(xref);
if (func && (instruction2 < func->start_ea))
{
//msg(" " EAFORMAT " arg2 outside of contained function **\n", func->start_ea);
break;
}
struct ARG2PAT
{
LPCSTR pattern;
UINT start, end, padding;
};
static const ALIGN(16) ARG2PAT arg2pat32[] =
{
{ "68 ?? ?? ?? ?? 68", 6, 1 }, // push offset s, push offset e
{ "B8 ?? ?? ?? ?? C7 04 24", 8, 1 }, // mov [esp+4+var_4], offset s, mov eax, offset e Maestia
{ "68 ?? ?? ?? ?? B8", 6, 1 }, // mov eax, offset s, push offset e
};
static const ALIGN(16) ARG2PAT arg2pat64[] =
{
{ "48 8D 15 ?? ?? ?? ?? 48 8D 0D", 3, 3 }, // lea rdx,s, lea rcx,e
};
const ARG2PAT* arg2pat = isDatabase64Bit ? arg2pat64 : arg2pat32;
UINT qnumber_arg2pat = isDatabase64Bit ? qnumber(arg2pat64) : qnumber(arg2pat32);
BOOL matched = FALSE;
for (UINT i = 0; (i < qnumber_arg2pat) && !matched; i++)
{
ea_t match = FIND_BINARY(instruction2, xref, arg2pat[i].pattern);
if (match != BADADDR)
{
ea_t start;
ea_t end;
if (!isDatabase64Bit)
{
start = getEa(match + arg2pat[i].start);
end = getEa(match + arg2pat[i].end);
}
else
{
UINT startOffset = get_32bit(instruction1 + arg2pat[i].start);
UINT endOffset = get_32bit(instruction2 + arg2pat[i].end);
start = (instruction1 + 7 + *((PINT) &startOffset)); // TODO: 7 is hard coded instruction length, put this in arg2pat table?
end = (instruction2 + 7 + *((PINT) &endOffset));
}
msg(" " EAFORMAT " Two instruction pattern match #%d\n", match, i);
count += doInittermTable(func, start, end, name);
matched = TRUE;
break;
}
}
// 3 instruction
/*
searchStart = prev_head(searchStart, BADADDR);
if (searchStart == BADADDR)
break;
if (func && (searchStart < func->start_ea))
break;
if (func && (searchStart < func->start_ea))
{
msg(" " EAFORMAT " arg3 outside of contained function **\n", func->start_ea);
break;
}
.text:10008F78 push offset unk_1000B1B8
.text:10008F7D push offset unk_1000B1B0
.text:10008F82 mov dword_1000F83C, 1
"68 ?? ?? ?? ?? 68 ?? ?? ?? ?? C7 05 ?? ?? ?? ?? ?? ?? ?? ??"
*/
if (!matched)
msg(" ** arguments not located!\n");
} while (FALSE);
}
else
msg(" " EAFORMAT " ** \"%s\" xref is not code! **\n", xref, name);
xref = get_next_fcref_to(address, xref);
};
msg(" \n");
return(count > 0);
}
// Process global/static ctor & dtor tables.
// Returns TRUE if user aborted
static BOOL processStaticTables()
{
staticCppCtorCnt = staticCCtorCnt = staticCtorDtorCnt = staticCDtorCnt = 0;
// x64 __tmainCRTStartup, _CRT_INIT
try
{
// Locate _initterm() and _initterm_e() functions
STRMAP inittermMap;
func_t *cinitFunc = NULL;
UINT funcCount = (UINT) get_func_qty();
for (UINT i = 0; i < funcCount; i++)
{
if (func_t *func = getn_func(i))
{
qstring qstr;
if (get_long_name(&qstr, func->start_ea) > 0)
{
char name[MAXSTR];
strncpy_s(name, MAXSTR, qstr.c_str(), (MAXSTR - 1));
int len = (int) strlen(name);
if (len >= SIZESTR("_cinit"))
{
if (strcmp((name + (len - SIZESTR("_cinit"))), "_cinit") == 0)
{
// Skip stub functions
if (func->size() > 16)
{
msg(EAFORMAT" C: \"%s\", %d bytes.\n", func->start_ea, name, func->size());
_ASSERT(cinitFunc == NULL);
cinitFunc = func;
}
}
else
if ((len >= SIZESTR("_initterm")) && (strcmp((name + (len - SIZESTR("_initterm"))), "_initterm") == 0))
{
msg(EAFORMAT" I: \"%s\", %d bytes.\n", func->start_ea, name, func->size());
inittermMap[func->start_ea] = name;
}
else
if ((len >= SIZESTR("_initterm_e")) && (strcmp((name + (len - SIZESTR("_initterm_e"))), "_initterm_e") == 0))
{
msg(EAFORMAT" E: \"%s\", %d bytes.\n", func->start_ea, name, func->size());
inittermMap[func->start_ea] = name;
}
}
}
}
}
if(WaitBox::isUpdateTime())
if (WaitBox::updateAndCancelCheck())
return(TRUE);
// Look for import versions
{
static LPCSTR imports[] =
{
"__imp__initterm", "__imp__initterm_e"
};
for (UINT i = 0; i < qnumber(imports); i++)
{
ea_t adress = get_name_ea(BADADDR, imports[i]);
if (adress != BADADDR)
{
if (inittermMap.find(adress) == inittermMap.end())
{
msg(EAFORMAT" import: \"%s\".\n", adress, imports[i]);
inittermMap[adress] = imports[i];
}
}
}
}
// Process register based _initterm() calls inside _cint()
if (cinitFunc)
{
struct CREPAT
{
LPCSTR pattern;
UINT start, end, call;
} static const ALIGN(16) pat[] =
{
{ "B8 ?? ?? ?? ?? BE ?? ?? ?? ?? 59 8B F8 3B C6 73 0F 8B 07 85 C0 74 02 FF D0 83 C7 04 3B FE 72 F1", 1, 6, 0x17},
{ "BE ?? ?? ?? ?? 8B C6 BF ?? ?? ?? ?? 3B C7 59 73 0F 8B 06 85 C0 74 02 FF D0 83 C6 04 3B F7 72 F1", 1, 8, 0x17},
};
for (UINT i = 0; i < qnumber(pat); i++)
{
ea_t match = FIND_BINARY(cinitFunc->start_ea, cinitFunc->end_ea, pat[i].pattern);
while (match != BADADDR)
{
msg(" " EAFORMAT " Register _initterm(), pattern #%d.\n", match, i);
ea_t start = getEa(match + pat[i].start);
ea_t end = getEa(match + pat[i].end);
processRegisterInitterm(start, end, (match + pat[i].call));
match = FIND_BINARY(match + 30, cinitFunc->end_ea, pat[i].pattern);
};
}
}
msg(" \n");
if (WaitBox::isUpdateTime())
if (WaitBox::updateAndCancelCheck())
return(TRUE);
// Process _initterm references
for (STRMAP::iterator it = inittermMap.begin(); it != inittermMap.end(); ++it)
{
if (processInitterm(it->first, it->second.c_str()))
if (WaitBox::isUpdateTime())
if (WaitBox::updateAndCancelCheck())
return(TRUE);
}
if (WaitBox::isUpdateTime())
if (WaitBox::updateAndCancelCheck())
return(TRUE);
}
CATCH()
return(FALSE);
}
// ================================================================================================
// Return TRUE if address as a anterior comment
inline BOOL hasAnteriorComment(ea_t ea)
{
return(get_first_free_extra_cmtidx(ea, E_PREV) != E_PREV);
}
// Delete any anterior comment(s) at address if there is some
inline void killAnteriorComments(ea_t ea)
{
delete_extra_cmts(ea, E_PREV);
}
// Force a memory location to be DWORD size
void fixDword(ea_t ea)
{
if (!is_dword(get_flags(ea)))
{
setUnknown(ea, sizeof(DWORD));
create_dword(ea, sizeof(DWORD));
}
}
// Force memory location to be ea_t size
void fixEa(ea_t ea)
{
if (!isEa(get_flags(ea)))
{
setUnknown(ea, EA_SIZE);
isDatabase64Bit ? create_qword(ea, EA_SIZE) : create_dword(ea, EA_SIZE);
}
}
// Address should be a code function
void fixFunction(ea_t ea)
{
flags_t flags = get_flags(ea);
// No code here?
if (!is_code(flags))
{
// Attempt to make it so
create_insn(ea);
add_func(ea, BADADDR);
}
else
// Yea there is code here, should have a function boddy too
if (!is_func(flags))
add_func(ea, BADADDR);
}
// Get IDA EA bit value with verification
BOOL getVerifyEa(ea_t ea, ea_t &rValue)
{
// Location valid?
if (is_loaded(ea))
{
// Get ea_t value
rValue = getEa(ea);
return(TRUE);
}
return(FALSE);
}
// Undecorate to minimal class name
// typeid(T).name()
// http://en.wikipedia.org/wiki/Name_mangling
// http://en.wikipedia.org/wiki/Visual_C%2B%2B_name_mangling
// http://www.agner.org/optimize/calling_conventions.pdf
BOOL getPlainTypeName(__in LPCSTR mangled, __out_bcount(MAXSTR) LPSTR outStr)
{
outStr[0] = outStr[MAXSTR - 1] = 0;
// Use CRT function for type names
if (mangled[0] == '.')
{
__unDName(outStr, mangled + 1, MAXSTR, mallocWrap, free, (UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY | UNDNAME_NO_ECSU));
if ((outStr[0] == 0) || (strcmp((mangled + 1), outStr) == 0))
{
msg("** getPlainClassName:__unDName() failed to unmangle! input: \"%s\"\n", mangled);
return(FALSE);
}
}
else
// IDA demangler for everything else
{
qstring qstr;
int result = demangle_name(&qstr, mangled, M_COMPILER /*MT_MSCOMP*/, DQT_FULL);
if (result < 0)
{
//msg("** getPlainClassName:demangle_name2() failed to unmangle! result: %d, input: \"%s\"\n", result, mangled);
return(FALSE);
}
// No inhibit flags will drop this
strncpy_s(outStr, MAXSTR, qstr.c_str(), (MAXSTR - 1));
if (LPSTR ending = strstr(outStr, "::`vftable'"))
*ending = 0;
}
return(TRUE);
}
void setUnknown(ea_t ea, int size)
{
del_items(ea, DELIT_EXPAND, size);
#if 0
// TODO: Does the item overrun problem still exist in IDA 7?
//do_unknown_range(ea, (size_t)size, DOUNK_SIMPLE);
while (size > 0)
{
int isize = get_item_size(ea);
if (isize > size)
break;
else
{
do_unknown(ea, DOUNK_SIMPLE);
ea += (ea_t)isize, size -= isize;
}
};
#endif
}
// Set name for address
void setName(ea_t ea, __in LPCSTR name)
{
//msg("%08X \"%s\"\n", ea, name);
set_name(ea, name, (SN_NON_AUTO | SN_NOWARN | SN_NOCHECK | SN_FORCE));
}
// Set comment at address
void setComment(ea_t ea, LPCSTR comment, BOOL rptble)
{
//msg("%08X cmt: \"%s\"\n", ea, comment);
set_cmt(ea, comment, rptble);
}
// Set comment at the line above the address
void setAnteriorComment(ea_t ea, const char *format, ...)
{
va_list va;
va_start(va, format);
vadd_extra_line(ea, 0, format, va);
va_end(va);
}
// Scan segment for COLs
static BOOL scanSeg4Cols(segment_t *seg)
{
qstring name;
if (get_segm_name(&name, seg) <= 0)
name = "???";
msg(" N: \"%s\", A: " EAFORMAT " - " EAFORMAT ", S: %s.\n", name.c_str(), seg->start_ea, seg->end_ea, byteSizeString(seg->size()));
UINT found = 0;
UINT sizeof_RTTI_RTTICompleteObjectLocator = isDatabase64Bit ? sizeof(RTTI::_RTTICompleteObjectLocator) : sizeof(RTTI::_RTTICompleteObjectLocator32);
if (seg->size() >= sizeof_RTTI_RTTICompleteObjectLocator)
{
ea_t startEA = ((seg->start_ea + sizeof(UINT)) & ~((ea_t) (sizeof(UINT) - 1)));
ea_t endEA = (seg->end_ea - sizeof_RTTI_RTTICompleteObjectLocator);
for (ea_t ptr = startEA; ptr < endEA;)
{
if (isDatabase64Bit)
{
// Check for possible COL here
// Signature will be one
// TODO: Is this always 1 or can it be zero like 32bit?
if (get_32bit(ptr + offsetof(RTTI::_RTTICompleteObjectLocator, signature)) == 1)
{
if (RTTI::_RTTICompleteObjectLocator::isValid(ptr))
{
// yes
colList.push_front(ptr);
missingColsFixed += (UINT)RTTI::_RTTICompleteObjectLocator::tryStruct(ptr);
ptr += sizeof(RTTI::_RTTICompleteObjectLocator);
continue;
}
}
else
{
// TODO: Should we check stray BCDs?
// Each value would have to be tested for a valid type_def and
// the pattern is pretty ambiguous.
}
}
else
{
// TypeDescriptor address here?
ea_t ea = getEa(ptr);
if (ea >= 0x10000)
{
if (RTTI::type_info::isValid(ea))
{
// yes, a COL here?
ea_t col = (ptr - offsetof(RTTI::_RTTICompleteObjectLocator, typeDescriptor));
if (RTTI::_RTTICompleteObjectLocator::isValid2(col))
{
// yes
colList.push_front(col);
missingColsFixed += (UINT)RTTI::_RTTICompleteObjectLocator::tryStruct(col);
ptr += sizeof(RTTI::_RTTICompleteObjectLocator32);
continue;
}
/*
else
// No, is it a BCD then?
if (RTTI::_RTTIBaseClassDescriptor::isValid2(ptr))
{
// yes
char dontCare[MAXSTR];
RTTI::_RTTIBaseClassDescriptor::doStruct(ptr, dontCare);
}
*/
}
}
}
if (WaitBox::isUpdateTime())
if (WaitBox::updateAndCancelCheck())
return(TRUE);
ptr += sizeof(UINT);
}
}
if (found)
{
char numBuffer[32];
msg(" Count: %s\n", prettyNumberString(found, numBuffer));
}
return(FALSE);
}
//
// Locate COL by descriptor list
static BOOL findCols(SegSelect::segments *segList)
{
try
{
TIMESTAMP startTime = getTimeStamp();
// Use user selected segments
if (segList && !segList->empty())
{
for (SegSelect::segments::iterator it = segList->begin(); it != segList->end(); ++it)
{
if (scanSeg4Cols(*it))
return(FALSE);
}
}
else
// Scan data segments named
{
int segCount = get_segm_qty();
for (int i = 0; i < segCount; i++)
{
if (segment_t *seg = getnseg(i))
{
if (seg->type == SEG_DATA)
{
if (scanSeg4Cols(seg))
return(FALSE);
}
}
}
}
char numBuffer[32];
msg(" Total COL: %s\n", prettyNumberString(colList.size(), numBuffer));
msg("COL scan time: %.3f\n", (getTimeStamp() - startTime));
}
CATCH()
return(FALSE);
}
// Locate vftables
static BOOL scanSeg4Vftables(segment_t *seg, eaRefMap &colMap)
{
qstring name;
if (get_segm_name(&name, seg) <= 0)
name = "???";
msg(" N: \"%s\", A: " EAFORMAT " - " EAFORMAT ", S: %s.\n", name.c_str(), seg->start_ea, seg->end_ea, byteSizeString(seg->size()));
UINT foundCount = 0;
if (seg->size() >= (UINT)EA_SIZE)
{
ea_t startEA = ((seg->start_ea + EA_SIZE) & ~((ea_t)(EA_SIZE - 1)));
ea_t endEA = (seg->end_ea - EA_SIZE);
_ASSERT(((startEA | endEA) & 3) == 0);
eaRefMap::iterator colEnd = colMap.end();
// Walk uint32 at the time, at align 4 (same for either 32bit or 64bit targets)
for (ea_t ptr = startEA; ptr < endEA; ptr += sizeof(UINT))
{
// A COL here?
ea_t ea = getEa(ptr);
eaRefMap::iterator it = colMap.find(ea);
if (it != colEnd)
{
// yes, look for vftable one ea_t below
ea_t vfptr = (ptr + EA_SIZE);
ea_t method = getEa(vfptr);
// Points to code?
if (segment_t *s = getseg(method))
{
// yes,
if (s->type == SEG_CODE)
{
BOOL result = RTTI::processVftable(vfptr, it->first);
//if(result)
// msg(EAFORMAT " vft fix **\n", vfptr);
vftablesFixed += (UINT) result;
it->second++, foundCount++;
}
}
}
if (WaitBox::isUpdateTime())
if (WaitBox::updateAndCancelCheck())
return(TRUE);
}
}
if (foundCount)
{
char numBuffer[32];
msg(" Count: %s\n", prettyNumberString(foundCount, numBuffer));
}
return(FALSE);
}
//
static BOOL findVftables(SegSelect::segments *segList)
{
try
{
TIMESTAMP startTime = getTimeStamp();
// COLs in a hash map for speed, plus add match counts
eaRefMap colMap;
for (eaList::const_iterator it = colList.begin(), end = colList.end(); it != end; ++it)
colMap[*it] = 0;
// Use user selected segments
if (segList && !segList->empty())
{
for (SegSelect::segments::iterator it = segList->begin(); it != segList->end(); ++it)
{
if (scanSeg4Vftables(*it, colMap))
return(FALSE);
}
}
else
// Scan data segments named
{
int segCount = get_segm_qty();
for (int i = 0; i < segCount; i++)
{
if (segment_t *seg = getnseg(i))
{
if (seg->type == SEG_DATA)
{
if (scanSeg4Vftables(seg, colMap))
return(FALSE);
}
}
}
}
// Rebuild 'colList' with any that were not located
if (!colList.empty())
{
colCount = (UINT) colList.size();
colList.clear();
for (eaRefMap::const_iterator it = colMap.begin(), end = colMap.end(); it != end; ++it)
{
if (it->second == 0)
colList.push_front(it->first);
}
//msg("\n** COLs not located: %u\n", (UINT)colList.size()); refreshUI();
}
msg("Vftable scan time: %.3f\n", (getTimeStamp() - startTime));
}
CATCH()
return(FALSE);
}
// ================================================================================================
// Gather RTTI data
static BOOL getRttiData(SegSelect::segments *segList)
{
// Free RTTI working data on return
struct OnReturn { ~OnReturn() { RTTI::freeWorkingData(); }; } onReturn;
try
{
// ==== Locate __type_info_root_node
BOOL aborted = FALSE;
// ==== Find and process Complete Object Locators (COL)
msg("\nScanning for for RTTI Complete Object Locators..\n");
msg("-------------------------------------------------\n");
if(findCols(segList))
return(TRUE);
// typeDescList = TDs left that don't have a COL reference
// colList = Located COLs
// ==== Find and process vftables
msg("\nScanning for Virtual Function Tables..\n");
msg("-------------------------------------------------\n");
if(findVftables(segList))
return(TRUE);
// colList = COLs left that don't have a vft reference
// Could use the unlocated ref lists typeDescList & colList around for possible separate listing, etc.
// They get cleaned up on return of this function anyhow.
}
CATCH()
return(FALSE);
}
// ================================================================================================
static char _comment[] = "Class Informer: Locates and fixes C++ Run Time Type class and structure information.";
static char _help[] = "";
static char _name[] = "Class Informer";
static const char _wanted_hotkey[] = "Alt-Shift-I";
// Plug-in description block
plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION, // IDA version plug-in is written for
PLUGIN_MULTI |
PLUGIN_PROC |
PLUGIN_MOD, // Plug-in flags
init, // Initialization function
nullptr, // Clean-up function
nullptr, // Main plug-in body
_comment, // Comment
_help, // Help
_name, // Plug-in name shown in Edit->Plugins menu
_wanted_hotkey // Hot key to run the plug-in
};
================================================
FILE: classinformer-code/Plugin/Main.h
================================================
// ****************************************************************************
// File: Main.h
// Desc:
//
// ****************************************************************************
extern void fixEa(ea_t ea);
extern void fixDword(ea_t eaAddress);
extern void fixFunction(ea_t eaFunc);
extern void setUnknown(ea_t ea, int size);
extern BOOL getVerifyEa(ea_t ea, ea_t &rValue);
extern BOOL hasAnteriorComment(ea_t ea);
extern void killAnteriorComments(ea_t ea);
#if IDA_SDK_VERSION < 900
extern int addStrucMember(struc_t *sptr, char *name, ea_t offset, flags_t flag, opinfo_t *type, asize_t nbytes);
#endif
extern void addTableEntry(UINT flags, ea_t vft, int methodCount, LPCSTR format, ...);
extern BOOL getPlainTypeName(__in LPCSTR mangled, __out_bcount(MAXSTR) LPSTR outStr);
extern void setName(ea_t ea, __in LPCSTR name);
extern void setComment(ea_t ea, LPCSTR comment, BOOL rptble);
extern void setAnteriorComment(ea_t ea, const char *format, ...);
// Return TRUE if there is a name at address that is not a dumbly name
inline BOOL hasName(ea_t ea) { return has_name(get_flags(ea)); }
// Return TRUE if there is a comment at address
inline BOOL hasComment(ea_t ea) { return has_cmt(get_flags(ea)); }
// Get IDA 32 bit value with verification
template <class T> BOOL getVerify32(ea_t eaPtr, T &rValue)
{
// Location valid?
if (is_loaded(eaPtr))
{
// Get 32bit value
rValue = (T) get_32bit(eaPtr);
return(TRUE);
}
return(FALSE);
}
#if IDA_SDK_VERSION < 820
#define EA_SIZE sizeof(ea_t)
#else
#define EA_SIZE EAH.ea_size
#endif
extern BOOL isDatabase64Bit;
// Get address/pointer value
inline ea_t getEa(ea_t ea)
{
return isDatabase64Bit ? get_64bit(ea) : get_32bit(ea);
}
// Returns TRUE if ea_t sized value flags
inline BOOL isEa(flags_t f)
{
return isDatabase64Bit ? is_qword(f) : is_dword(f);
}
extern BOOL optionPlaceStructs;
extern BOOL optionPlaceAtNamed;
================================================
FILE: classinformer-code/Plugin/MainDialog.cpp
================================================
// ****************************************************************************
// File: MainDialog.cpp
// Desc: Main Dialog
//
// ****************************************************************************
#include "stdafx.h"
#include "Main.h"
#include "MainDialog.h"
#include <QtWidgets/QDialogButtonBox>
MainDialog::MainDialog(BOOL& optionPlaceStructs, BOOL& optionProcessStatic, BOOL& optionAudioOnDone, SegSelect::segments** segs) : QDialog(QApplication::activeWindow(), QT::Qt::Widget)
{
Ui::MainCIDialog::setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
buttonBox->addButton("CONTINUE", QDialogButtonBox::AcceptRole);
buttonBox->addButton("CANCEL", QDialogButtonBox::RejectRole);
#define INITSTATE(obj,state) obj->setCheckState((state == TRUE) ? Qt::Checked : Qt::Unchecked);
INITSTATE(checkBox1, optionPlaceStructs);
INITSTATE(checkBoxAtNamed, optionPlaceAtNamed);
INITSTATE(checkBox2, optionProcessStatic);
INITSTATE(checkBox3, optionAudioOnDone);
#undef INITSTATE
// Apply style sheet
QFile file(STYLE_PATH "style.qss");
if (file.open(QFile::ReadOnly | QFile::Text))
setStyleSheet(QTextStream(&file).readAll());
this->segs = segs;
}
// On choose segments
void MainDialog::segmentSelect()
{
*segs = SegSelect::select((SegSelect::DATA_HINT | SegSelect::RDATA_HINT), "Choose segments to scan");
}
// Do main dialog, return TRUE if canceled
BOOL doMainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments **segs)
{
BOOL result = TRUE;
MainDialog *dlg = new MainDialog(optionPlaceStructs, optionProcessStatic, optionAudioOnDone, segs);
if (dlg->exec())
{
#define CHECKSTATE(obj,var) var = dlg->obj->isChecked()
CHECKSTATE(checkBox1, optionPlaceStructs);
CHECKSTATE(checkBoxAtNamed, optionPlaceAtNamed);
CHECKSTATE(checkBox2, optionProcessStatic);
CHECKSTATE(checkBox3, optionAudioOnDone);
#undef CHECKSTATE
result = FALSE;
}
delete dlg;
return(result);
}
================================================
FILE: classinformer-code/Plugin/MainDialog.h
================================================
#pragma once
#include "stdafx.h"
#include <QtWidgets/QDialog>
#include <SegSelect.h>
#include "ui_dialog.h"
class MainDialog : public QDialog, public Ui::MainCIDialog
{
Q_OBJECT
public:
MainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments **segs);
private:
SegSelect::segments **segs;
private slots:
void segmentSelect();
};
// Do main dialog, return TRUE if canceled
BOOL doMainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments **segs);
================================================
FILE: classinformer-code/Plugin/PropertySheet.props
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<IDADIR>C:\Program Files\IDA Professional 9.0\</IDADIR>
<QTDIR>..\..\..\..\Qt\5.15.2-x64\</QTDIR>
<IDASUPPORT>..\..\ida-support-library-code\</IDASUPPORT>
<IDASDK>..\..\..\idasdk90\</IDASDK>
<IDASDK8x>..\..\..\idasdk_pro80\</IDASDK8x>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup />
<ItemGroup>
<BuildMacro Include="IDADIR">
<Value>$(IDADIR)</Value>
</BuildMacro>
<BuildMacro Include="QTDIR">
<Value>$(QTDIR)</Value>
</BuildMacro>
<BuildMacro Include="IDASUPPORT">
<Value>$(IDASUPPORT)</Value>
</BuildMacro>
<BuildMacro Include="IDASDK">
<Value>$(IDASDK)</Value>
</BuildMacro>
<BuildMacro Include="IDASDK8x">
<Value>$(IDASDK8x)</Value>
</BuildMacro>
</ItemGroup>
</Project>
================================================
FILE: classinformer-code/Plugin/RTTI.cpp
================================================
// ****************************************************************************
// File: RTTI.cpp
// Desc: Run-Time Type Information (RTTI) support
//
// ****************************************************************************
#include "stdafx.h"
#include "Main.h"
#include "RTTI.h"
#include "Vftable.h"
// const Name::`vftable'
static LPCSTR FORMAT_RTTI_VFTABLE = "??_7%s6B@";
static LPCSTR FORMAT_RTTI_VFTABLE_PREFIX = "??_7";
// type 'RTTI Type Descriptor'
static LPCSTR FORMAT_RTTI_TYPE = "??_R0?%s@8";
// 'RTTI Base Class Descriptor at (a,b,c,d)'
static LPCSTR FORMAT_RTTI_BCD = "??_R1%s%s%s%s%s8";
// `RTTI Base Class Array'
static LPCSTR FORMAT_RTTI_BCA = "??_R2%s8";
// 'RTTI Class Hierarchy Descriptor'
static LPCSTR FORMAT_RTTI_CHD = "??_R3%s8";
// 'RTTI Complete Object Locator'
static LPCSTR FORMAT_RTTI_COL = "??_R4%s6B@";
static LPCSTR FORMAT_RTTI_COL_PREFIX = "??_R4";
// Skip type_info tag for class/struct mangled name strings
#define SKIP_TD_TAG(_str) ((_str) + SIZESTR(".?Ax"))
// Class name list container
struct bcdInfo
{
char m_name[496];
UINT m_attribute;
RTTI::PMD m_pmd;
};
typedef qvector<bcdInfo> bcdList;
namespace RTTI
{
void getBCDInfo(ea_t col, __out bcdList &nameList, __out UINT &numBaseClasses);
};
typedef std::unordered_map<ea_t, qstring> stringMap;
static stringMap stringCache;
static eaSet tdSet;
static eaSet chdSet;
static eaSet bcdSet;
void RTTI::freeWorkingData()
{
stringCache.clear();
tdSet.clear();
chdSet.clear();
bcdSet.clear();
}
// Mangle number for labeling
static LPSTR mangleNumber(UINT number, __out_bcount(64) LPSTR buffer)
{
//
// 0 = A@
// X = X-1 (1 <= X <= 10)
// -X = ? (X - 1)
// 0x0..0xF = 'A'..'P'
// Can only get unsigned inputs
int num = *((PINT) &number);
if(num == 0)
return("A@");
else
{
int sign = 0;
if(num < 0)
{
sign = 1;
num = -num;
}
if(num <= 10)
{
_snprintf_s(buffer, 64, (64 - 1), "%s%d", (sign ? "?" : ""), (num - 1));
return(buffer);
}
else
{
// Count digits
char buffer2[64] = {0};
int count = sizeof(buffer2);
while((num > 0) && (count > 0))
{
buffer2[sizeof(buffer2) - count] = ('A' + (num % 16));
num = (num / 16);
count--;
};
if(count == 0)
msg(" *** mangleNumber() overflow! ***");
_snprintf_s(buffer, 64, (64-1), "%s%s@", (sign ? "?" : ""), buffer2);
return(buffer);
}
}
}
// Return a short label indicating the CHD inheritance type by attributes
// TODO: Consider CHD_AMBIGUOUS?
static LPCSTR attributeLabel(UINT attributes)
{
if ((attributes & 3) == RTTI::CHD_MULTINH)
return("[MI]");
else
if ((attributes & 3) == RTTI::CHD_VIRTINH)
return("[VI]");
else
if ((attributes & 3) == (RTTI::CHD_MULTINH | RTTI::CHD_VIRTINH))
return("[MI VI]");
else
return("");
}
// Add RTTI definitions to IDA
// Structure type IDs
static tid_t s_type_info_ID = 1;
static tid_t s_ClassHierarchyDescriptor_ID = 2;
static tid_t s_PMD_ID = 3;
static tid_t s_BaseClassDescriptor_ID = 4;
static tid_t s_CompleteObjectLocator_ID = 5;
void RTTI::addDefinitionsToIda()
{
char *lpszDecl;
#if IDA_SDK_VERSION >= 900
#define get_named_type_tid get_named_type_tid
#else
#define get_named_type_tid(name) import_type(NULL, -1, name)
#endif
// IDA 7 has a definition for this now
s_type_info_ID = get_named_type_tid("TypeDescriptor");
#if IDA_SDK_VERSION >= 900
if (s_type_info_ID == BADADDR)
{
tinfo_t tif = tinfo_t();
if (tif.get_named_type("TypeDescriptor"))
{
s_type_info_ID = tif.force_tid();
}
}
#endif
if (s_type_info_ID == BADADDR)
{
msg("** Failed to load the IDA TypeDescriptor type, generating one **\n");
if (!isDatabase64Bit)
{
lpszDecl = R"DECL(
/// RTTI std::type_info class (#classinformer)
struct type_info
{
int vfptr;
int data;
char name[];
};
)DECL";
}
else
{
lpszDecl = R"DECL(
/// RTTI std::type_info class (#classinformer)
struct type_info
{
void *vfptr;
void *data;
char name[];
};
)DECL";
}
if (parse_decls(nullptr, lpszDecl, msg, HTI_DCL) != 0)
msg("** addDefinitionsToIda(): type_info failed! \n");
s_type_info_ID = get_named_type_tid("type_info");
}
// Set the representation of the "name" field to a string literal.
#if IDA_SDK_VERSION >= 900
if (s_type_info_ID != BADADDR)
{
tinfo_t tif = tinfo_t();
value_repr_t repr = value_repr_t();
if (tif.get_type_by_tid(s_type_info_ID) && repr.parse_value_repr("__strlit(C)"))
{
tif.set_udm_repr(2, repr);
}
}
#else
struc_t *sptr = get_struc(s_type_info_ID);
if (sptr)
{
member_t* mptr = get_member_by_name(sptr, "name");
if (mptr)
{
#define FF_STRLIT 0x50000000
mptr->flag |= FF_STRLIT;
}
}
#endif
// Must come before the following "_RTTIBaseClassDescriptor"
lpszDecl = R"DECL(
/// RTTI Base class descriptor displacement container (#classinformer)
struct _PMD
{
int mdisp;
int pdisp;
int vdisp;
};
)DECL";
parse_decls(nullptr, lpszDecl, msg, HTI_DCL);
s_PMD_ID = get_named_type_tid("_PMD");
if (!isDatabase64Bit)
{
lpszDecl = R"DECL(
/// RTTI Class Hierarchy Descriptor (#classinformer)
struct _RTTIClassHierarchyDescriptor
{
int signature;
int attributes;
int numBaseClasses;
void* baseClassArray;
};
)DECL";
}
else
{
lpszDecl = R"DECL(
/// RTTI Class Hierarchy Descriptor (#classinformer)
struct _RTTIClassHierarchyDescriptor
{
int signature;
int attributes;
int numBaseClasses;
int baseClassArray;
};
)DECL";
}
parse_decls(nullptr, lpszDecl, msg, HTI_DCL);
s_ClassHierarchyDescriptor_ID = get_named_type_tid("_RTTIClassHierarchyDescriptor");
if (!isDatabase64Bit)
{
lpszDecl = R"DECL(
/// RTTI Base Class Descriptor (#classinformer)
struct _RTTIBaseClassDescriptor
{
void* typeDescriptor;
int numContainedBases;
_PMD pmd;
int attributes;
};
)DECL";
}
else
{
lpszDecl = R"DECL(
/// RTTI Base Class Descriptor (#classinformer)
struct _RTTIBaseClassDescriptor
{
int typeDescriptor;
int numContainedBases;
_PMD pmd;
int attributes;
};
)DECL";
}
parse_decls(nullptr, lpszDecl, msg, HTI_DCL);
s_BaseClassDescriptor_ID = get_named_type_tid("_RTTIBaseClassDescriptor");
if (!isDatabase64Bit)
{
lpszDecl = R"DECL(
/// RTTI Complete Object Locator (#classinformer)
struct _RTTICompleteObjectLocator
{
int signature;
int offset;
int cdOffset;
void* typeDescriptor;
void* classDescriptor;
};
)DECL";
}
else
{
lpszDecl = R"DECL(
/// RTTI Complete Object Locator (#classinformer)
struct _RTTICompleteObjectLocator
{
int signature;
int offset;
int cdOffset;
int typeDescriptor;
int classDescriptor;
int objectBase;
};
)DECL";
}
parse_decls(nullptr, lpszDecl, msg, HTI_DCL);
s_CompleteObjectLocator_ID = get_named_type_tid("_RTTICompleteObjectLocator");
#undef get_named_type_tid
}
// Version 1.05, manually set fields and then try to place the struct
// If it fails at least the fields should be set
// 2.5: IDA 7 now has RTTI support; only place structs if don't exist at address
// Returns TRUE if structure was placed, else it was already set
static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BOOL bHasChd = FALSE)
{
#define putDword(ea) create_dword(ea, sizeof(DWORD))
#define putEa(ea) isDatabase64Bit ? create_qword(ea, EA_SIZE) : create_dword(ea, EA_SIZE)
UINT sizeof_RTTI_RTTICompleteObjectLocator = isDatabase64Bit ? sizeof(RTTI::_RTTICompleteObjectLocator) : sizeof(RTTI::_RTTICompleteObjectLocator32);
if(tid == s_type_info_ID)
{
UINT offsetof_RTTI_type_info_M_d_name = isDatabase64Bit ? offsetof(RTTI::type_info64, _M_d_name) : offsetof(RTTI::type_info32, _M_d_name);
UINT offsetof_RTTI_type_info_vfptr = isDatabase64Bit ? offsetof(RTTI::type_info64, vfptr) : offsetof(RTTI::type_info32, vfptr);
UINT offsetof_RTTI_type_info_M_data = isDatabase64Bit ? offsetof(RTTI::type_info64, _M_data) : offsetof(RTTI::type_info32, _M_data);
if (optionPlaceAtNamed || !hasName(ea))
{
_ASSERT(typeName != NULL);
UINT nameLen = (UINT)(strlen(typeName) + 1);
UINT structSize = (offsetof_RTTI_type_info_M_d_name + nameLen);
// Place struct
setUnknown(ea, structSize);
BOOL result = FALSE;
if (optionPlaceStructs)
result = create_struct(ea, structSize, s_type_info_ID);
if (!result)
{
putEa(ea + offsetof_RTTI_type_info_vfptr);
putEa(ea + offsetof_RTTI_type_info_M_data);
create_strlit((ea + offsetof_RTTI_type_info_M_d_name), nameLen, STRTYPE_C);
}
// sh!ft: End should be aligned
ea_t end = (ea + offsetof_RTTI_type_info_M_d_name + nameLen);
if (end % EA_SIZE)
create_align(end, (EA_SIZE - (end % EA_SIZE)), 0);
return TRUE;
}
}
else
if (tid == s_ClassHierarchyDescriptor_ID)
{
if (optionPlaceAtNamed || !hasName(ea))
{
setUnknown(ea, sizeof(RTTI::_RTTIClassHierarchyDescriptor));
BOOL result = FALSE;
if (optionPlaceStructs)
result = create_struct(ea, sizeof(RTTI::_RTTIClassHierarchyDescriptor), s_ClassHierarchyDescriptor_ID);
if (!result)
{
putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, signature));
putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, attributes));
putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, numBaseClasses));
putDword(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, baseClassArray));
}
return TRUE;
}
}
else
if(tid == s_PMD_ID)
{
if (optionPlaceAtNamed || !hasName(ea))
{
setUnknown(ea, sizeof(RTTI::PMD));
BOOL result = FALSE;
if (optionPlaceStructs)
result = create_struct(ea, sizeof(RTTI::PMD), s_PMD_ID);
if (!result)
{
putDword(ea + offsetof(RTTI::PMD, mdisp));
putDword(ea + offsetof(RTTI::PMD, pdisp));
putDword(ea + offsetof(RTTI::PMD, vdisp));
}
return TRUE;
}
}
else
if(tid == s_CompleteObjectLocator_ID)
{
if (optionPlaceAtNamed || !hasName(ea))
{
setUnknown(ea, sizeof_RTTI_RTTICompleteObjectLocator);
BOOL result = FALSE;
if (optionPlaceStructs)
result = create_struct(ea, sizeof_RTTI_RTTICompleteObjectLocator, s_CompleteObjectLocator_ID);
if (!result)
{
putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, signature));
putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, offset));
putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, cdOffset));
putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, typeDescriptor));
putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor));
if (isDatabase64Bit)
{
putDword(ea + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase));
}
}
return TRUE;
}
}
else
if (tid == s_BaseClassDescriptor_ID)
{
// Recursive
tryStructRTTI(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, pmd), s_PMD_ID);
if (optionPlaceAtNamed || !hasName(ea))
{
setUnknown(ea, sizeof(RTTI::_RTTIBaseClassDescriptor));
BOOL result = FALSE;
if (optionPlaceStructs)
result = create_struct(ea, sizeof(RTTI::_RTTIBaseClassDescriptor), s_BaseClassDescriptor_ID);
if (!result)
{
putDword(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, typeDescriptor));
putDword(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, numContainedBases));
putDword(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, attributes));
if (bHasChd)
{
putDword(ea + (offsetof(RTTI::_RTTIBaseClassDescriptor, attributes) + sizeof(UINT)));
}
}
return TRUE;
}
}
else
{
_ASSERT(FALSE);
}
return FALSE;
}
// Read ASCII string from IDB at address
static int getIdaString(ea_t ea, __out LPSTR buffer, int bufferSize)
{
buffer[0] = 0;
// Return cached name if it exists
stringMap::iterator it = stringCache.find(ea);
if (it != stringCache.end())
{
LPCSTR str = it->second.c_str();
int len = (int) strlen(str);
if (len > bufferSize)
len = bufferSize;
strncpy_s(buffer, MAXSTR, str, len);
return len;
}
else
{
// Read string at ea if it exists
int len = (int) get_max_strlit_length(ea, STRTYPE_C, ALOPT_IGNHEADS);
if (len > 0)
{
// Length includes terminator
if (len > bufferSize)
len = bufferSize;
qstring str;
int len2 = get_strlit_contents(&str, ea, len, STRTYPE_C);
if (len2 > 0)
{
// Length with out terminator
if (len2 > bufferSize)
len2 = bufferSize;
// Cache it
memcpy(buffer, str.c_str(), len2);
buffer[len2] = 0;
stringCache[ea] = buffer;
}
else
len = 0;
}
return len ;
}
}
// --------------------------- Type descriptor ---------------------------
// Get type name into a buffer
// type_info assumed to be valid
int RTTI::type_info::getName(ea_t typeInfo, __out LPSTR buffer, int bufferSize)
{
UINT offsetof_type_info_M_d_name = isDatabase64Bit ? offsetof(type_info64, _M_d_name) : offsetof(type_info32, _M_d_name);
return(getIdaString(typeInfo + offsetof_type_info_M_d_name, buffer, bufferSize));
}
// A valid type_info/TypeDescriptor at pointer?
BOOL RTTI::type_info::isValid(ea_t typeInfo)
{
// TRUE if we've already seen it
if (tdSet.find(typeInfo) != tdSet.end())
return(TRUE);
if (is_loaded(typeInfo))
{
UINT offsetof_type_info_vfptr = isDatabase64Bit ? offsetof(type_info64, vfptr) : offsetof(type_info32, vfptr);
UINT offsetof_type_info_M_data = isDatabase64Bit ? offsetof(type_info64, _M_data) : offsetof(type_info32, _M_data);
UINT offsetof_type_info_M_d_name = isDatabase64Bit ? offsetof(type_info64, _M_d_name) : offsetof(type_info32, _M_d_name);
// Verify what should be a vftable
ea_t ea = getEa(typeInfo + offsetof_type_info_vfptr);
if (is_loaded(ea))
{
// _M_data should be NULL statically
ea_t _M_data = BADADDR;
if (getVerifyEa((typeInfo + offsetof_type_info_M_data), _M_data))
{
if (_M_data == 0)
return(isTypeName(typeInfo + offsetof_type_info_M_d_name));
}
}
}
return(FALSE);
}
// Returns TRUE if known typename at address
BOOL RTTI::type_info::isTypeName(ea_t name)
{
// Should start with a period
if (get_byte(name) == '.')
{
// Read the rest of the possible name string
char buffer[MAXSTR];
if (getIdaString(name, buffer, SIZESTR(buffer)))
{
// Should be valid if it properly demangles
if (LPSTR s = __unDName(NULL, buffer+1 /*skip the '.'*/, 0, mallocWrap, free, (UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY)))
{
free(s);
return(TRUE);
}
}
}
return(FALSE);
}
// Put struct and place name at address
void RTTI::type_info::tryStruct(ea_t typeInfo)
{
// Only place once per address
if (tdSet.find(typeInfo) != tdSet.end())
return;
else
tdSet.insert(typeInfo);
// Get type name
char name[MAXSTR];
int nameLen = getName(typeInfo, name, SIZESTR(name));
tryStructRTTI(typeInfo, s_type_info_ID, name);
if (nameLen > 0)
{
if (!hasName(typeInfo))
{
// Set decorated name/label
char name2[MAXSTR];
_snprintf_s(name2, sizeof(name2), SIZESTR(name2), FORMAT_RTTI_TYPE, (name + 2));
setName(typeInfo, name2);
}
}
else
{
_ASSERT(FALSE);
}
}
// --------------------------- Complete Object Locator ---------------------------
// Return TRUE if address is a valid RTTI structure
BOOL RTTI::_RTTICompleteObjectLocator::isValid(ea_t col)
{
if (is_loaded(col))
{
// Check signature
UINT signature = -1;
if (getVerify32((col + offsetof(_RTTICompleteObjectLocator, signature)), signature))
{
if (!isDatabase64Bit && signature == 0)
{
// Check valid type_info
ea_t typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor));
if (RTTI::type_info::isValid(typeInfo))
{
ea_t classDescriptor = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor));
if (RTTI::_RTTIClassHierarchyDescriptor::isValid(classDescriptor))
{
//msg(EAFORMAT" " EAFORMAT " " EAFORMAT " \n", col, typeInfo, classDescriptor);
return(TRUE);
}
}
}
else if (isDatabase64Bit && signature == 1)
{
// TODO: Can any of these be zero and still be valid?
UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase));
if (objectLocator != 0)
{
UINT tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor));
if (tdOffset != 0)
{
UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor));
if (cdOffset != 0)
{
ea_t colBase = (col - (UINT64)objectLocator);
ea_t typeInfo = (colBase + (UINT64)tdOffset);
if (RTTI::type_info::isValid(typeInfo))
{
ea_t classDescriptor = (colBase + (UINT64) cdOffset);
if (RTTI::_RTTIClassHierarchyDescriptor::isValid(classDescriptor, colBase))
{
//msg(EAFORMAT" " EAFORMAT " " EAFORMAT " \n", col, typeInfo, classDescriptor);
return(TRUE);
}
}
}
}
}
}
}
}
return(FALSE);
}
// Same as above but from an already validated type_info perspective
BOOL RTTI::_RTTICompleteObjectLocator::isValid2(ea_t col)
{
// 'signature' should be zero
UINT signature = -1;
if (getVerify32((col + offsetof(_RTTICompleteObjectLocator, signature)), signature))
{
if (signature == 0)
{
// Verify CHD
ea_t classDescriptor = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor));
if (classDescriptor && (classDescriptor != BADADDR))
return(RTTI::_RTTIClassHierarchyDescriptor::isValid(classDescriptor));
}
}
return(FALSE);
}
// Place full COL hierarchy structures if they don't already exist
BOOL RTTI::_RTTICompleteObjectLocator::tryStruct(ea_t col)
{
// If it doesn't have a name, IDA's analyzer missed it
if (optionPlaceAtNamed || !hasName(col))
{
#if 0
qstring buf;
idaFlags2String(get_flags(col), buf);
msg(EAFORMAT " fix COL (%s)\n", col, buf.c_str());
#endif
tryStructRTTI(col, s_CompleteObjectLocator_ID);
if (!isDatabase64Bit)
{
// Put type_def
ea_t typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor));
type_info::tryStruct(typeInfo);
// Place CHD hierarchy
ea_t classDescriptor = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor));
_RTTIClassHierarchyDescriptor::tryStruct(classDescriptor);
}
else
{
UINT tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor));
UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor));
UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase));
ea_t colBase = (col - (UINT64)objectLocator);
ea_t typeInfo = (colBase + (UINT64)tdOffset);
type_info::tryStruct(typeInfo);
ea_t classDescriptor = (colBase + (UINT64)cdOffset);
_RTTIClassHierarchyDescriptor::tryStruct(classDescriptor, colBase);
// Set absolute address comments
ea_t ea = (col + offsetof(RTTI::_RTTICompleteObjectLocator, typeDescriptor));
if (!hasComment(ea))
{
char buffer[64];
sprintf_s(buffer, sizeof(buffer), "0x" EAFORMAT, typeInfo);
setComment(ea, buffer, TRUE);
}
ea = (col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor));
if (!hasComment(ea))
{
char buffer[64];
sprintf_s(buffer, sizeof(buffer), "0x" EAFORMAT, classDescriptor);
setComment(ea, buffer, TRUE);
}
}
return TRUE;
}
return FALSE;
}
// --------------------------- Base Class Descriptor ---------------------------
// Return TRUE if address is a valid BCD
BOOL RTTI::_RTTIBaseClassDescriptor::isValid(ea_t bcd, ea_t colBase64)
{
// TRUE if we've already seen it
if (bcdSet.find(bcd) != bcdSet.end())
return(TRUE);
if (is_loaded(bcd))
{
// Check attributes flags first
UINT attributes = -1;
if (getVerify32((bcd + offsetof(_RTTIBaseClassDescriptor, attributes)), attributes))
{
// Valid flags are the lower byte only
if ((attributes & 0xFFFFFF00) == 0)
{
// Check for valid type_info
if (!isDatabase64Bit)
{
return(RTTI::type_info::isValid(getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor))));
}
else
{
UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor));
ea_t typeInfo = (colBase64 + (UINT64)tdOffset);
return(RTTI::type_info::isValid(typeInfo));
}
}
}
}
return(FALSE);
}
// Put BCD structure at address
void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LPSTR baseClassName, ea_t colBase64)
{
// Only place it once
if (bcdSet.find(bcd) != bcdSet.end())
{
// Seen already, just return type name
ea_t typeInfo;
if (!isDatabase64Bit)
{
typeInfo = getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor));
}
else
{
UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor));
typeInfo = (colBase64 + (UINT64)tdOffset);
}
char buffer[MAXSTR];
type_info::getName(typeInfo, buffer, SIZESTR(buffer));
strcpy_s(baseClassName, sizeof(buffer), SKIP_TD_TAG(buffer));
return;
}
else
bcdSet.insert(bcd);
if (is_loaded(bcd))
{
UINT attributes = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes));
tryStructRTTI(bcd, s_BaseClassDescriptor_ID, NULL, ((attributes & BCD_HASPCHD) > 0));
// Has appended CHD?
if (attributes & BCD_HASPCHD)
{
// yes, process it
ea_t chdOffset = (bcd + (offsetof(_RTTIBaseClassDescriptor, attributes) + sizeof(UINT)));
ea_t chd;
if (!isDatabase64Bit)
{
fixEa(chdOffset);
chd = getEa(chdOffset);
}
else
{
fixDword(chdOffset);
UINT chdOffset32 = get_32bit(chdOffset);
chd = (colBase64 + (UINT64)chdOffset32);
if (!hasComment(chdOffset))
{
char buffer[64];
sprintf_s(buffer, sizeof(buffer), "0x" EAFORMAT, chd);
setComment(chdOffset, buffer, TRUE);
}
}
if (is_loaded(chd))
_RTTIClassHierarchyDescriptor::tryStruct(chd, colBase64);
else
_ASSERT(FALSE);
}
// Place type_info struct
ea_t typeInfo;
if (!isDatabase64Bit)
{
typeInfo = getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor));
}
else
{
UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor));
typeInfo = (colBase64 + (UINT64)tdOffset);
}
type_info::tryStruct(typeInfo);
// Get raw type/class name
char buffer[MAXSTR];
type_info::getName(typeInfo, buffer, SIZESTR(buffer));
strcpy_s(baseClassName, sizeof(buffer), SKIP_TD_TAG(buffer));
if (!optionPlaceStructs && attributes)
{
// Place attributes comment
ea_t ea = (bcd + offsetof(_RTTIBaseClassDescriptor, attributes));
if (!hasComment(ea))
{
qstring s("");
BOOL b = 0;
#define ATRIBFLAG(_flag) { if (attributes & _flag) { if (b) s += " | "; s += #_flag; b = 1; } }
ATRIBFLAG(BCD_NOTVISIBLE);
ATRIBFLAG(BCD_AMBIGUOUS);
ATRIBFLAG(BCD_PRIVORPROTINCOMPOBJ);
ATRIBFLAG(BCD_PRIVORPROTBASE);
ATRIBFLAG(BCD_VBOFCONTOBJ);
ATRIBFLAG(BCD_NONPOLYMORPHIC);
ATRIBFLAG(BCD_HASPCHD);
#undef ATRIBFLAG
setComment(ea, s.c_str(), TRUE);
}
}
// Give it a label
if (!hasName(bcd))
{
// Name::`RTTI Base Class Descriptor at (0, -1, 0, 0)'
ZeroMemory(buffer, sizeof(buffer));
char buffer1[64] = { 0 }, buffer2[64] = { 0 }, buffer3[64] = { 0 }, buffer4[64] = { 0 };
_snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), FORMAT_RTTI_BCD,
mangleNumber(get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp))), buffer1),
mangleNumber(get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp))), buffer2),
mangleNumber(get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp))), buffer3),
mangleNumber(attributes, buffer4),
baseClassName);
setName(bcd, buffer);
}
}
else
_ASSERT(FALSE);
}
// --------------------------- Class Hierarchy Descriptor ---------------------------
// Return true if address is a valid CHD structure
BOOL RTTI::_RTTIClassHierarchyDescriptor::isValid(ea_t chd, ea_t colBase64)
{
// TRUE if we've already seen it
if (chdSet.find(chd) != chdSet.end())
return(TRUE);
if (is_loaded(chd))
{
// signature should be zero statically
UINT signature = -1;
if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, signature)), signature))
{
if (signature == 0)
{
// Check attributes flags
UINT attributes = -1;
if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)), attributes))
{
// Valid flags are the lower nibble only
if ((attributes & 0xFFFFFFF0) == 0)
{
// Should have at least one base class
UINT numBaseClasses = 0;
if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses)), numBaseClasses))
{
if (numBaseClasses >= 1)
{
// Check the first BCD entry
ea_t baseClassArray;
if (!isDatabase64Bit)
{
baseClassArray = getEa(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray));
}
else
{
UINT baseClassArrayOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray));
baseClassArray = (colBase64 + (UINT64)baseClassArrayOffset);
}
if (is_loaded(baseClassArray))
{
if (!isDatabase64Bit)
{
ea_t baseClassDescriptor = getEa(baseClassArray);
return(RTTI::_RTTIBaseClassDescriptor::isValid(baseClassDescriptor));
}
else
{
ea_t baseClassDescriptor = (colBase64 + (UINT64)get_32bit(baseClassArray));
return(RTTI::_RTTIBaseClassDescriptor::isValid(baseClassDescriptor, colBase64));
}
}
}
}
}
}
}
}
}
return(FALSE);
}
// Put CHD structure at address
void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, ea_t colBase64)
{
// Only place it once per address
if (chdSet.find(chd) != chdSet.end())
return;
else
chdSet.insert(chd);
if (is_loaded(chd))
{
// Place CHD
tryStructRTTI(chd, s_ClassHierarchyDescriptor_ID);
// Place attributes comment
UINT attributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes));
if (!optionPlaceStructs && attributes)
{
ea_t ea = (chd + offsetof(_RTTIClassHierarchyDescriptor, attributes));
if (!hasComment(ea))
{
qstring s("");
BOOL b = 0;
#define ATRIBFLAG(_flag) { if (attributes & _flag) { if (b) s += " | "; s += #_flag; b = 1; } }
ATRIBFLAG(CHD_MULTINH);
ATRIBFLAG(CHD_VIRTINH);
ATRIBFLAG(CHD_AMBIGUOUS);
#undef ATRIBFLAG
setComment(ea, s.c_str(), TRUE);
}
}
// ---- Place BCD's ----
UINT numBaseClasses = 0;
if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses)), numBaseClasses))
{
// Get pointer
ea_t baseClassArray;
if (!isDatabase64Bit)
{
baseClassArray = getEa(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray));
}
else
{
UINT baseClassArrayOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray));
baseClassArray = (colBase64 + (UINT64)baseClassArrayOffset);
ea_t ea = (chd + offsetof(RTTI::_RTTIClassHierarchyDescriptor, baseClassArray));
if (!hasComment(ea))
{
char buffer[MAXSTR];
_snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), "0x" EAFORMAT, baseClassArray);
setComment(ea, buffer, TRUE);
}
}
if (baseClassArray && (baseClassArray != BADADDR))
{
// Create offset string based on input digits
char format[128];
if (!isDatabase64Bit)
{
if (numBaseClasses > 1)
{
int digits = (int)strlen(_itoa(numBaseClasses, format, 10));
if (digits > 1)
_snprintf_s(format, sizeof(format), SIZESTR(format), " BaseClass[%%0%dd]", digits);
else
strcpy_s(format, sizeof(format), " BaseClass[%d]");
}
}
else
{
if (numBaseClasses > 1)
{
int digits = (int)strlen(_itoa(numBaseClasses, format, 10));
if (digits > 1)
_snprintf_s(format, sizeof(format), SIZESTR(format), " BaseClass[%%0%dd] 0x%%016I64X", digits);
else
strcpy_s(format, sizeof(format), " BaseClass[%d] 0x%016I64X");
}
}
for (UINT i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(UINT)) // sizeof(ea_t)
{
char baseClassName[MAXSTR];
if (!isDatabase64Bit)
{
fixEa(baseClassArray);
// Add index comment to to it
if (!hasComment(baseClassArray))
{
if (numBaseClasses == 1)
setComment(baseClassArray, " BaseClass", FALSE);
else
{
char ptrComent[MAXSTR];
_snprintf_s(ptrComent, sizeof(ptrComent), SIZESTR(ptrComent), format, i);
setComment(baseClassArray, ptrComent, false);
}
}
// Place BCD struct, and grab the base class name
_RTTIBaseClassDescriptor::tryStruct(getEa(baseClassArray), baseClassName);
}
else
{
fixDword(baseClassArray);
UINT bcOffset = get_32bit(baseClassArray);
ea_t bcd = (colBase64 + (UINT64)bcOffset);
// Add index comment to to it
if (!hasComment(baseClassArray))
{
if (numBaseClasses == 1)
{
char buffer[MAXSTR];
sprintf_s(buffer, sizeof(buffer), " BaseClass 0x" EAFORMAT, bcd);
setComment(baseClassArray, buffer, FALSE);
}
else
{
char buffer[MAXSTR];
_snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), format, i, bcd);
setComment(baseClassArray, buffer, false);
}
}
// Place BCD struct, and grab the base class name
_RTTIBaseClassDescriptor::tryStruct(bcd, baseClassName, colBase64);
}
// Now we have the base class name, name and label some things
if (i == 0)
{
// Set array name
if (!hasName(baseClassArray))
{
// ??_R2A@@8 = A::`RTTI Base Class Array'
char mangledName[MAXSTR];
_snprintf_s(mangledName, sizeof(mangledName), SIZESTR(mangledName), FORMAT_RTTI_BCA, baseClassName);
setName(baseClassArray, mangledName);
}
// Add a spacing comment line above us
if (!hasAnteriorComment(baseClassArray))
setAnteriorComment(baseClassArray, "");
// Set CHD name
if (!hasName(chd))
{
// A::`RTTI Class Hierarchy Descriptor'
char mangledName[MAXSTR];
_snprintf_s(mangledName, sizeof(mangledName), SIZESTR(mangledName), FORMAT_RTTI_CHD, baseClassName);
setName(chd, mangledName);
}
}
}
// Make following DWORD if it's bytes are zeros
if (numBaseClasses > 0)
{
if (is_loaded(baseClassArray))
if (get_32bit(baseClassArray) == 0)
fixDword(baseClassArray);
}
}
else
_ASSERT(FALSE);
}
else
_ASSERT(FALSE);
}
else
_ASSERT(FALSE);
}
// --------------------------- Vftable ---------------------------
// Get list of base class descriptor info
static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT &numBaseClasses)
{
numBaseClasses = 0;
ea_t chd;
ea_t colBase;
if (!isDatabase64Bit)
{
chd = getEa(col + offsetof(_RTTICompleteObjectLocator, classDescriptor));
}
else
{
UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor));
UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase));
colBase = (col - (UINT64)objectLocator);
chd = (colBase + (UINT64)cdOffset);
}
if(chd)
{
if (numBaseClasses = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses)))
{
list.resize(numBaseClasses);
// Get pointer
ea_t baseClassArray;
if (!isDatabase64Bit)
{
baseClassArray = getEa(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray));
}
else
{
UINT bcaOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray));
baseClassArray = (colBase + (UINT64)bcaOffset);
}
if(baseClassArray && (baseClassArray != BADADDR))
{
for(UINT i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(UINT)) // sizeof(ea_t)
{
ea_t bcd;
ea_t typeInfo;
if (!isDatabase64Bit)
{
// Get next BCD
bcd = getEa(baseClassArray);
// Get type name
typeInfo = getEa(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor));
}
else
{
UINT bcdOffset = get_32bit(baseClassArray);
bcd = (colBase + (UINT64)bcdOffset);
UINT tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor));
typeInfo = (colBase + (UINT64)tdOffset);
}
bcdInfo *bi = &list[i];
type_info::getName(typeInfo, bi->m_name, SIZESTR(bi->m_name));
// Add info to list
UINT mdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp)));
UINT pdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp)));
UINT vdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp)));
// As signed int
bi->m_pmd.mdisp = *((PINT) &mdisp);
bi->m_pmd.pdisp = *((PINT) &pdisp);
bi->m_pmd.vdisp = *((PINT) &vdisp);
bi->m_attribute = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes));
//msg(" BN: [%d] \"%s\", ATB: %04X\n", i, szBuffer1, get_32bit((ea_t) &pBCD->attributes));
//msg(" mdisp: %d, pdisp: %d, vdisp: %d, attributes: %04X\n", *((PINT) &mdisp), *((PINT) &pdisp), *((PINT) &vdisp), attributes);
}
}
}
}
}
// Process RTTI vftable info
// Returns TRUE if if vftable and wasn't named on entry
BOOL RTTI::processVftable(ea_t vft, ea_t col)
{
BOOL result = FALSE;
ea_t colBase;
ea_t typeInfo;
if (isDatabase64Bit)
{
UINT tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor));
UINT objectLocator = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, objectBase));
colBase = (col - (UINT64)objectLocator);
typeInfo = (colBase + (UINT64)tdOffset);
}
// Verify and fix if vftable exists here
vftable::vtinfo vi;
if (vftable::getTableInfo(vft, vi))
{
//msg(EAFORMAT " - " EAFORMAT " c: %d\n", vi.start, vi.end, vi.methodCount);
// Get COL type name
ea_t chd;
if (!isDatabase64Bit)
{
typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor));
chd = get_32bit(col + offsetof(_RTTICompleteObjectLocator, classDescriptor));
}
else
{
UINT cdOffset = get_32bit(col + offsetof(RTTI::_RTTICompleteObjectLocator, classDescriptor));
chd = (colBase + (UINT64)cdOffset);
}
char colName[MAXSTR];
type_info::getName(typeInfo, colName, SIZESTR(colName));
char demangledColName[MAXSTR];
getPlainTypeName(colName, demangledColName);
UINT chdAttributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes));
UINT offset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, offset));
// Parse BCD info
bcdList list;
UINT numBaseClasses;
getBCDInfo(col, list, numBaseClasses);
BOOL sucess = FALSE, isTopLevel = FALSE;
qstring cmt;
// ======= Simple or no inheritance
if ((offset == 0) && ((chdAttributes & (CHD_MULTINH | CHD_VIRTINH)) == 0))
{
// Set the vftable name
if (!hasName(vft))
{
result = TRUE;
// Decorate raw name as a vftable. I.E. const Name::`vftable'
char decorated[MAXSTR];
_snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_VFTABLE, SKIP_TD_TAG(colName));
setName(vft, decorated);
}
// Set COL name. I.E. const Name::`RTTI Complete Object Locator'
if (!hasName(col))
{
char decorated[MAXSTR];
_snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_COL, SKIP_TD_TAG(colName));
setName(col, decorated);
}
// Build object hierarchy string
int placed = 0;
if (numBaseClasses > 1)
{
// Parent
char plainName[MAXSTR];
getPlainTypeName(list[0].m_name, plainName);
cmt.sprnt("%s%s: ", ((list[0].m_name[3] == 'V') ? "" : "struct "), plainName);
placed++;
isTopLevel = ((strcmp(list[0].m_name, colName) == 0) ? TRUE : FALSE);
// Child object hierarchy
for (UINT i = 1; i < numBaseClasses; i++)
{
// Append name
getPlainTypeName(list[i].m_name, plainName);
cmt.cat_sprnt("%s%s, ", ((list[i].m_name[3] == 'V') ? "" : "struct "), plainName);
placed++;
}
// Nix the ending ',' for the last one
if (placed > 1)
cmt.remove((cmt.length() - 2), 2);
}
else
{
// Plain, no inheritance object(s)
cmt.sprnt("%s%s: ", ((colName[3] == 'V') ? "" : "struct "), demangledColName);
isTopLevel = TRUE;
}
if (placed > 1)
cmt += ';';
sucess = TRUE;
}
// ======= Multiple inheritance, and, or, virtual inheritance hierarchies
else
{
bcdInfo *bi = NULL;
int index = 0;
// Must be the top level object for the type
if (offset == 0)
{
_ASSERT(strcmp(colName, list[0].m_name) == 0);
bi = &list[0];
isTopLevel = TRUE;
}
else
{
// Get our object BCD level by matching COL offset to displacement
for (UINT i = 0; i < numBaseClasses; i++)
{
if (list[i].m_pmd.mdisp == offset)
{
bi = &list[i];
index = i;
break;
}
}
// If not found in list, use the first base object instead
if (!bi)
{
//msg("** " EAFORMAT " MI COL class offset: %X(%d) not in BCD.\n", vft, offset, offset);
for (UINT i = 0; i < numBaseClasses; i++)
{
if (list[i].m_pmd.pdisp != -1)
{
bi = &list[i];
index = i;
break;
}
}
}
}
if (bi)
{
// Top object level layout
int placed = 0;
if (isTopLevel)
{
// Set the vft name
if (!hasName(vft))
{
result = TRUE;
char decorated[MAXSTR];
_snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_VFTABLE, SKIP_TD_TAG(colName));
setName(vft, decorated);
}
// COL name
if (!hasName(col))
{
char decorated[MAXSTR];
_snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_COL, SKIP_TD_TAG(colName));
setName(col, decorated);
}
// Build hierarchy string starting with parent
char plainName[MAXSTR];
getPlainTypeName(list[0].m_name, plainName);
cmt.sprnt("%s%s: ", ((list[0].m_name[3] == 'V') ? "" : "struct "), plainName);
placed++;
// Concatenate forward child hierarchy
for (UINT i = 1; i < numBaseClasses; i++)
{
getPlainTypeName(list[i].m_name, plainName);
cmt.cat_sprnt("%s%s, ", ((list[i].m_name[3] == 'V') ? "" : "struct "), plainName);
placed++;
}
if (placed > 1)
cmt.remove((cmt.length() - 2), 2);
}
else
{
// Combine COL and CHD name
char combinedName[MAXSTR];
_snprintf_s(combinedName, sizeof(combinedName), SIZESTR(combinedName), "%s6B%s@", SKIP_TD_TAG(colName), SKIP_TD_TAG(bi->m_name));
// Set vftable name
if (!hasName(vft))
{
result = TRUE;
char decorated[MAXSTR];
strcpy(decorated, FORMAT_RTTI_VFTABLE_PREFIX);
strncat_s(decorated, MAXSTR, combinedName, (MAXSTR - (1 + SIZESTR(FORMAT_RTTI_VFTABLE_PREFIX))));
setName(vft, decorated);
}
// COL name
if (!hasName((ea_t) col))
{
char decorated[MAXSTR];
strcpy(decorated, FORMAT_RTTI_COL_PREFIX);
strncat_s(decorated, MAXSTR, combinedName, (MAXSTR - (1 + SIZESTR(FORMAT_RTTI_COL_PREFIX))));
setName((ea_t) col, decorated);
}
// Build hierarchy string starting with parent
char plainName[MAXSTR];
getPlainTypeName(bi->m_name, plainName);
cmt.sprnt("%s%s: ", ((bi->m_name[3] == 'V') ? "" : "struct "), plainName);
placed++;
// Concatenate forward child hierarchy
if (++index < (int) numBaseClasses)
{
for (; index < (int) numBaseClasses; index++)
{
getPlainTypeName(list[index].m_name, plainName);
cmt.cat_sprnt("%s%s, ", ((list[index].m_name[3] == 'V') ? "" : "struct "), plainName);
placed++;
}
if (placed > 1)
cmt.remove((cmt.length() - 2), 2);
}
/*
Experiment, maybe better this way to show before and after to show it's location in the hierarchy
// Concatenate reverse child hierarchy
if (--index >= 0)
{
for (; index >= 0; index--)
{
getPlainTypeName(list[index].m_name, plainName);
cmt.cat_sprnt("%s%s, ", ((list[index].m_name[3] == 'V') ? "" : "struct "), plainName);
placed++;
}
if (placed > 1)
cmt.remove((cmt.length() - 2), 2);
}
*/
}
if (placed > 1)
cmt += ';';
sucess = TRUE;
}
else
msg(EAFORMAT" ** Couldn't find a BCD for MI/VI hierarchy!\n", vft);
}
if (sucess)
{
// Store entry
addTableEntry(((chdAttributes & 0xF) | ((isTopLevel == TRUE) ? RTTI::IS_TOP_LEVEL : 0)), vft, vi.methodCount, "%s@%s", demangledColName, cmt.c_str());
// Add a separating comment above RTTI COL
ea_t colPtr = (vft - EA_SIZE);
fixEa(colPtr);
//cmt.cat_sprnt(" %s O: %d, A: %d (#classinformer)", attributeLabel(chdAttributes, numBaseClasses), offset, chdAttributes);
cmt.cat_sprnt(" %s (#classinformer)", attributeLabel(chdAttributes));
if (!hasAnteriorComment(colPtr))
setAnteriorComment(colPtr, "\n; %s %s", ((colName[3] == 'V') ? "class" : "struct"), cmt.c_str());
//vftable::processMembers(plainName, vft, end);
}
}
else
// Usually a typedef reference to a COL, not a vftable
{
#if 0
qstring tmp;
idaFlags2String(get_flags(vft), tmp);
msg(EAFORMAT" ** Vftable attached to this COL, error? (%s)\n", vft, tmp.c_str());
#endif
// Just set COL name
if (!hasName(col))
{
if (!isDatabase64Bit)
{
typeInfo = getEa(col + offsetof(_RTTICompleteObjectLocator, typeDescriptor));
}
char colName[MAXSTR];
type_info::getName(typeInfo, colName, SIZESTR(colName));
char decorated[MAXSTR];
_snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_COL, SKIP_TD_TAG(colName));
setName(col, decorated);
}
}
return result;
}
================================================
FILE: classinformer-code/Plugin/RTTI.h
================================================
// ****************************************************************************
// File: RTTI.h
// Desc: Run-Time Type Information (RTTI) support
//
// ****************************************************************************
#pragma once
namespace RTTI
{
#pragma pack(push, 1)
// std::type_info class representation
struct type_info
{
static BOOL isValid(ea_t typeInfo);
static BOOL isTypeName(ea_t name);
static int getName(ea_t typeInfo, __out LPSTR bufffer, int bufferSize);
static void tryStruct(ea_t typeInfo);
};
struct type_info32 : type_info
{
UINT vfptr; // type_info class vftable
UINT _M_data; // NULL until loaded at runtime
char _M_d_name[1]; // Mangled name (prefix: .?AV=classes, .?AU=structs)
};
struct type_info64 : type_info
{
ea_t vfptr; // type_info class vftable
ea_t _M_data; // NULL until loaded at runtime
char _M_d_name[1]; // Mangled name (prefix: .?AV=classes, .?AU=structs)
};
const UINT MIN_TYPE_INFO_SIZE_32 = (offsetof(type_info32, _M_d_name) + sizeof(".?AVx"));
const UINT MIN_TYPE_INFO_SIZE_64 = (offsetof(type_info64, _M_d_name) + sizeof(".?AVx"));
typedef type_info _TypeDescriptor;
typedef type_info _RTTITypeDescriptor;
// Base class "Pointer to Member Data"
struct PMD
{
int mdisp; // 00 Vftable displacement inside class instance
int pdisp; // 04 Vbtable displacement
int vdisp; // 08 Vftable displacement inside vbtable
};
// Describes all base classes together with information to derived class a
gitextract_80tmnr81/
├── .gitignore
├── README.md
├── classinformer-code/
│ ├── IDA_ClassInformer.sln
│ ├── Plugin/
│ │ ├── ClassInformerRes.qrc
│ │ ├── Class_Informer.txt
│ │ ├── IDA_ClassInformer_PlugIn.vcxproj
│ │ ├── IDA_ClassInformer_PlugIn.vcxproj.filters
│ │ ├── IDA_ClassInformer_PlugIn.vcxproj.user
│ │ ├── Main.cpp
│ │ ├── Main.h
│ │ ├── MainDialog.cpp
│ │ ├── MainDialog.h
│ │ ├── PropertySheet.props
│ │ ├── RTTI.cpp
│ │ ├── RTTI.h
│ │ ├── StdAfx.h
│ │ ├── Vftable.cpp
│ │ ├── Vftable.h
│ │ ├── completed.ogg
│ │ ├── dialog.ui
│ │ ├── progress-style.qss
│ │ ├── style.qss
│ │ ├── undname.h
│ │ └── view-style.qss
│ └── README.md
└── ida-support-library-code/
├── IDA_OggPlayer/
│ ├── IDA_OggPlayer.sln
│ ├── IDA_OggPlayer.vcxproj
│ ├── IDA_OggPlayer.vcxproj.filters
│ ├── IDA_OggPlayer.vcxproj.user
│ ├── IdaOgg.cpp
│ ├── IdaOgg.h
│ ├── IdaOggPlayer.LiB
│ ├── IdaOggPlayer.pdb
│ ├── IdaOggPlayer64.LiB
│ ├── IdaOggPlayer64.pdb
│ ├── IdaOggPlayer64D.LiB
│ ├── IdaOggPlayer64D.pdb
│ ├── IdaOggPlayerD.LiB
│ ├── IdaOggPlayerD.pdb
│ ├── PropertySheet.props
│ ├── original README.md
│ ├── stb_vorbis.cpp
│ ├── stb_vorbis.h
│ └── stb_vorbis.txt
├── IDA_SegmentSelect/
│ ├── IDA_SegmentSelect.sln
│ ├── Lib/
│ │ ├── PropertySheet.props
│ │ ├── SegSelect.cpp
│ │ ├── SegSelect.h
│ │ ├── SegSelectRes.qrc
│ │ ├── SegmentDialog.h
│ │ ├── SegmentDialog.ui
│ │ ├── lib.vcxproj
│ │ ├── lib.vcxproj.filters
│ │ └── lib.vcxproj.user
│ ├── SegSelect.LiB
│ ├── SegSelect.h
│ ├── SegSelect64.LiB
│ ├── SegSelect64D.LiB
│ └── SegSelectD.LiB
├── IDA_WaitEx/
│ ├── IDA_WaitBoxEx.sln
│ ├── IDA_WaitBoxEx.txt
│ ├── Lib/
│ │ ├── MyQProgressDialog.h
│ │ ├── PropertySheet.props
│ │ ├── WaitBoxEx.cpp
│ │ ├── WaitBoxEx.h
│ │ ├── WinTaskProgress.cpp
│ │ ├── WinTaskProgress.h
│ │ ├── lib.vcxproj
│ │ ├── lib.vcxproj.filters
│ │ └── lib.vcxproj.user
│ ├── Plugin Example/
│ │ ├── Plugin Example.vcxproj
│ │ ├── Plugin Example.vcxproj.filters
│ │ ├── Plugin Example.vcxproj.user
│ │ └── WaitBoxEx_Example.cpp
│ ├── WaitBoxEx.LiB
│ ├── WaitBoxEx.h
│ ├── WaitBoxEx.pdb
│ ├── WaitBoxEx64.LiB
│ ├── WaitBoxEx64.pdb
│ ├── WaitBoxExD.LiB
│ ├── WaitBoxExD.pdb
│ ├── WaitBoxExD64.LiB
│ ├── WaitBoxExD64.pdb
│ ├── WaitBoxExMd.LiB
│ ├── WaitBoxExMd.pdb
│ ├── WaitBoxExMd64.LiB
│ ├── WaitBoxExMd64.pdb
│ ├── WaitBoxExMdD.LiB
│ ├── WaitBoxExMdD.pdb
│ ├── WaitBoxExMdD64.LiB
│ └── WaitBoxExMdD64.pdb
├── README.md
└── SupportLib/
├── SupportLib.sln
├── SupportLib.vcxproj
├── SupportLib.vcxproj.user
├── Utility.cpp
└── Utility.h
Condensed preview — 68 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (657K chars).
[
{
"path": ".gitignore",
"chars": 100,
"preview": ".vs\nclassinformer-code/x64/\nclassinformer-code/Plugin/x64/\nclassinformer-code/Plugin/GeneratedFiles\n"
},
{
"path": "README.md",
"chars": 1731,
"preview": "# Class Informer\nUse the original classinformer (See the URL below). \nhttps://github.com/kweatherman/IDA_ClassInformer_..."
},
{
"path": "classinformer-code/IDA_ClassInformer.sln",
"chars": 1868,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 17\r\nVisualStudioVersion = 17.10...."
},
{
"path": "classinformer-code/Plugin/ClassInformerRes.qrc",
"chars": 291,
"preview": "<!DOCTYPE RCC><RCC version=\"1.0\">\n\t<qresource prefix=\"/classinf\">\n\t\t<file>banner.png</file>\n\t\t<file>icon.png</file>\n\t\t<f..."
},
{
"path": "classinformer-code/Plugin/Class_Informer.txt",
"chars": 12551,
"preview": "Class Informer for IDA 9:\r\n===========================================================\r\nIDA Pro class vftable finder, na..."
},
{
"path": "classinformer-code/Plugin/IDA_ClassInformer_PlugIn.vcxproj",
"chars": 60556,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro..."
},
{
"path": "classinformer-code/Plugin/IDA_ClassInformer_PlugIn.vcxproj.filters",
"chars": 4972,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui..."
},
{
"path": "classinformer-code/Plugin/IDA_ClassInformer_PlugIn.vcxproj.user",
"chars": 2016,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu..."
},
{
"path": "classinformer-code/Plugin/Main.cpp",
"chars": 48914,
"preview": "\r\n// ****************************************************************************\r\n// File: Core.cpp\r\n// Desc: Class Inf..."
},
{
"path": "classinformer-code/Plugin/Main.h",
"chars": 1975,
"preview": "\r\n// ****************************************************************************\r\n// File: Main.h\r\n// Desc:\r\n//\r\n// ***..."
},
{
"path": "classinformer-code/Plugin/MainDialog.cpp",
"chars": 2145,
"preview": "\r\n// ****************************************************************************\r\n// File: MainDialog.cpp\r\n// Desc: Mai..."
},
{
"path": "classinformer-code/Plugin/MainDialog.h",
"chars": 590,
"preview": "\r\n#pragma once\r\n\r\n#include \"stdafx.h\"\r\n#include <QtWidgets/QDialog>\r\n#include <SegSelect.h>\r\n\r\n#include \"ui_dialog.h\"..."
},
{
"path": "classinformer-code/Plugin/PropertySheet.props",
"chars": 1019,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil..."
},
{
"path": "classinformer-code/Plugin/RTTI.cpp",
"chars": 54062,
"preview": "\r\n// ****************************************************************************\r\n// File: RTTI.cpp\r\n// Desc: Run-Time..."
},
{
"path": "classinformer-code/Plugin/RTTI.h",
"chars": 5099,
"preview": "\r\n// ****************************************************************************\r\n// File: RTTI.h\r\n// Desc: Run-Time Ty..."
},
{
"path": "classinformer-code/Plugin/StdAfx.h",
"chars": 2031,
"preview": "\r\n#pragma once\r\n\r\n#define WIN32_LEAN_AND_MEAN\r\n#define WINVER\t\t 0x0601 // _WIN32_WINNT_WIN7\r\n#define _WIN32_WINNT 0x0601..."
},
{
"path": "classinformer-code/Plugin/Vftable.cpp",
"chars": 6289,
"preview": "\r\n// ****************************************************************************\r\n// File: Vftable.cpp\r\n// Desc: Virtua..."
},
{
"path": "classinformer-code/Plugin/Vftable.h",
"chars": 701,
"preview": "\r\n// ****************************************************************************\r\n// File: Vftable.h\r\n// Desc: Virtual..."
},
{
"path": "classinformer-code/Plugin/dialog.ui",
"chars": 7819,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ui version=\"4.0\">\r\n <class>MainCIDialog</class>\r\n <widget class=\"QDialog\" name=..."
},
{
"path": "classinformer-code/Plugin/progress-style.qss",
"chars": 539,
"preview": "\r\nQWidget\r\n{\r\n\tcolor: #C0C0C0;\r\n background-color: #303030;\r\n\r\n\tfont-family: Noto Sans, Tahoma;\r\n\tfont-size: 13px;\r\n\tf..."
},
{
"path": "classinformer-code/Plugin/style.qss",
"chars": 2345,
"preview": "\r\n/* Class Informer Stylesheet by Sirmabus */\r\n/* Rev 1.0 Feb 22, 2015 */\r\n/* Dark theme, with some Google Material Desi..."
},
{
"path": "classinformer-code/Plugin/undname.h",
"chars": 2973,
"preview": "\r\n// Access to CRT C++ demangler/undecorator function\r\n#pragma once\r\n\r\n// Online: http://demangler.com/\r\n\r\ntypedef PVOID..."
},
{
"path": "classinformer-code/Plugin/view-style.qss",
"chars": 368,
"preview": "\r\n/* Make the table easier to read */\r\nQHeaderView\r\n{\r\n\tfont-family: Noto Sans,Consolas;\r\n\tfont-weight: 100;\r\n\tfont-size..."
},
{
"path": "classinformer-code/README.md",
"chars": 514,
"preview": "Before building this solution, build support libs first.\n\nFind and open PropertySheet.props. Change the paths to the pro..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/IDA_OggPlayer.sln",
"chars": 1493,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 15\r\nVisualStudioVersion = 15.0.27130.201..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/IDA_OggPlayer.vcxproj",
"chars": 12323,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/IDA_OggPlayer.vcxproj.filters",
"chars": 784,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/IDA_OggPlayer.vcxproj.user",
"chars": 163,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/IdaOgg.cpp",
"chars": 5456,
"preview": "\r\n// IdaOgg: A mini Vorbis Ogg clip player for IDA\r\n// By Sirmabus 2015\r\n// Site: http://www.macromonkey.com\r\n// License..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/IdaOgg.h",
"chars": 924,
"preview": "\r\n// IdaOgg: A mini Vorbis Ogg clip player for IDA\r\n// Sean Barrett's \"Ogg Vorbis decoder\"\r\n// http://nothings.org/stb_v..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/PropertySheet.props",
"chars": 590,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/original README.md",
"chars": 4003,
"preview": "stb\n===\n\nsingle-file public domain libraries for C/C++\n\nlibrary | lastest version | category | description\n----------..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/stb_vorbis.cpp",
"chars": 159386,
"preview": "\r\n// Ogg Vorbis audio decoder - v1.04 - public domain\r\n// https://github.com/nothings/stb\r\n// Modified\r\n#define WIN32_LE..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/stb_vorbis.h",
"chars": 8456,
"preview": "\r\n// Ogg Vorbis audio decoder - v1.04 - public domain\r\n// Modified by Sirmabus\r\n#pragma once\r\n\r\n// *********************..."
},
{
"path": "ida-support-library-code/IDA_OggPlayer/stb_vorbis.txt",
"chars": 6709,
"preview": "\r\n\r\n// Ogg Vorbis audio decoder - v1.04 - public domain\r\n// http://nothings.org/stb_vorbis/\r\n//\r\n// Written by Sean Barr..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/IDA_SegmentSelect.sln",
"chars": 1487,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 15\r\nVisualStudioVersion = 15.0.27130.201..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/PropertySheet.props",
"chars": 730,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/SegSelect.cpp",
"chars": 10702,
"preview": "\r\n// SegSelect: IDA Pro Qt multi-segment select dialog\r\n// By Sirmabus 2015\r\n// Docs: http://www.macromonkey.com/ida-wai..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/SegSelect.h",
"chars": 1442,
"preview": "\r\n// SegSelect: IDA Pro Qt multi-segment select dialog\r\n// By Sirmabus 2015\r\n// Version 1.2\r\n// Docs: http://www.macromo..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/SegSelectRes.qrc",
"chars": 235,
"preview": "<RCC>\n <qresource prefix=\"/seglib\">\n <file>code_seg.png</file>\n <file>data_seg.png</file>\n <file..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/SegmentDialog.h",
"chars": 657,
"preview": "\r\n#pragma once\r\n\r\n#include <Windows.h>\r\n\r\n#include <QtWidgets/QDialog>\r\n#include \"ui_SegmentDialog.h\"\r\n\r\n#define USE_DAN..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/SegmentDialog.ui",
"chars": 11337,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ui version=\"4.0\">\r\n <author>Sirmabus</author>\r\n <class>SegSelectDialog</class>..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/lib.vcxproj",
"chars": 25172,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/lib.vcxproj.filters",
"chars": 2685,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/Lib/lib.vcxproj.user",
"chars": 899,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu..."
},
{
"path": "ida-support-library-code/IDA_SegmentSelect/SegSelect.h",
"chars": 1442,
"preview": "\r\n// SegSelect: IDA Pro Qt multi-segment select dialog\r\n// By Sirmabus 2015\r\n// Version 1.2\r\n// Docs: http://www.macromo..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/IDA_WaitBoxEx.sln",
"chars": 3349,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 17\r\nVisualStudioVersion = 17.13...."
},
{
"path": "ida-support-library-code/IDA_WaitEx/IDA_WaitBoxEx.txt",
"chars": 1565,
"preview": "\r\nIDA WaitBoxEx:\r\nVersion 1.5, April 2018\r\nBy Sirmabus\r\nA full featured IDA Pro wait box replacement with progress bar a..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/MyQProgressDialog.h",
"chars": 957,
"preview": "\r\n// Subclass of QProgressDialog for customization\r\n#pragma once\r\n\r\n#define WIN32_LEAN_AND_MEAN\r\n#define WINVER 0x..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/PropertySheet.props",
"chars": 730,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/WaitBoxEx.cpp",
"chars": 11118,
"preview": "\r\n// WaitBoxEx: Custom IDA Pro wait box\r\n// By Sirmabus\r\n// http://www.macromonkey.com\r\n// License: Qt LGPL\r\n#define WIN..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/WaitBoxEx.h",
"chars": 1737,
"preview": "\r\n// WaitBoxEx: Custom IDA Pro wait box\r\n// By Sirmabus\r\n// Version 1.5\r\n// http://www.macromonkey.com\r\n// License: Qt L..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/WinTaskProgress.cpp",
"chars": 3265,
"preview": "\r\n// Windows 7+ taskbar progress\r\n// Sirmabus 2015\r\n// http://www.macromonkey.com\r\n#define WIN32_LEAN_AND_MEAN\r\n#define..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/WinTaskProgress.h",
"chars": 500,
"preview": "\r\n// Windows 7+ taskbar progress\r\n// Sirmabus 2015\r\n// http://www.macromonkey.com\r\n#pragma once\r\n\r\nnamespace TaskProgres..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/lib.vcxproj",
"chars": 46638,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/lib.vcxproj.filters",
"chars": 3759,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Lib/lib.vcxproj.user",
"chars": 2123,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Plugin Example/Plugin Example.vcxproj",
"chars": 21482,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Plugin Example/Plugin Example.vcxproj.filters",
"chars": 223,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Plugin Example/Plugin Example.vcxproj.user",
"chars": 1974,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/Plugin Example/WaitBoxEx_Example.cpp",
"chars": 4881,
"preview": "\r\n// IDA WaitEx plug-in examples\r\n// By Sirmabus 2015\r\n#define WIN32_LEAN_AND_MEAN\r\n#include <windows.h>\r\n\r\n// Minimal I..."
},
{
"path": "ida-support-library-code/IDA_WaitEx/WaitBoxEx.h",
"chars": 1737,
"preview": "\r\n// WaitBoxEx: Custom IDA Pro wait box\r\n// By Sirmabus\r\n// Version 1.5\r\n// http://www.macromonkey.com\r\n// License: Qt L..."
},
{
"path": "ida-support-library-code/README.md",
"chars": 394,
"preview": "You do not need to compile SupportLib.\n\nFind and open PropertySheet.props on each project if it exists.\nChange the paths..."
},
{
"path": "ida-support-library-code/SupportLib/SupportLib.sln",
"chars": 960,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 2013\r\nVisualStudioVersion = 12.0.31101.0..."
},
{
"path": "ida-support-library-code/SupportLib/SupportLib.vcxproj",
"chars": 6771,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micro..."
},
{
"path": "ida-support-library-code/SupportLib/SupportLib.vcxproj.user",
"chars": 163,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu..."
},
{
"path": "ida-support-library-code/SupportLib/Utility.cpp",
"chars": 13942,
"preview": "\r\n// ****************************************************************************\r\n// File: Utility.cpp\r\n// Desc: IDA ut..."
},
{
"path": "ida-support-library-code/SupportLib/Utility.h",
"chars": 5165,
"preview": "\r\n// ****************************************************************************\r\n// File: Utility.h\r\n// Desc: IDA util..."
}
]
About this extraction
This page contains the full source code of the herosi/classinformer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 97 files (597.6 KB), approximately 168.3k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.