forked from allthingsida/GraphSlick
-
Notifications
You must be signed in to change notification settings - Fork 0
/
algo.cpp
211 lines (176 loc) · 4.62 KB
/
algo.cpp
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#include "algo.hpp"
//--------------------------------------------------------------------------
bool func_to_mgraph(
ea_t func_ea,
mutable_graph_t *mg,
gnodemap_t &node_map,
qflow_chart_t *fc,
bool append_node_id)
{
// Build function's flowchart (if needed)
qflow_chart_t _fc;
if (fc == NULL)
{
fc = &_fc;
if (!get_func_flowchart(func_ea, *fc))
return false;
}
// Resize the graph
int nodes_count = fc->size();
mg->resize(nodes_count);
// Build the node cache and edges
for (int nid=0; nid < nodes_count; nid++)
{
qbasic_block_t &block = fc->blocks[nid];
gnode_t *nc = node_map.add(nid);
// Append node ID to the output
if (append_node_id)
nc->text.sprnt("ID(%d)\n", nid);
// Generate disassembly text
get_disasm_text(
block.startEA,
block.endEA,
&nc->text);
// Build edges
for (int nid_succ=0, succ_sz=fc->nsucc(nid); nid_succ < succ_sz; nid_succ++)
{
int nsucc = fc->succ(nid, nid_succ);
mg->add_edge(nid, nsucc, NULL);
}
}
return true;
}
//--------------------------------------------------------------------------
void build_groupman_from_fc(
qflow_chart_t *fc,
groupman_t *gm,
bool sanitize)
{
// Clear previous groupman contents
gm->clear();
gm->src_filename = "noname.bbgroup";
// Resize the graph
int nodes_count = fc->size();
// Build groupman
for (int nid=0; nid < nodes_count; nid++)
{
qbasic_block_t &block = fc->blocks[nid];
psupergroup_t sg = gm->add_supergroup();
sg->id.sprnt("ID_%d", nid);
sg->name.sprnt("SG_%d", nid);
sg->is_synthetic = false;
pnodegroup_t ng = sg->add_nodegroup();
pnodedef_t nd = ng->add_node();
nd->nid = nid;
nd->start = block.startEA;
nd->end = block.endEA;
gm->map_nodedef(nid, nd);
}
if (sanitize)
{
if (sanitize_groupman(BADADDR, gm, fc))
gm->initialize_lookups();
}
}
//--------------------------------------------------------------------------
void build_groupman_from_3dvec(
qflow_chart_t *fc,
int_3dvec_t &path,
groupman_t *gm,
bool sanitize)
{
// Clear previous groupman contents
gm->clear();
gm->src_filename = "noname.bbgroup";
// Build groupman
int sg_id = 0;
for (int_3dvec_t::iterator it_sg=path.begin();
it_sg != path.end();
++it_sg, ++sg_id)
{
// Build super group
psupergroup_t sg = gm->add_supergroup();
sg->id.sprnt("ID_%d", sg_id);
sg->name.sprnt("SG_%d", sg_id);
sg->is_synthetic = false;
// Build SG
int_2dvec_t &ng_vec = *it_sg;
for (int_2dvec_t::iterator it_ng= ng_vec.begin();
it_ng != ng_vec.end();
++it_ng)
{
// Build NG
pnodegroup_t ng = sg->add_nodegroup();
intvec_t &nodes_vec = *it_ng;
// Build nodes
for (intvec_t::iterator it_nd = nodes_vec.begin();
it_nd != nodes_vec.end();
++it_nd)
{
int nid = *it_nd;
qbasic_block_t &block = fc->blocks[nid];
pnodedef_t nd = ng->add_node();
nd->nid = nid;
nd->start = block.startEA;
nd->end = block.endEA;
gm->map_nodedef(nid, nd);
}
}
}
if (sanitize)
{
if (sanitize_groupman(BADADDR, gm, fc))
gm->initialize_lookups();
}
}
//--------------------------------------------------------------------------
bool sanitize_groupman(
ea_t func_ea,
groupman_t *gm,
qflow_chart_t *fc)
{
// Build function's flowchart (if needed)
qflow_chart_t _fc;
if (fc == NULL)
{
fc = &_fc;
if (!get_func_flowchart(func_ea, *fc))
return false;
}
// Create a group for all potentially missing nodes
psupergroup_t missing_sg = new supergroup_t();
int nodes_count = fc->size();
nid2ndef_t *nds = gm->get_nds();
// Verify that all nodes are present
for (int n=0; n < nodes_count; n++)
{
nid2ndef_t::iterator it = nds->find(n);
if (it != nds->end())
continue;
// Convert basic block to an ND
qbasic_block_t &block = fc->blocks[n];
pnodedef_t nd = new nodedef_t();
nd->nid = n;
nd->start = block.startEA;
nd->end = block.endEA;
// Add the node to its own group
pnodegroup_t ng = missing_sg->add_nodegroup();
ng->add_node(nd);
}
if (missing_sg->gcount() == 0)
{
// No orphan nodes where found, get rid of the group
delete missing_sg;
}
else
{
// Found at least one orphan node, add it to the groupman
missing_sg->name = missing_sg->id = "orphan_nodes";
// This is a synthetic group
missing_sg->is_synthetic = true;
gm->add_supergroup(
gm->get_path_sgl(),
missing_sg);
}
return true;
}