Skip to content

Commit c429ded

Browse files
committed
Update pri_taint hypercall for LAVA - Just dwarf2 fix now
1 parent fc26385 commit c429ded

File tree

7 files changed

+182
-245
lines changed

7 files changed

+182
-245
lines changed

panda/plugins/dwarf2/dwarf2.cpp

Lines changed: 90 additions & 139 deletions
Large diffs are not rendered by default.

panda/plugins/hypercaller/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ This was designed primarily for Python use cases:
5151
MAGIC = 0x12345678
5252
@panda.hypercall(MAGIC)
5353
def hypercall(cpu):
54-
print("Hello from my hypercall!"
54+
print("Hello from my hypercall!")
5555

5656
```
5757

@@ -64,7 +64,7 @@ It's much easier to handle this from Python, but here's an example of how you mi
6464
#include <panda/plugin.h>
6565
#include <hypercaller/hypercaller.h>
6666

67-
hypercall_t* register_hypercall;
67+
register_hypercall_t register_hypercall;
6868

6969
void my_hypercall(CPUState *cpu) {
7070
printf("Hello from my hypercall!\n");
@@ -76,7 +76,7 @@ bool init_plugin(void *self) {
7676
panda_require("hypercaller");
7777
hypercaller = panda_get_plugin_by_name("hypercaller");
7878
}
79-
register_hypercall = (hypercall_t*)dlsym(hypercaller, "register_hypercall");
79+
register_hypercall_t register_hypercall = (register_hypercall_t) dlsym(hypercaller, "register_hypercall");
8080
register_hypercall(0x12345678, my_hypercall);
8181
return true;
8282
}

panda/plugins/hypercaller/hypercaller.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// files in this directory that contain subsections like this one.
77

88
typedef void (*hypercall_t)(CPUState *cpu);
9+
typedef void (*register_hypercall_t)(uint32_t, hypercall_t);
910
void register_hypercall(uint32_t magic, hypercall_t);
1011
void unregister_hypercall(uint32_t magic);
1112

panda/plugins/pri_dwarf/pri_dwarf.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,12 +1806,9 @@ void on_library_load(CPUState *cpu, target_ulong pc, char *guest_lib_name, targe
18061806
int mod_check_count = 0;
18071807
bool main_exec_initialized = false;
18081808
#define MOD_CHECK_FREQ 1000
1809-
bool ensure_main_exec_initialized(CPUState *cpu) {
1810-
//if (!correct_asid(cpu)) return;
1811-
OsiProc *p = get_current_process(cpu);
1809+
bool ensure_main_exec_initialized(CPUState *cpu, OsiProc *p) {
18121810
GArray *libs = NULL;
18131811
libs = get_mappings(cpu, p);
1814-
free_osiproc(p);
18151812
if (!libs)
18161813
return false;
18171814

@@ -2314,8 +2311,8 @@ void handle_asid_change(CPUState *cpu, target_ulong asid, OsiProc *p) {
23142311
monitored_asid.insert(current_asid);
23152312
printf ("monitoring asid %x\n", current_asid);
23162313
}
2317-
if (correct_asid(cpu) && !main_exec_initialized){
2318-
main_exec_initialized = ensure_main_exec_initialized(cpu);
2314+
if (correct_asid(cpu) && !main_exec_initialized) {
2315+
main_exec_initialized = ensure_main_exec_initialized(cpu, p);
23192316
}
23202317
//free_osiproc(p);
23212318

panda/plugins/pri_taint/pri_taint.cpp

Lines changed: 77 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "callstack_instr/callstack_instr.h"
1616

1717
extern "C" {
18+
#include <hypercaller/hypercaller.h>
1819

1920
#include "panda/rr/rr_log.h"
2021
#include "panda/plog.h"
@@ -37,14 +38,14 @@ extern "C" {
3738
bool init_plugin(void *);
3839
void uninit_plugin(void *);
3940

40-
int get_loglevel() ;
41+
int get_loglevel();
4142
void set_loglevel(int new_loglevel);
4243
}
4344

4445
const char *global_src_filename = NULL;
4546
uint64_t global_src_linenum;
4647
unsigned global_ast_loc_id;
47-
uint64_t global_funcaddr;
48+
// uint64_t global_funcaddr;
4849
bool debug = false;
4950

5051
#define dprintf(...) if (debug) { printf(__VA_ARGS__); fflush(stdout); }
@@ -97,11 +98,18 @@ void print_membytes(CPUState *env, target_ulong a, target_ulong len) {
9798
printf("}");
9899
}
99100

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+
100109
// max length of strnlen or taint query
101110
#define LAVA_TAINT_QUERY_MAX_LEN (target_ulong)64ULL
102-
#if defined(TARGET_I386)
111+
#if defined(TARGET_I386) || defined(TARGET_ARM)
103112
void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, const char *astnodename) {
104-
105113
dprintf("[pri_taint] Attempt to lava_taint_query\n");
106114

107115
// 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
115123
dprintf("[pri_taint] The Location is either error OR constant. Shouldn't happen based on pfun()\n");
116124
return;
117125
}
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");
120128
return;
121129
}
130+
if (taint2_num_labels_applied() == 0) {
131+
// see taint_api.cpp
132+
dprintf("[pri_taint] No taint2 num labeled applied\n");
133+
}
122134
dprintf("[pri_taint] OK, Seems like I can Lava Taint! LFG!\n");
123135

124136
CPUState *cpu = first_cpu;
125-
CPUArchState *env = (CPUArchState *)cpu->env_ptr;
137+
CPUArchState *env = (CPUArchState *) cpu -> env_ptr;
126138
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;
129141

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");
132144
return;
133145
}
134146

@@ -163,7 +175,7 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con
163175
// is there *any* taint on this extent
164176
uint32_t num_tainted = 0;
165177
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);
167179
if (taint2_query(a)) {
168180
num_tainted++;
169181
}
@@ -185,7 +197,7 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con
185197
// this is just a snippet. we dont want to write 1M buffer
186198
if (loc_t == LocMem) {
187199
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);
189201
}
190202
} else {
191203
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
199211
// 2. iterate over the bytes in the extent and pandalog detailed info about taint
200212
std::vector<Panda__TaintQuery *> tq;
201213
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);
204216
if (taint2_query(a)) {
205217
if (loc_t == LocMem) {
206218
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
231243
pandalog_taint_query_free(ptq);
232244
}
233245
}
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-
};
242246

243-
#if defined(TARGET_I386)
244247
void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc, void *in_args) {
245248
if (!taint2_enabled()) {
246249
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
255258
return;
256259
}
257260
}
261+
258262
const char *var_ty = dwarf2_type_to_string((DwarfVarType *) var_ty_void);
263+
259264
// restore args
260265
struct args *args = (struct args *) in_args;
261266
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
264269
global_src_filename = args->src_filename;
265270
global_src_linenum = args->src_linenum;
266271
global_ast_loc_id = args->ast_loc_id;
267-
global_funcaddr = args->funcaddr;
272+
// global_funcaddr = args->funcaddr;
268273
//target_ulong guest_dword;
269274
//std::string ty_string = std::string(var_ty);
270275
//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
289294
default:
290295
assert(1==0);
291296
}
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);
307297
}
308298

299+
/*
309300
// Trace logging in the level of source code
310301
void hypercall_log_trace(unsigned ast_loc_id) {
311302
Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
@@ -315,37 +306,54 @@ void hypercall_log_trace(unsigned ast_loc_id) {
315306
pandalog_write_entry(&ple);
316307
}
317308
*/
318-
#ifdef TARGET_I386
309+
319310
// Support all features of label and query program
320-
void i386_hypercall_callback(CPUState *cpu) {
311+
void lava_hypercall(CPUState *cpu) {
321312
dprintf("[pri_taint] Calling lava hypercall!\n");
322-
323313
CPUArchState *env = (CPUArchState*) cpu->env_ptr;
324314
if (taint2_enabled()) {
325315
// 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)
329321
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]);
330324
#endif
331-
325+
332326
if ((int) addr == -1) {
333-
#ifdef TARGET_X86_64
327+
#if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
334328
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)
337334
dprintf("[pri_taint] panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%x paddr=0x%x\n",
338335
(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);
339339
#endif
340340
}
341341
else if (pandalog) {
342342
dprintf("[pri_taint] Hypercall is OK and Panda Log is set\n");
343343
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
345353

346354
// 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));
349357
// if the phs action is a pri_query point, see
350358
// lava/include/pirate_mark_lava.h
351359
if (phs.action == 13) {
@@ -359,7 +367,8 @@ void i386_hypercall_callback(CPUState *cpu) {
359367
dprintf("[pri_taint] panda hypercall: [%s], "
360368
"ln: %4ld, pc @ 0x" TARGET_FMT_lx "\n",
361369
info.filename,
362-
info.line_number,pc);
370+
info.line_number, pc);
371+
363372
// Calls 'pri_funct_livevar_iter' in pri.c, which calls 'on_funct_livevar_iter'
364373
// In Dwarf2, the function 'on_funct_livevar_iter' is mapped to 'dwarf_funct_livevar_iter'
365374
// 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) {
368377
else {
369378
dprintf("[pri_taint] pri_get_pc_src_info has failed: %d != 0.\n", rc);
370379
}
380+
// hypercall_log_trace(phs.src_filename);
371381
}
372382
else {
373383
dprintf("[pri_taint] Invalid action value in PHS struct: %d != 13.\n", phs.action);
@@ -380,71 +390,43 @@ void i386_hypercall_callback(CPUState *cpu) {
380390
else {
381391
dprintf("[pri_taint] taint2 is not enabled (hypercall)\n");
382392
}
383-
return ret;
384393
}
385-
#endif // TARGET_I386
386-
387-
388-
bool guest_hypercall_callback(CPUState *cpu) {
389-
#ifdef TARGET_I386
390-
return i386_hypercall_callback(cpu);
391394
#endif
392395

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-
*/
413396
bool init_plugin(void *self) {
414-
415-
#if defined(TARGET_I386)
397+
#if defined(TARGET_I386) || defined(TARGET_ARM)
416398
panda_arg_list *args = panda_get_args("pri_taint");
417399
debug = panda_parse_bool_opt(args, "debug", "enable debug output");
418400

419401
panda_require("callstack_instr");
420402
assert(init_callstack_instr_api());
421403
panda_require("pri");
422404
assert(init_pri_api());
423-
panda_require("dwarf2");
424-
assert(init_dwarf2_api());
425405
panda_require("taint2");
426406
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());
432409

433410
// If taint isn't already enabled, turn it on.
434411
if (!taint2_enabled()) {
435412
printf("[pri_taint] enabling taint now!\n");
436413
taint2_enable_taint();
437414
}
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");
438422
return true;
439423
#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");
441425
return false;
442-
//taint2_track_taint_state();
443426
#endif
444427
}
445428

446-
447-
448429
void uninit_plugin(void *self) {
430+
// You don't need to unregister the hypercall!
431+
printf("[pri_taint] Unloading plugin complete!\n");
449432
}
450-

0 commit comments

Comments
 (0)