15
15
#include " callstack_instr/callstack_instr.h"
16
16
17
17
extern " C" {
18
+ #include < hypercaller/hypercaller.h>
18
19
19
20
#include " panda/rr/rr_log.h"
20
21
#include " panda/plog.h"
@@ -37,14 +38,14 @@ extern "C" {
37
38
bool init_plugin (void *);
38
39
void uninit_plugin (void *);
39
40
40
- int get_loglevel () ;
41
+ int get_loglevel ();
41
42
void set_loglevel (int new_loglevel);
42
43
}
43
44
44
45
const char *global_src_filename = NULL ;
45
46
uint64_t global_src_linenum;
46
47
unsigned global_ast_loc_id;
47
- uint64_t global_funcaddr;
48
+ // uint64_t global_funcaddr;
48
49
bool debug = false ;
49
50
50
51
#define dprintf (...) if (debug) { printf (__VA_ARGS__); fflush (stdout); }
@@ -97,11 +98,18 @@ void print_membytes(CPUState *env, target_ulong a, target_ulong len) {
97
98
printf (" }" );
98
99
}
99
100
101
+ struct args {
102
+ CPUState *cpu;
103
+ const char *src_filename;
104
+ uint64_t src_linenum;
105
+ unsigned ast_loc_id;
106
+ // uint64_t funcaddr;
107
+ };
108
+
100
109
// max length of strnlen or taint query
101
110
#define LAVA_TAINT_QUERY_MAX_LEN (target_ulong)64ULL
102
- #if defined(TARGET_I386)
111
+ #if defined(TARGET_I386) || defined(TARGET_ARM)
103
112
void lava_taint_query (target_ulong buf, LocType loc_t , target_ulong buf_len, const char *astnodename) {
104
-
105
113
dprintf (" [pri_taint] Attempt to lava_taint_query\n " );
106
114
107
115
// can't do a taint query if it is not a valid register (loc) or if
@@ -115,20 +123,24 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con
115
123
dprintf (" [pri_taint] The Location is either error OR constant. Shouldn't happen based on pfun()\n " );
116
124
return ;
117
125
}
118
- if (!pandalog || !taint2_enabled () || taint2_num_labels_applied () == 0 ) {
119
- dprintf (" [pri_taint] No Panda log, Taint2 not enabled, or No taint2 num labeled applied \n " );
126
+ if (!pandalog || !taint2_enabled ()) {
127
+ dprintf (" [pri_taint] No Panda log or Taint2 not enabled\n " );
120
128
return ;
121
129
}
130
+ if (taint2_num_labels_applied () == 0 ) {
131
+ // see taint_api.cpp
132
+ dprintf (" [pri_taint] No taint2 num labeled applied\n " );
133
+ }
122
134
dprintf (" [pri_taint] OK, Seems like I can Lava Taint! LFG!\n " );
123
135
124
136
CPUState *cpu = first_cpu;
125
- CPUArchState *env = (CPUArchState *)cpu-> env_ptr ;
137
+ CPUArchState *env = (CPUArchState *) cpu -> env_ptr;
126
138
bool is_strnlen = ((int ) buf_len == -1 );
127
- hwaddr phys = loc_t == LocMem ? panda_virt_to_phys (cpu, buf) : 0 ;
128
- ram_addr_t RamOffset = RAM_ADDR_INVALID ;
139
+ extern ram_addr_t ram_size ;
140
+ target_ulong phys = loc_t == LocMem ? panda_virt_to_phys (cpu, buf) : 0 ;
129
141
130
- if (phys == (hwaddr) -1
131
- || PandaPhysicalAddressToRamOffset (&RamOffset, phys, false ) != MEMTX_OK) {
142
+ if (phys == -1 || phys > ram_size) {
143
+ dprintf ( " [pri_taint] The physical address is invalid \n " );
132
144
return ;
133
145
}
134
146
@@ -163,7 +175,7 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con
163
175
// is there *any* taint on this extent
164
176
uint32_t num_tainted = 0 ;
165
177
for (uint32_t i = 0 ; i < len; i++) {
166
- Addr a = loc_t == LocMem ? make_maddr (RamOffset + i) : make_greg (buf, i); /* HACK: presumes for the same physical page ram_addr_t(x + i) == ram_addr_t(x) + i */
178
+ Addr a = loc_t == LocMem ? make_maddr (phys + i) : make_greg (buf, i);
167
179
if (taint2_query (a)) {
168
180
num_tainted++;
169
181
}
@@ -185,7 +197,7 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con
185
197
// this is just a snippet. we dont want to write 1M buffer
186
198
if (loc_t == LocMem) {
187
199
for (int i = 0 ; i < len; i++) {
188
- panda_physical_memory_rw (phys + i, (uint8_t *)&data[i], 1 , false );
200
+ panda_physical_memory_read (phys + i, (uint8_t *)&data[i], 1 );
189
201
}
190
202
} else {
191
203
for (int i = 0 ; i < len; i++) {
@@ -199,8 +211,8 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con
199
211
// 2. iterate over the bytes in the extent and pandalog detailed info about taint
200
212
std::vector<Panda__TaintQuery *> tq;
201
213
for (uint32_t offset = 0 ; offset < len; offset++) {
202
- // uint32_t pa_indexed = phys + offset;
203
- Addr a = loc_t == LocMem ? make_maddr (RamOffset + offset ) : make_greg (buf, offset); /* HACK: presumes for the same physical page ram_addr_t(x + i) == ram_addr_t(x) + i */
214
+ uint32_t pa_indexed = phys + offset;
215
+ Addr a = loc_t == LocMem ? make_maddr (pa_indexed ) : make_greg (buf, offset);
204
216
if (taint2_query (a)) {
205
217
if (loc_t == LocMem) {
206
218
dprintf (" \" %s\" @ 0x" TARGET_FMT_lx " is tainted\n " , astnodename, buf + offset);
@@ -231,16 +243,7 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con
231
243
pandalog_taint_query_free (ptq);
232
244
}
233
245
}
234
- #endif
235
- struct args {
236
- CPUState *cpu;
237
- const char *src_filename;
238
- uint64_t src_linenum;
239
- unsigned ast_loc_id;
240
- uint64_t funcaddr;
241
- };
242
246
243
- #if defined(TARGET_I386)
244
247
void pfun (void *var_ty_void, const char *var_nm, LocType loc_t , target_ulong loc, void *in_args) {
245
248
if (!taint2_enabled ()) {
246
249
dprintf (" [pri_taint] Taint2 was not enabled (pfun called)\n " );
@@ -255,7 +258,9 @@ void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc
255
258
return ;
256
259
}
257
260
}
261
+
258
262
const char *var_ty = dwarf2_type_to_string ((DwarfVarType *) var_ty_void);
263
+
259
264
// restore args
260
265
struct args *args = (struct args *) in_args;
261
266
CPUState *pfun_cpu = args->cpu ;
@@ -264,7 +269,7 @@ void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc
264
269
global_src_filename = args->src_filename ;
265
270
global_src_linenum = args->src_linenum ;
266
271
global_ast_loc_id = args->ast_loc_id ;
267
- global_funcaddr = args->funcaddr ;
272
+ // global_funcaddr = args->funcaddr;
268
273
// target_ulong guest_dword;
269
274
// std::string ty_string = std::string(var_ty);
270
275
// size_t num_derefs = std::count(ty_string.begin(), ty_string.end(), '*');
@@ -289,23 +294,9 @@ void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc
289
294
default :
290
295
assert (1 ==0 );
291
296
}
292
- // free(si);
293
- }
294
- /*
295
- void on_line_change(CPUState *cpu, target_ulong pc, const char *file_Name, const char *funct_name, unsigned long long lno){
296
- if (taint2_enabled()){
297
- struct args args = {cpu, file_Name, lno, 0};
298
- //printf("[%s] %s(), ln: %4lld, pc @ 0x%x\n",file_Name, funct_name,lno,pc);
299
- pri_funct_livevar_iter(cpu, pc, (liveVarCB) pfun, (void *)&args);
300
- //pri_all_livevar_iter(cpu, pc, (liveVarCB) pfun, (void *)&args);
301
- }
302
- }
303
- void on_fn_start(CPUState *cpu, target_ulong pc, const char *file_Name, const char *funct_name, unsigned long long lno){
304
- struct args args = {cpu, file_Name, lno, 0};
305
- dprintf("fn-start: %s() [%s], ln: %4lld, pc @ 0x" TARGET_FMT_lx "\n",funct_name,file_Name,lno,pc);
306
- pri_funct_livevar_iter(cpu, pc, (liveVarCB) pfun, (void *)&args);
307
297
}
308
298
299
+ /*
309
300
// Trace logging in the level of source code
310
301
void hypercall_log_trace(unsigned ast_loc_id) {
311
302
Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
@@ -315,37 +306,54 @@ void hypercall_log_trace(unsigned ast_loc_id) {
315
306
pandalog_write_entry(&ple);
316
307
}
317
308
*/
318
- # ifdef TARGET_I386
309
+
319
310
// Support all features of label and query program
320
- void i386_hypercall_callback (CPUState *cpu) {
311
+ void lava_hypercall (CPUState *cpu) {
321
312
dprintf (" [pri_taint] Calling lava hypercall!\n " );
322
-
323
313
CPUArchState *env = (CPUArchState*) cpu->env_ptr ;
324
314
if (taint2_enabled ()) {
325
315
// LAVA Hypercall
326
- #ifdef TARGET_X86_64
327
- target_ulong addr = panda_virt_to_phys (cpu, env->regs [R_EDI]);
328
- #else
316
+ #if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
317
+ target_ulong addr = panda_virt_to_phys (cpu, env->regs [0 ]);
318
+ #elif defined(TARGET_ARM) && defined(TARGET_AARCH64)
319
+ target_ulong addr = panda_virt_to_phys (cpu, env->xregs [0 ]);
320
+ #elif defined(TARGET_I386) && !defined(TARGET_X86_64)
329
321
target_ulong addr = panda_virt_to_phys (cpu, env->regs [R_EBX]);
322
+ #elif defined(TARGET_I386) && defined(TARGET_X86_64)
323
+ target_ulong addr = panda_virt_to_phys (cpu, env->regs [R_EDI]);
330
324
#endif
331
-
325
+
332
326
if ((int ) addr == -1 ) {
333
- #ifdef TARGET_X86_64
327
+ #if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
334
328
dprintf (" [pri_taint] panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%x paddr=0x%x\n " ,
335
- (uint32_t ) env->regs [R_EDI], (uint32_t ) addr);
336
- #else
329
+ (uint32_t ) env->regs [0 ], (uint32_t ) addr);
330
+ #elif defined(TARGET_ARM) && defined(TARGET_AARCH64)
331
+ dprintf (" [pri_taint] panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%lx paddr=0x%lx\n " ,
332
+ (uint64_t ) env->xregs [0 ], (uint64_t ) addr);
333
+ #elif defined(TARGET_I386) && !defined(TARGET_X86_64)
337
334
dprintf (" [pri_taint] panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%x paddr=0x%x\n " ,
338
335
(uint32_t ) env->regs [R_EBX], (uint32_t ) addr);
336
+ #elif defined(TARGET_I386) && defined(TARGET_X86_64)
337
+ dprintf (" [pri_taint] panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%lx paddr=0x%lx\n " ,
338
+ (uint64_t ) env->regs [R_EDI], (uint64_t ) addr);
339
339
#endif
340
340
}
341
341
else if (pandalog) {
342
342
dprintf (" [pri_taint] Hypercall is OK and Panda Log is set\n " );
343
343
PandaHypercallStruct phs;
344
- panda_virtual_memory_read (cpu, env->regs [R_EAX], (uint8_t *) &phs, sizeof (phs));
344
+ #if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
345
+ panda_virtual_memory_read (cpu, env->regs [0 ], (uint8_t *) &phs, sizeof (phs));
346
+ #elif defined(TARGET_ARM) && defined(TARGET_AARCH64)
347
+ panda_virtual_memory_read (cpu, env->xregs [0 ], (uint8_t *) &phs, sizeof (phs));
348
+ #elif defined(TARGET_I386) && !defined(TARGET_X86_64)
349
+ panda_virtual_memory_read (cpu, env->regs [R_EBX], (uint8_t *) &phs, sizeof (phs));
350
+ #elif defined(TARGET_I386) && defined(TARGET_X86_64)
351
+ panda_virtual_memory_read (cpu, env->regs [R_EDI], (uint8_t *) &phs, sizeof (phs));
352
+ #endif
345
353
346
354
// To be used for chaff bugs?
347
- uint64_t funcaddr = 0 ;
348
- panda_virtual_memory_read (cpu, phs.info , (uint8_t *)&funcaddr, sizeof (target_ulong));
355
+ // uint64_t funcaddr = 0;
356
+ // panda_virtual_memory_read(cpu, phs.info, (uint8_t*)&funcaddr, sizeof(target_ulong));
349
357
// if the phs action is a pri_query point, see
350
358
// lava/include/pirate_mark_lava.h
351
359
if (phs.action == 13 ) {
@@ -359,7 +367,8 @@ void i386_hypercall_callback(CPUState *cpu) {
359
367
dprintf (" [pri_taint] panda hypercall: [%s], "
360
368
" ln: %4ld, pc @ 0x" TARGET_FMT_lx " \n " ,
361
369
info.filename ,
362
- info.line_number ,pc);
370
+ info.line_number , pc);
371
+
363
372
// Calls 'pri_funct_livevar_iter' in pri.c, which calls 'on_funct_livevar_iter'
364
373
// In Dwarf2, the function 'on_funct_livevar_iter' is mapped to 'dwarf_funct_livevar_iter'
365
374
// This is passing the function 'pfun' to 'pri_funct_livevar_iter', which is called at the end
@@ -368,6 +377,7 @@ void i386_hypercall_callback(CPUState *cpu) {
368
377
else {
369
378
dprintf (" [pri_taint] pri_get_pc_src_info has failed: %d != 0.\n " , rc);
370
379
}
380
+ // hypercall_log_trace(phs.src_filename);
371
381
}
372
382
else {
373
383
dprintf (" [pri_taint] Invalid action value in PHS struct: %d != 13.\n " , phs.action );
@@ -380,71 +390,43 @@ void i386_hypercall_callback(CPUState *cpu) {
380
390
else {
381
391
dprintf (" [pri_taint] taint2 is not enabled (hypercall)\n " );
382
392
}
383
- return ret;
384
393
}
385
- #endif // TARGET_I386
386
-
387
-
388
- bool guest_hypercall_callback (CPUState *cpu) {
389
- #ifdef TARGET_I386
390
- return i386_hypercall_callback (cpu);
391
394
#endif
392
395
393
- #ifdef TARGET_ARM
394
- // not implemented for now
395
- // arm_hypercall_callback(cpu);
396
- #endif
397
-
398
- return false ;
399
- }
400
- #endif
401
- /*
402
- void on_taint_change(Addr a, uint64_t size){
403
- uint32_t num_tainted = 0;
404
- for (uint32_t i=0; i<size; i++){
405
- a.off = i;
406
- num_tainted += (taint2_query(a) != 0);
407
- }
408
- if (num_tainted > 0) {
409
- printf("In taint change!\n");
410
- }
411
- }
412
- */
413
396
bool init_plugin (void *self) {
414
-
415
- #if defined(TARGET_I386)
397
+ #if defined(TARGET_I386) || defined(TARGET_ARM)
416
398
panda_arg_list *args = panda_get_args (" pri_taint" );
417
399
debug = panda_parse_bool_opt (args, " debug" , " enable debug output" );
418
400
419
401
panda_require (" callstack_instr" );
420
402
assert (init_callstack_instr_api ());
421
403
panda_require (" pri" );
422
404
assert (init_pri_api ());
423
- panda_require (" dwarf2" );
424
- assert (init_dwarf2_api ());
425
405
panda_require (" taint2" );
426
406
assert (init_taint2_api ());
427
-
428
- panda_cb pcb;
429
- pcb.guest_hypercall = guest_hypercall_callback;
430
- panda_register_callback (self, PANDA_CB_GUEST_HYPERCALL, pcb);
431
- printf (" [pri_taint] This plugin is activated!\n " );
407
+ panda_require (" dwarf2" );
408
+ assert (init_dwarf2_api ());
432
409
433
410
// If taint isn't already enabled, turn it on.
434
411
if (!taint2_enabled ()) {
435
412
printf (" [pri_taint] enabling taint now!\n " );
436
413
taint2_enable_taint ();
437
414
}
415
+
416
+ panda_require (" hypercaller" );
417
+ void * hypercaller = panda_get_plugin_by_name (" hypercaller" );
418
+ register_hypercall_t register_hypercall = (register_hypercall_t ) dlsym (hypercaller, " register_hypercall" );
419
+ register_hypercall (LAVA_MAGIC, lava_hypercall);
420
+
421
+ printf (" [pri_taint] This plugin is activated!\n " );
438
422
return true ;
439
423
#else
440
- printf (" [pri_taint] This plugin is only supported on x86\n " );
424
+ printf (" [pri_taint] This plugin is only supported on x86 or ARM \n " );
441
425
return false ;
442
- // taint2_track_taint_state();
443
426
#endif
444
427
}
445
428
446
-
447
-
448
429
void uninit_plugin (void *self) {
430
+ // You don't need to unregister the hypercall!
431
+ printf (" [pri_taint] Unloading plugin complete!\n " );
449
432
}
450
-
0 commit comments