-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathshadow.h
160 lines (144 loc) · 3.33 KB
/
shadow.h
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
#ifndef SHADOW_H
#define SHADOW_H
#include "pin.H"
#include "instlib.H"
#include <unordered_map>
#include <map>
const int regionsBits = 2;
const int regionsNum = 1 << regionsBits;
const int regionsOff = 7;
const int cacheLineSize = 1 << regionsOff; // 128 bytes
class CacheLine
{
private:
enum elementSizes {one, two, four};
elementSizes elementSize;
void *memory;
public:
//read
long read(unsigned int offset);
//write
void write(unsigned int offset, long value);
//
CacheLine();
CacheLine(const CacheLine &s);
~CacheLine();
CacheLine& operator=(const CacheLine& s);
CacheLine& operator=(CacheLine&& rhs);
void swap(CacheLine &s);
};
class ShadowMemory
{
private:
unordered_map<ADDRINT,CacheLine> cacheShadowMemory[regionsNum];
map<ADDRINT,size_t> allocationMap;
#ifdef THREADSAFE
PIN_RWMUTEX regionLock[regionsNum];
PIN_RWMUTEX allocationLock;
#endif
void writeMemUnlocked(ADDRINT address, long depth);
public:
//Access Memory
long readMem(ADDRINT address);
long readMem(ADDRINT address, USIZE width);
//Set Memory
void writeMem(ADDRINT address, long depth);
void writeMem(ADDRINT address, long depth, USIZE width);
//Clear
void clear();
//Add Memory Allocation
void arrayMem(ADDRINT start, size_t size, bool tracinglevel);
//Free Memroy Allocation
void arrayMemClear(ADDRINT start);
//Check if addr is allocated
bool memIsArray(VOID *addr);
//Print allocation map
void printAllocationMap(FILE *out);
//
ShadowMemory();
ShadowMemory(const ShadowMemory &s);
~ShadowMemory();
ShadowMemory& operator=(const ShadowMemory& s);
ShadowMemory& operator=(ShadowMemory&& rhs);
void swap(ShadowMemory &s);
};
class ShadowRegisters
{
private:
long shadowRegisters[XED_REG_LAST]; // Register Memory
public:
//Access Register
long readReg(size_t reg);
//Set Register
void writeReg(size_t reg, long depth);
};
class ShadowMemoryNoCache
{
long shadowRegisters[XED_REG_LAST]; // Register Memory
map<ADDRINT,long> shadowMemory;
map<ADDRINT,size_t> allocationMap;
public:
//Access Memory
long readMem(ADDRINT address)
{
return shadowMemory[address];
};
//Set Memory
void writeMem(ADDRINT address, long depth)
{
shadowMemory[address] = depth;
}
//Clear
void clear()
{
for(int i = 0; i < XED_REG_LAST; i++)
{
shadowRegisters[i] = 0;
}
shadowMemory.clear();
for(auto it = allocationMap.begin(); it != allocationMap.end(); it++)
{
size_t start = it->first;
for(size_t i = 0; i < allocationMap[start]; i++)
this->writeMem(start+i, 1);
}
};
//Add Memory Allocation
void arrayMem(ADDRINT start, size_t size, bool tracinglevel)
{
if(size > 0)
allocationMap[start] = size;
if(tracinglevel)
for(size_t i = 0; i < size; i++)
this->writeMem(start+i, 1);
};
//Free Memroy Allocation
void arrayMemClear(ADDRINT start)
{
for(size_t i = 0; i < allocationMap[start]; i++)
this->writeMem(start+i, 0);
allocationMap.erase(start);
};
//Check if addr is allocated
bool memIsArray(VOID *addr)
{
auto it = allocationMap.upper_bound((size_t) addr);
if(it != allocationMap.end())
{
--it;
if(((size_t)(*it).first + (*it).second > (size_t)addr))
return true;
}
return false;
};
//Print allocation map
void printAllocationMap(FILE *out)
{
for(auto a : allocationMap)
{
fprintf(out, "[%p,%p]", (void*) a.first, (void *)(a.first + a.second));
}
fprintf(out, "\n");
};
};
#endif