-
Notifications
You must be signed in to change notification settings - Fork 494
Panda supports 64-bit LAVA #1574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
1c240fc
to
bbbed20
Compare
3bb1e81
to
ead3e01
Compare
c429ded
to
dffad1f
Compare
0ca00bb
to
132b41e
Compare
3157e34
to
4aa000e
Compare
fbfb92f
to
4116b14
Compare
06be0fe
to
006126b
Compare
#define CPU_NB_REGS 16 | ||
#define REGS(env) ((env)->regs) | ||
#elif defined(TARGET_ARM) && defined(TARGET_AARCH64) | ||
#define NUM_REGS 31 | ||
#define CPU_NB_REGS 31 | ||
#define REGS(env) ((env)->xregs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed this change so I can compile pri_taint with ARM. I want to have this so that maybe someday we can plant LAVA bugs into ARM architecture too
#if defined(TARGET_I386) && !defined(TARGET_X86_64) || defined(TARGET_ARM) && !defined(TARGET_AARCH64) | ||
// technically for 32-bit it is pgoff, not offset! But I want to avoid code duplication! | ||
void linux_mmap_return(CPUState *cpu, target_ulong pc, uint32_t addr, uint32_t len, uint32_t prot, uint32_t flags, uint32_t fd, uint32_t offset) | ||
#elif defined(TARGET_X86_64) | ||
void linux_mmap_return(CPUState *cpu, target_ulong pc, uint64_t addr, uint64_t len, uint64_t prot, uint64_t flags, uint64_t fd, uint64_t offset) | ||
#elif defined(TARGET_AARCH64) | ||
void linux_mmap_return(CPUState* cpu, target_ulong pc, uint64_t addr, uint32_t len, int32_t prot, int32_t flags, int32_t fd, uint64_t offset) | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the real change, I updated the function to work both i386, x86_64 and ARM. ARM might be needed for future LAVA work
@@ -64,7 +64,7 @@ It's much easier to handle this from Python, but here's an example of how you mi | |||
#include <panda/plugin.h> | |||
#include <hypercaller/hypercaller.h> | |||
|
|||
hypercall_t* register_hypercall; | |||
register_hypercall_t register_hypercall; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worked with @jamcleod, so it was decided to add this to the header, from there, I was able to to use hypercaller.h correctly in pri_taint.
The documentation also matches the new code in pri_taint.
uint64_t num_tainted = 0; | ||
for (uint64_t offset = 0; offset < len; offset++) { | ||
hwaddr pa = panda_virt_to_phys(cpu, buf + offset); | ||
if ((int) pa != (hwaddr)-1) { | ||
ram_addr_t RamOffset = RAM_ADDR_INVALID; | ||
if (PandaPhysicalAddressToRamOffset(&RamOffset, pa, false) != MEMTX_OK) { | ||
dprintf("[pri_taint] can't query va=0x%" PRIx64 " pa=0x" TARGET_FMT_plx ": physical map is not RAM.\n", buf + offset, pa); | ||
continue; | ||
} | ||
else { | ||
Addr a; | ||
if (loc_t == LocMem) { | ||
a = make_maddr(RamOffset); | ||
} | ||
else { | ||
a = make_greg(buf, offset); | ||
} | ||
if (taint2_query(a)) { | ||
num_tainted++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code was mostly taken from taint2_hypercalls.cpp, also, it aligned well with what I saw in file_taint.
// Taken from taint2_hypercalls.cpp, not sure why but at the moment | ||
// AttackPoints is never populated. | ||
Panda__SrcInfo *pandalog_src_info_create(PandaHypercallStruct phs) { | ||
Panda__SrcInfo *si = (Panda__SrcInfo *) malloc(sizeof(Panda__SrcInfo)); | ||
*si = PANDA__SRC_INFO__INIT; | ||
si->filename = phs.src_filename; | ||
si->astnodename = phs.src_ast_node_name; | ||
si->linenum = phs.src_linenum; | ||
si->has_insertionpoint = 0; | ||
if (phs.insertion_point) { | ||
si->has_insertionpoint = 1; | ||
si->insertionpoint = phs.insertion_point; | ||
} | ||
si->has_ast_loc_id = 1; | ||
si->ast_loc_id = phs.src_filename; | ||
return si; | ||
} | ||
void on_fn_start(CPUState *cpu, target_ulong pc, const char *file_Name, const char *funct_name, unsigned long long lno){ | ||
struct args args = {cpu, file_Name, lno, 0}; | ||
dprintf("fn-start: %s() [%s], ln: %4lld, pc @ 0x" TARGET_FMT_lx "\n",funct_name,file_Name,lno,pc); | ||
pri_funct_livevar_iter(cpu, pc, (liveVarCB) pfun, (void *)&args); | ||
|
||
void lava_attack_point(PandaHypercallStruct phs) { | ||
if (pandalog) { | ||
Panda__AttackPoint *ap = (Panda__AttackPoint *)malloc(sizeof(Panda__AttackPoint)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was taken from taint2_hypercalls.cpp. Based on an old LAVA pandalog, it seems like this implementation of attack point is needed
panda_require("hypercaller"); | ||
void * hypercaller = panda_get_plugin_by_name("hypercaller"); | ||
register_hypercall_t register_hypercall = (register_hypercall_t) dlsym(hypercaller, "register_hypercall"); | ||
register_hypercall(LAVA_MAGIC, lava_hypercall); | ||
|
||
printf("[pri_taint] This plugin is activated!\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worked with @jamcleod and this worked to get pri_taint to use the new hypercall system.
if (strstr(file_callee, "hypercall.h")) { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made sure that using hypercall.h also got ignored too
// First attempt to load debug symbols for main process | ||
bb_count++; | ||
if ((bb_count % 100) == 0) { | ||
if (correct_asid(cpu) && !main_exec_initialized) { | ||
main_exec_initialized = ensure_main_exec_initialized(cpu); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dwarf2's real big change, is that it didn't reliably load debug symbols. Got this code from loaded_libs, but essentially every 100 blocks attempt to load all debug symbols, yes it slows the recording, but now it works consistently.
All other changes are either formatting, comments, adding debug prints, and replacing auto with the actual type for easier code reading.
hwaddr pa = panda_virt_to_phys(cpu, buf + offset); | ||
if ((int) pa != (hwaddr) -1) { | ||
ram_addr_t RamOffset = RAM_ADDR_INVALID; | ||
if (PandaPhysicalAddressToRamOffset(&RamOffset, pa, false) != MEMTX_OK) { | ||
dprintf("[pri_taint] can't query va=0x%" PRIx64 " pa=0x%lx: physical map is not RAM.\n", (uint64_t) buf + offset, pa); | ||
continue; | ||
} | ||
else { | ||
Addr a; | ||
if (loc_t == LocMem) { | ||
a = make_maddr(RamOffset); | ||
} | ||
else { | ||
a = make_greg(buf, offset); | ||
} | ||
if (taint2_query(a)) { | ||
if (loc_t == LocMem) { | ||
dprintf("\"%s\" @ 0x" TARGET_FMT_lx " is tainted\n", astnodename, buf + offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once again, copied from file_taint and taint2_hypercalls to get RamOffsets to know where to find the tainted data
This pull request is needed for LAVA 3.0 to be ready, the main summary of the findings is the following by commit:
This PR closes loaded plugin not supported for x86-64 #1547 as I need loaded 64-bit for LAVA. Also, loaded should now work with ARM 32 and 64-bits
https://github.com/HighW4y2H3ll/panda/blob/x64dev/panda/plugins/loaded/loaded.cpp
loaded.cpp.txt
More debug and comments are added to better understand how dwarf2 and pri_taint work
Finishing touches on updating pri_taint and dwarf2