Skip to content

Commit

Permalink
loaded is now supported for x86-64
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewQuijano committed Nov 17, 2024
1 parent 85555d5 commit a3295d4
Showing 1 changed file with 63 additions and 9 deletions.
72 changes: 63 additions & 9 deletions panda/plugins/loaded/loaded.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ PANDAENDCOMMENT */
#include <cstdio>
#include <map>
#include <memory>
#include <sys/mman.h>

#include "panda/plugin.h"
#include "panda/plugin_plugin.h"
Expand Down Expand Up @@ -80,7 +81,7 @@ uint32_t guest_strncpy(CPUState *cpu, char *buf, size_t maxlen, target_ulong gue
return i;
}

#if defined(TARGET_I386) && !defined(TARGET_X86_64)
#if defined(TARGET_I386)
// 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) {
Expand Down Expand Up @@ -108,25 +109,66 @@ void linux_mmap_pgoff_return(CPUState *cpu,target_ulong pc,uint32_t addr,uint32_
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);
// 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 (filename != NULL && ((prot & PROT_EXEC) == PROT_EXEC)) {
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) {
PPP_RUN_CB(on_library_load, cpu, pc, filename, env->regs[R_EAX], len);
} else if ((prot & PROT_EXEC) == PROT_EXEC) {
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]);
}
}
// https://man7.org/linux/man-pages/man2/mmap.2.html
// https://github.com/panda-re/panda/blob/dev/panda/plugins/syscalls2/generated/syscalls_ext_typedefs_x64.h#L7405-L7412
#elif defined(TARGET_X86_64)

void linux_mprotect_return(CPUState* cpu, target_ulong pc,
uint64_t start, uint32_t len,
uint64_t prot, int32_t pkey) {
if (debug) {
printf("[loaded] mprotect()\n");
}
}

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) {

CPUArchState *env = (CPUArchState*)cpu->env_ptr;
target_ulong asid = panda_current_asid(cpu);
if (running_procs.count(asid) == 0) {
return;
}
if ((int32_t) fd == -1) {
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
if (filename != NULL && ((prot & PROT_EXEC) == PROT_EXEC)) {
if (debug) {
printf("[loaded] linux_mmap(fd=%lu filename=[%s] len=%lu prot=%lx flags=%lx pgoff=%lu)=%lx\n",
fd, filename, len, prot, flags, offset, (unsigned long) env->regs[R_EAX]);
}
PPP_RUN_CB(on_library_load, cpu, pc, filename, env->regs[R_EAX], len);
}
else if ((prot & PROT_EXEC) == PROT_EXEC) {
printf("[loaded] mapped executable section without a filename!\n");
printf("[loaded] linux_mmap(fd=%lu len=%lu prot=%lx flags=%lx pgoff=%lu)=%lx\n",
fd, len, prot, flags, offset, (unsigned long) env->regs[R_EAX]);
}
}
#endif

// get current process before each bb execs
Expand Down Expand Up @@ -166,7 +208,7 @@ void osi_foo(CPUState *cpu, TranslationBlock *tb) {
return;
}
bool init_plugin(void *self) {
//panda_arg_list *args = panda_get_args("loaded");
// panda_arg_list *args = panda_get_args("loaded");

panda_require("osi");
assert(init_osi_api());
Expand All @@ -183,8 +225,20 @@ bool init_plugin(void *self) {

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_sys_old_mmap_return, linux_old_mmap_return);
// PPP_REG_CB("syscalls2", on_sys_mprotect_return, linux_mprotect_return);
printf("The loaded plugin is supported on i386\n");
#elif 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);
}
// 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);
PPP_REG_CB("syscalls2", on_sys_mprotect_return, linux_mprotect_return);
printf("The loaded plugin is supported on x86-64\n");
#else
fprintf(stderr, "The loaded plugin is not currently supported on this platform.\n");
return false;
Expand Down

0 comments on commit a3295d4

Please sign in to comment.