-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtraceFunctions.cpp
More file actions
131 lines (125 loc) · 4.16 KB
/
traceFunctions.cpp
File metadata and controls
131 lines (125 loc) · 4.16 KB
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
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <algorithm>
#include "pin.H"
struct Node{
// name of the function
std::string label;
// number of the function starting from 1
unsigned int number = 1;
// used to format the graph
// 0 if the node is both a parent and a child, and 1 otherwise.
bool show = true;
};
// map from function name to the function children
std::map<std::string, std::vector<Node>> parents;
// map to store all seen children nodes
std::map<ADDRINT, unsigned int> seenChildren;
// function number counter
unsigned int stepsCounter = 0;
// add function to functions map
void addToMap(std::string sourceName, std::string targetName, ADDRINT sourceAddress, ADDRINT targetAddress){
stepsCounter++;
Node calledFunction = {targetName,stepsCounter,1};
auto parentFound = parents.find(sourceName);
if(parentFound != parents.end()){
// if parent was found
seenChildren.insert({targetAddress,stepsCounter});
parentFound->second.push_back(calledFunction);
}else{
// new parent
auto childFound = seenChildren.find(sourceAddress);
Node parent;
bool parentFound = false;
if(childFound != seenChildren.end()){
// if the function calls other functions (parent) and it is a child of another function.
// set show =0, and use the number the child node has
parent = {sourceName,childFound->second,false};
parentFound = true;
}
else if(sourceName=="main"){
// create new parent "new root node"
// main is the root function
parent = {sourceName,++stepsCounter,true};
parentFound =true;
}
if(parentFound==false){
return;
}
std::vector<Node> v;
v.push_back(parent);
v.push_back(calledFunction);
parents.insert({sourceName,v});
}
}
// format the dot graph file
void createDotGraphOutput(int code, void *v){
std::string graphFileName = "graph.txt";
std::ofstream myfile;
myfile.open (graphFileName.c_str());
myfile << "digraph executedFunctions {\nforcelabels=true;\nedge [ style=dashed ];\n";
// print labeles
for(auto const& x : parents){
for(auto & element : x.second){
if(element.show==1){
myfile << element.number << " [label=" << element.label << "]\n";
}
}
}
// print subgraphs
for(auto const& x : parents){
myfile << "subgraph cluster_" << x.first << "{\n";
for(auto & element : x.second){
if(element.show==1){
myfile << element.number << "\n";
}
}
myfile << "}\n";
}
// print nodes connections
Node pre;
bool preFound =false;
for(auto const& x : parents){
for(auto const& element : x.second){
if(preFound){
myfile << pre.number << " -> " << element.number << "\n";
}
pre = element;
preFound = true;
}
preFound = false;
}
myfile << "}\n";
myfile.close();
}
// instrumentation function for each instruction
void instrumentInsn(INS ins, void *v){
// check if instruction is a call instruction
if(!INS_IsCall(ins) || !INS_IsDirectControlFlow(ins)){
return;
}
// check if the instruction is in the main executable
IMG img = IMG_FindByAddress(INS_Address(ins));
if(!IMG_Valid(img) || !IMG_IsMainExecutable(img)){
return;
}
RTN source = INS_Rtn(ins);
ADDRINT sourceAddress = RTN_Address(source);
std::string sourceName = RTN_Name(source);
ADDRINT targetAddress = INS_DirectControlFlowTargetAddress(ins);
std::string targetName = RTN_FindNameByAddress(targetAddress);
addToMap(sourceName,targetName,sourceAddress,targetAddress);
}
int main(int argc, char *argv[]){
PIN_InitSymbols();
if(PIN_Init(argc,argv)) {
return 1;
}
// instrument at instruction granularity
INS_AddInstrumentFunction(instrumentInsn, NULL);
PIN_AddFiniFunction(createDotGraphOutput, NULL);
PIN_StartProgram();
return 0;
}