1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include "rtti.h"
#include "microsoft.h"
#include "itanium.h"
using namespace BinaryNinja;
bool MetadataExists(const Ref<BinaryView>& view)
{
return view->QueryMetadata(VIEW_METADATA_RTTI) != nullptr;
}
void RTTIAnalysis(const Ref<AnalysisContext>& analysisContext)
{
auto view = analysisContext->GetBinaryView();
auto platform = view->GetDefaultPlatform();
if (!platform)
return;
auto platformName = platform->GetName();
if (platformName.find("window") != std::string::npos)
{
// We currently only want to check for MSVC rtti on windows platforms
try
{
auto processor = RTTI::Microsoft::MicrosoftRTTIProcessor(view);
processor.ProcessRTTI();
view->StoreMetadata(VIEW_METADATA_RTTI, processor.SerializedMetadata(), true);
}
catch (std::exception& e)
{
LogError("MSVC RTTI Analysis failed with uncaught exception: %s", e.what());
}
}
try
{
auto processor = RTTI::Itanium::ItaniumRTTIProcessor(view);
processor.ProcessRTTI();
view->StoreMetadata(VIEW_METADATA_RTTI, processor.SerializedMetadata(), true);
}
catch (std::exception& e)
{
LogError("Itanium RTTI Analysis failed with uncaught exception: %s", e.what());
}
}
void VFTAnalysis(const Ref<AnalysisContext>& analysisContext)
{
auto view = analysisContext->GetBinaryView();
if (!MetadataExists(view))
return;
try
{
auto microsoftProcessor = RTTI::Microsoft::MicrosoftRTTIProcessor(view);
microsoftProcessor.ProcessVFT();
// TODO: We have to store the data for the second processor to pick up the info.
view->StoreMetadata(VIEW_METADATA_RTTI, microsoftProcessor.SerializedMetadata(), true);
}
catch (std::exception& e)
{
LogError("MSVC VFT Analysis failed with uncaught exception: %s", e.what());
}
try
{
auto itaniumProcessor = RTTI::Itanium::ItaniumRTTIProcessor(view);
itaniumProcessor.ProcessVFT();
view->StoreMetadata(VIEW_METADATA_RTTI, itaniumProcessor.SerializedMetadata(), true);
}
catch (std::exception& e)
{
LogError("Itanium VFT Analysis failed with uncaught exception: %s", e.what());
}
}
extern "C" {
BN_DECLARE_CORE_ABI_VERSION
#ifdef DEMO_EDITION
bool RTTIPluginInit()
#else
BINARYNINJAPLUGIN bool CorePluginInit()
#endif
{
// TODO: In the future we will have a function level workflow which:
// TODO: 1. Uses MSVC metadata to identify if a function is apart of a VFT
// TODO: a. Or possibly we can tag some info to the function as apart of the VFT analysis, this would save a lookup.
// TODO: 2. Identify if the function is unique to a class, renaming and retyping if true
// TODO: 3. Identify functions which address a VFT and are probably a constructor (alloc use), retyping if true
// TODO: 4. Identify functions which address a VFT and are probably a deconstructor (free use), retyping if true
Ref<Workflow> rttiMetaWorkflow = Workflow::Instance("core.module.metaAnalysis")->Clone();
// Add RTTI analysis.
rttiMetaWorkflow->RegisterActivity(R"~({
"title": "RTTI Analysis",
"name": "analysis.rtti.rttiAnalysis",
"role": "action",
"description": "This analysis step attempts to parse and symbolize rtti information.",
"aliases": ["plugin.msvc.rttiAnalysis"],
"eligibility": {
"runOnce": true,
"auto": {}
}
})~", &RTTIAnalysis);
// Add Virtual Function Table analysis.
rttiMetaWorkflow->RegisterActivity(R"~({
"title": "VFT Analysis",
"name": "analysis.rtti.vftAnalysis",
"role": "action",
"description": "This analysis step attempts to parse and symbolize virtual function table information.",
"aliases": ["plugin.msvc.vftAnalysis"],
"eligibility": {
"runOnce": true,
"auto": {}
},
"dependencies": {
"downstream": ["core.module.update"]
}
})~", &VFTAnalysis);
// Run rtti before debug info is applied.
rttiMetaWorkflow->Insert("core.module.loadDebugInfo", "analysis.rtti.rttiAnalysis");
// Run vft after functions have analyzed (so that the virtual functions have analyzed)
rttiMetaWorkflow->InsertAfter("core.module.extendedAnalysis", "analysis.rtti.vftAnalysis");
Workflow::RegisterWorkflow(rttiMetaWorkflow);
return true;
}
}
|