-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathpin_taint.h
265 lines (185 loc) · 6.07 KB
/
pin_taint.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
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
// -*- c++ -*-
/**** TODO: Add verbosity ****/
#pragma once
#include <iostream>
#include <fstream>
#include <map>
#include <set>
#include <vector>
#include <string.h>
#ifndef _WIN32
#include <asm/unistd.h>
#endif
#include "pin_misc.h"
#include <libtrace/trace.container.hpp>
// Size of temporary buffers
#define BUFSIZE 128
// Determine architecture
#if _WIN32 || _WIN64
#if _WIN64
#define ARCH_64
#else
#define ARCH_32
#endif
#endif
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ARCH_64
#else
#define ARCH_32
#endif
#endif
// TODO: we need a type for the mapping to variables/registers
typedef uint32_t var;
// We only consider 32-bit memory addresses
// #define address uint32_t
// And enable 2^32 different taint tags
// special values:
// * 0 -> untainted
// * ffffffff -> mixed taint
// * other n -> nth input byte
#define MIXED_TAINT 0xFFFFFFFF
#define NOTAINT 0
typedef uint32_t t;
typedef std::map<var,t> context;
// Some bit masks
#define LOW8 0xff
#define HIGH8 0xff000000
#define LOW16 0xffff
#define HIGH16 0xffff0000
/*********** IDs for taint sources **********/
#define ARG_ID 2
#define ENV_ID 2
/************* Operand Usage **************/
#define RD 0x01
#define WR 0x10
#define RW 0x11
/********************************************/
struct ValSpecRec {
pintrace::RegMem_t type; // Type of value specifier.
ADDRINT loc; // Location of this value.
pintrace::PIN_REGISTER value;// Actual value.
uint32_t usage; // Operand usage (R, RW, W, etc)
uint32_t taint; // Taint status of the value
};
/** Like [frame option] type in ML. If b is true, then f is a valid,
* meaningful frame. If b is false, some failure returned and no
* frame is present. */
struct FrameOption_t {
frame f;
bool b;
FrameOption_t(bool b) {
assert (b == false);
this->b = b;
}
FrameOption_t(bool b, frame &tf) {
this->f = f;
}
FrameOption_t() {
}
};
/* globals */
extern int g_skipTaints;
/* functions */
bool defaultPolicy(ADDRINT addr, uint32_t length, const char *msg);
namespace pintrace { // We will use namespace to avoid collision
typedef bool(*TAINT_POLICY_FUN)(ADDRINT addr, uint32_t length, const char *msg);
struct fdInfo_t {
fdInfo_t() {
name = string("Uninitialized"); offset=-1;
}
fdInfo_t(string name_in, uint64_t offset_in) {
name = name_in; offset = offset_in;
}
string name;
uint64_t offset;
};
typedef std::pair<string, uint64_t> resource_t;
// Tracking the taint during program flow
class TaintTracker {
public:
TaintTracker(ValSpecRec *env);
/** A function to introduce taint in the contexts. Writes
information to state; this state must be passed to
taintIntro */
bool taintPreSC(uint32_t callno, const uint64_t * args, uint32_t &state);
FrameOption_t taintPostSC(const uint32_t bytes,
const uint64_t * args,
ADDRINT &addr,
uint32_t &length,
const uint32_t state);
#ifdef _WIN32
std::vector<frame> taintArgs(char *cmdA, wchar_t *cmdW);
#else
std::vector<frame> taintArgs(int args, char **argv);
#endif
#ifdef _WIN32
std::vector<frame> taintEnv(char *env, wchar_t *wenv);
#else
std::vector<frame> taintEnv(char **env);
#endif
// A function to propagate taint
void taintPropagation(context &delta);
// A function to apply taint policies
bool taintChecking();
void setTaintContext(context &delta);
void resetTaint(context &delta);
void setCount(uint32_t cnt);
void setTaintArgs(bool taint);
void setTaintEnv(string env_var);
void trackFile(string file);
void setTaintStdin();
void setTaintNetwork();
// Helpers
// A function to check whether the instruction arguments are tainted
uint32_t getReadTaint(context &delta);
bool hasTaint(context &delta);
//bool propagatedTaint(bool branch);
void printMem();
void printRegs(context &delta);
void postSysCall(context &delta);
void acceptHelper(uint32_t fd);
FrameOption_t recvHelper(uint32_t fd, void *ptr, size_t len);
uint32_t getRegTaint(context &delta, uint32_t reg_int);
uint32_t getMemTaint(ADDRINT addr, RegMem_t type);
void untaintMem(ADDRINT addr);
static uint32_t getSize(RegMem_t type);
static bool isValid(RegMem_t type);
static bool isReg(RegMem_t type);
static bool isMem(RegMem_t type);
private:
// The taint number (producing taint tags)
uint32_t taintnum;
// a context defining a map from registers to taint
// this is maintainted externally now
//context delta;
// We can use a byte-centric approach, each byte maps to taint
// a context defining a map from memory locations to taint
context memory;
// The table containing the values of the current instruction
ValSpecRec *values;
// How many values are being used
uint32_t count;
/********** Syscall-specific vars ***********/
std::set<string> taint_files;
std::map<resource_t, uint32_t> taint_mappings;
std::map<uint32_t, fdInfo_t> fds;
std::map<uint32_t,uint32_t> sections;
bool taint_net;
bool taint_args;
std::set<string> taint_env;
/********************************************/
// The taint policy function
TAINT_POLICY_FUN pf;
#ifdef _WIN32
std::map<unsigned int, unsigned int> syscall_map;
#endif
void addTaintToWritten(context &delta, uint32_t tag);
uint32_t combineTaint(uint32_t oldtag, uint32_t newtag);
uint32_t exists(context &ctx, uint32_t elem);
uint32_t getTaint(context &ctx, uint32_t elem);
FrameOption_t introMemTaint(ADDRINT addr, uint32_t length, const char *source, int64_t offset);
FrameOption_t introMemTaintFromFd(uint32_t fd, ADDRINT addr, uint32_t length);
void setTaint(context &ctx, uint32_t key, uint32_t tag);
};
}; // End of namespace