-
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
Open
AndrewQuijano
wants to merge
3
commits into
dev
Choose a base branch
from
lava
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
panda.deb | ||
*.deb | ||
*.whl |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ PANDAENDCOMMENT */ | |
#include <cstdio> | ||
#include <map> | ||
#include <memory> | ||
#include <sys/mman.h> | ||
|
||
#include "panda/plugin.h" | ||
#include "panda/plugin_plugin.h" | ||
|
@@ -52,14 +53,14 @@ PPP_PROT_REG_CB(on_library_load); | |
// This creates the global for this call back fn (on_library_load) | ||
PPP_CB_BOILERPLATE(on_library_load) | ||
|
||
bool debug = true; | ||
bool debug = false; | ||
#define dprintf(...) if (debug) { printf(__VA_ARGS__); fflush(stdout); } | ||
|
||
#define MAX_FILENAME 256 | ||
std::map <target_ulong, OsiProc> running_procs; | ||
|
||
void die(const char* fmt, ...) { | ||
va_list args; | ||
|
||
va_start(args, fmt); | ||
vfprintf(stderr, fmt, args); | ||
va_end(args); | ||
|
@@ -80,116 +81,167 @@ uint32_t guest_strncpy(CPUState *cpu, char *buf, size_t maxlen, target_ulong gue | |
return i; | ||
} | ||
|
||
#if defined(TARGET_I386) && !defined(TARGET_X86_64) | ||
// 125 long sys_mprotect ['unsigned long start', ' size_t len', 'unsigned long prot'] | ||
void linux_mprotect_return(CPUState* cpu,target_ulong pc,uint32_t start,uint32_t len,uint32_t prot) { | ||
if (debug) { | ||
printf("[loaded] mprotect()\n"); | ||
} | ||
} | ||
// 90 long sys_old_mmap ['struct mmap_arg_struct __user *arg'] | ||
void linux_old_mmap_return(CPUState *cpu, target_ulong pc, uint32_t arg_ptr) { | ||
if (debug) { | ||
printf("[loaded] old mmap()\n"); | ||
} | ||
} | ||
|
||
void linux_mmap_pgoff_return(CPUState *cpu,target_ulong pc,uint32_t addr,uint32_t len,uint32_t prot,uint32_t flags,uint32_t fd,uint32_t pgoff) { | ||
CPUArchState *env = (CPUArchState*)cpu->env_ptr; | ||
target_ulong asid = panda_current_asid(cpu); | ||
if (running_procs.count(asid) == 0) { | ||
//printf ("linux_mmap_pgoff_enter for asid=0x%x fd=%d -- dont know about that asid. discarding \n", (unsigned int) asid, (int) fd); | ||
return; | ||
} | ||
if ((int32_t) fd == -1){ | ||
//printf ("linux_mmap_pgoff_enter for asid=0x%x fd=%d flags=%x -- not valid fd . . . \n", (unsigned int) asid, (int) fd, flags); | ||
return; | ||
} | ||
OsiProc proc = running_procs[asid]; | ||
char *filename = osi_linux_fd_to_filename(cpu, &proc, fd); | ||
// gets us offset into the file. could be useful | ||
//uint64_t pos = osi_linux_fd_to_pos(env, &proc, fd); | ||
// if a filename exists and permission is executable | ||
// TODO: fix this magic constant of 0x04 for PROT_EXEC | ||
if (filename != NULL && ((prot & 0x04) == 0x04)) { | ||
if (debug) { | ||
printf ("[loaded] linux_mmap_pgoff(fd=%d filename=[%s] " | ||
"len=%d prot=%x flags=%x " | ||
"pgoff=%d)=" TARGET_FMT_lx "\n", (int) fd, | ||
filename, len, prot, flags, pgoff, env->regs[R_EAX]); | ||
} | ||
PPP_RUN_CB(on_library_load, cpu, pc, filename, env->regs[R_EAX], len) | ||
} else if ((prot & 0x04) == 0x04) { | ||
printf("[loaded] mapped executable section without a filename!\n"); | ||
printf ("[loaded] linux_mmap_pgoff(fd=%d " | ||
"len=%d prot=%x flags=%x " | ||
"pgoff=%d)=" TARGET_FMT_lx "\n", (int) fd, | ||
len, prot, flags, pgoff, env->regs[R_EAX]); | ||
} | ||
} | ||
#endif | ||
|
||
// get current process before each bb execs | ||
// which will probably help us actually know the current process | ||
void osi_foo(CPUState *cpu, TranslationBlock *tb) { | ||
|
||
if (panda_in_kernel(cpu)) { | ||
|
||
std::unique_ptr<OsiProc, decltype(free_osiproc)*> p { get_current_process(cpu), free_osiproc }; | ||
|
||
//some sanity checks on what we think the current process is | ||
// some sanity checks on what we think the current process is | ||
// we couldn't find the current task | ||
if (!p) return; | ||
if (!p) { | ||
return; | ||
} | ||
// this means we didnt find current task | ||
if (p->taskd == 0) return; | ||
if (p->taskd == 0) { | ||
return; | ||
} | ||
// or the name | ||
if (p->name == 0) return; | ||
if (p->name == 0) { | ||
return; | ||
} | ||
// this is just not ok | ||
if (((int) p->pid) == -1) return; | ||
if (((int) p->pid) == -1) { | ||
return; | ||
} | ||
uint32_t n = strnlen(p->name, 32); | ||
// name is one char? | ||
if (n<2) return; | ||
if (n < 2) { | ||
return; | ||
} | ||
uint32_t np = 0; | ||
for (uint32_t i=0; i<n; i++) { | ||
np += (isprint(p->name[i]) != 0); | ||
} | ||
// name doesnt consist of solely printable characters | ||
// printf ("np=%d n=%d\n", np, n); | ||
if (np != n) return; | ||
if (np != n) { | ||
return; | ||
} | ||
target_ulong asid = panda_current_asid(cpu); | ||
if (running_procs.count(asid) == 0) { | ||
printf ("adding asid=0x%x to running procs. cmd=[%s] task=0x%x\n", (unsigned int) asid, p->name, (unsigned int) p->taskd); | ||
printf("[loaded] adding asid=0x%x to running procs. cmd=[%s] task=0x%x\n", (unsigned int) asid, p->name, (unsigned int) p->taskd); | ||
} | ||
running_procs[asid] = *p; | ||
} | ||
|
||
return; | ||
} | ||
bool init_plugin(void *self) { | ||
//panda_arg_list *args = panda_get_args("loaded"); | ||
|
||
#if defined(TARGET_I386) || defined(TARGET_ARM) | ||
#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 | ||
Comment on lines
+131
to
+138
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
{ | ||
dprintf("[loaded] linux_mmap_return is called!\n"); | ||
CPUArchState *env = (CPUArchState*)cpu->env_ptr; | ||
target_ulong asid = panda_current_asid(cpu); | ||
if (running_procs.count(asid) == 0) { | ||
return; | ||
} | ||
if (fd == -1) { | ||
return; | ||
} | ||
dprintf("[loaded] linux_mmap_return is called, with OK fd and non-zero running proc\n"); | ||
OsiProc proc = running_procs[asid]; | ||
char *filename = osi_linux_fd_to_filename(cpu, &proc, fd); | ||
// gets us offset into the file. could be useful | ||
// uint64_t pos = osi_linux_fd_to_pos(env, &proc, fd); | ||
// if a filename exists and permission is executable | ||
#if defined(TARGET_I386) && !defined(TARGET_X86_64) | ||
dprintf("[loaded] linux_mmap_pgoff(fd=%d filename=[%s] " | ||
"len=%d prot=%x flags=%x " | ||
"pgoffset=%d)=" TARGET_FMT_lx "\n", (int) fd, | ||
filename, len, prot, flags, offset, env->regs[R_EAX]); | ||
#elif defined(TARGET_ARM) && !defined(TARGET_AARCH64) | ||
dprintf("[loaded] linux_mmap_pgoff(fd=%d filename=[%s] " | ||
"len=%u prot=%u flags=%u " | ||
"pgoffset=%d)=" TARGET_FMT_lx "\n", (int) fd, | ||
filename, len, prot, flags, offset, env->regs[0]); | ||
#elif defined(TARGET_X86_64) | ||
dprintf("[loaded] linux_mmap_pgoff(fd=%lu filename=[%s] " | ||
"len=%lu prot=%lu flags=%lu " | ||
"pgoff=%lu)=" TARGET_FMT_lx "\n", (unsigned long) fd, | ||
filename, (unsigned long) len, (unsigned long) prot, (unsigned long) flags, (unsigned long) offset, env->regs[R_EAX]); | ||
#elif defined(TARGET_AARCH64) | ||
printf("[loaded] linux_mmap(fd=%d filename=[%s] " | ||
"len=%u prot=%x flags=%x " | ||
"pgoff=%lu)=" TARGET_FMT_lx "\n", fd, | ||
filename, len, prot, flags, offset, env->xregs[0]); | ||
#endif | ||
|
||
if (filename != NULL && ((prot & PROT_EXEC) == PROT_EXEC)) { | ||
// See 'dwarf2.cpp' for the definition of 'on_library_load' | ||
dprintf("[loaded] Calling on_library_load\n"); | ||
#if defined(TARGET_I386) | ||
PPP_RUN_CB(on_library_load, cpu, pc, filename, env->regs[R_EAX], len); | ||
#elif defined(TARGET_AARCH64) | ||
PPP_RUN_CB(on_library_load, cpu, pc, filename, env->xregs[0], len); | ||
#elif defined(TARGET_ARM) && !defined(TARGET_AARCH64) | ||
PPP_RUN_CB(on_library_load, cpu, pc, filename, env->regs[0], len); | ||
#endif | ||
} | ||
else if ((prot & PROT_EXEC) == PROT_EXEC) { | ||
printf("[loaded] mapped executable section without a filename!\n"); | ||
} | ||
else { | ||
if (filename == NULL) { | ||
dprintf("[loaded] I got a null file name\n"); | ||
} | ||
else { | ||
dprintf("[loaded] It seems like filename %s was null, OR PROT_EXEC was not there\n", filename); | ||
} | ||
} | ||
} | ||
#endif | ||
|
||
bool init_plugin(void *self) { | ||
panda_require("osi"); | ||
assert(init_osi_api()); | ||
panda_require("osi_linux"); | ||
assert(init_osi_linux_api()); | ||
panda_require("syscalls2"); | ||
panda_arg_list *args = panda_get_args("loaded"); | ||
debug = panda_parse_bool_opt(args, "debug", "enable debug output"); | ||
|
||
#if defined(TARGET_I386) && !defined(TARGET_X86_64) | ||
{ | ||
panda_cb pcb; | ||
pcb.before_block_exec = osi_foo; | ||
panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); | ||
} | ||
PPP_REG_CB("syscalls2", on_sys_mmap_pgoff_return, linux_mmap_return); | ||
printf("[loaded] The plugin is supported on i386\n"); | ||
#elif defined(TARGET_ARM) && !defined(TARGET_AARCH64) | ||
{ | ||
panda_cb pcb; | ||
pcb.before_block_exec = osi_foo; | ||
panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); | ||
} | ||
|
||
PPP_REG_CB("syscalls2", on_sys_mmap_pgoff_return, linux_mmap_pgoff_return); | ||
// don't use these at them moment | ||
//PPP_REG_CB("syscalls2", on_sys_old_mmap_return, linux_old_mmap_return); | ||
//PPP_REG_CB("syscalls2", on_sys_mprotect_return, linux_mprotect_return); | ||
PPP_REG_CB("syscalls2", on_do_mmap2_return, linux_mmap_return); | ||
printf("[loaded] The plugin is supported on ARM 32-bits\n"); | ||
#elif defined(TARGET_X86_64) || defined(TARGET_AARCH64) | ||
{ | ||
panda_cb pcb; | ||
pcb.before_block_exec = osi_foo; | ||
panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); | ||
} | ||
// Tell Plugin 'syscall2', that if a systemcall 'mmap' occurs, then run the code in 'linux_mmap_return' | ||
// https://www.linuxquestions.org/questions/linux-general-1/difference-between-mmap2-syscall-and-mmap_pgoff-syscall-for-32-bit-linux-4175622986/ | ||
PPP_REG_CB("syscalls2", on_sys_mmap_return, linux_mmap_return); | ||
printf("[loaded] The plugin is supported on x86-64 and ARM 64-bits\n"); | ||
#else | ||
fprintf(stderr, "The loaded plugin is not currently supported on this platform.\n"); | ||
fprintf(stderr, "[loaded] The plugin is not currently supported on this platform.\n"); | ||
return false; | ||
#endif | ||
return true; | ||
} | ||
|
||
void uninit_plugin(void *self) { } | ||
void uninit_plugin(void *self) { | ||
printf("[loaded] uninit_plugin\n"); | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.