From b9e901d62a1ec5cb27680f55c58562fd947923b6 Mon Sep 17 00:00:00 2001 From: AndrewQuijano Date: Sat, 14 Dec 2024 16:02:32 -0500 Subject: [PATCH] Updating loaded for 64-bit systems --- panda/plugins/loaded/loaded.cpp | 134 ++++++++++++++++++---- panda/plugins/loaded_libs/loaded_libs.cpp | 65 +++++------ 2 files changed, 138 insertions(+), 61 deletions(-) diff --git a/panda/plugins/loaded/loaded.cpp b/panda/plugins/loaded/loaded.cpp index f3303c5fb73..12b416dcb39 100644 --- a/panda/plugins/loaded/loaded.cpp +++ b/panda/plugins/loaded/loaded.cpp @@ -18,6 +18,7 @@ PANDAENDCOMMENT */ #include #include #include +#include #include "panda/plugin.h" #include "panda/plugin_plugin.h" @@ -52,14 +53,13 @@ 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 MAX_FILENAME 256 std::map running_procs; void die(const char* fmt, ...) { va_list args; - va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); @@ -94,32 +94,35 @@ void linux_old_mmap_return(CPUState *cpu, target_ulong pc, uint32_t arg_ptr) { } } -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) { +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); + // 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); + 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); + // 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 " @@ -127,6 +130,63 @@ void linux_mmap_pgoff_return(CPUState *cpu,target_ulong pc,uint32_t addr,uint32_ len, prot, flags, pgoff, env->regs[R_EAX]); } } + +#elif defined(TARGET_I386) && defined(TARGET_X86_64) +void linux_mprotect_return(CPUState* cpu, target_ulong pc, + uint64_t start, uint32_t len, + uint64_t prot) { + if (debug) { + printf("[loaded] mprotect() on x86-64\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) { + + if (debug) { + printf("[loaded] linux_mmap_return 64-bit is called\n"); + } + 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; + } + if (debug) { + printf("[loaded] linux_mmap_return 64-bit 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(cpu, &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]); + } + else { + if (debug) { + if (filename == NULL) { + printf("[loaded] I got a null file name\n"); + } + else { + printf("[loaded] It seems like filename %s was null, OR PROT_EXEC was not there\n", filename); + } + } + } +} #endif // get current process before each bb execs @@ -137,42 +197,54 @@ void osi_foo(CPUState *cpu, TranslationBlock *tb) { std::unique_ptr 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; iname[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"); +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) { @@ -183,10 +255,22 @@ 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("[loaded] The 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("[loaded] The plugin is supported on x86-64\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; diff --git a/panda/plugins/loaded_libs/loaded_libs.cpp b/panda/plugins/loaded_libs/loaded_libs.cpp index b322e35a557..0e2084d5b45 100644 --- a/panda/plugins/loaded_libs/loaded_libs.cpp +++ b/panda/plugins/loaded_libs/loaded_libs.cpp @@ -1,7 +1,6 @@ #define __STDC_FORMAT_MACROS #include - #include "panda/plugin.h" #include "syscalls2/syscalls_ext_typedefs.h" @@ -9,15 +8,13 @@ #include "syscalls2/syscalls2_ext.h" extern "C" { - - bool init_plugin(void *); - void uninit_plugin(void *); +bool init_plugin(void *); +void uninit_plugin(void *); #include "osi/osi_types.h" #include "osi/osi_ext.h" } - #include #include #include @@ -40,24 +37,31 @@ uint64_t get_libs_failed_count = 0; void get_libs(CPUState *env) { get_libs_count ++; - bool fail = false; OsiProc *current = get_current_process(env); - if (current == NULL) fail=true; - if (program_name && strcmp(current->name, program_name)) fail=true; - if (current->pid == 0) fail=true; + if (current == NULL) { + fail = true; + } + if (program_name && strcmp(current->name, program_name)) { + fail = true; + } + if (current->pid == 0) { + fail = true; + } GArray *ms = get_mappings(env, current); - if (ms == NULL) fail=true; + if (ms == NULL) { + fail = true; + } OsiThread *thread = get_current_thread(env); - if (thread == NULL) fail=true; - + if (thread == NULL) { + fail = true; + } assert (pandalog); if (fail) { get_libs_failed_count ++; } else { - Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; Panda__LoadedLibs ll = PANDA__LOADED_LIBS__INIT; Panda__Module** m = (Panda__Module **) malloc (sizeof (Panda__Module *) * ms->len); @@ -90,7 +94,6 @@ void get_libs(CPUState *env) { ll.tid = thread->tid; Asid asid = panda_current_asid(env); - ple.has_asid = true; ple.asid = asid; ple.asid_libraries = ≪ @@ -106,54 +109,44 @@ void get_libs(CPUState *env) { cleanup_osi(current, thread, ms); } - - // 9 long sys_mmap( - void mmap_return(CPUState *cpu, target_ulong pc, unsigned long addr, unsigned long length, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long offset) { get_libs(cpu); } - uint64_t bb_count = 0; - void before_block(CPUState *env, TranslationBlock *tb) { - // check up on module list every 50 bb bb_count ++; if ((bb_count % 100) == 0) { get_libs(env); } - } - bool init_plugin(void *self) { panda_require("osi"); assert(init_osi_api()); panda_require("syscalls2"); #ifdef TARGET_X86_64 - PPP_REG_CB("syscalls2", on_sys_mmap_return, mmap_return); + PPP_REG_CB("syscalls2", on_sys_mmap_return, mmap_return); + panda_cb pcb; + pcb.before_block_exec = before_block; + panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); + + panda_arg_list *args; + args = panda_get_args("loaded_libs"); + program_name = panda_parse_string_opt(args, "program_name", NULL, "program name to collect libraries for"); + return true; #else - /* #error "No on_sys_mmap_return for target" */ + /* #error "No on_sys_mmap_return for target" */ + printf("loaded_libs plugin is not available for this architecture"); + return false; #endif - - panda_cb pcb; - pcb.before_block_exec = before_block; - panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); - - panda_arg_list *args; - args = panda_get_args("loaded_libs"); - program_name = panda_parse_string_opt(args, "program_name", NULL, "program name to collect libraries for"); - - return true; } void uninit_plugin(void *self) { - cout << "get_libs_count = " << get_libs_count << "\n"; cout << "get_libs_failed_count = " << get_libs_failed_count << "\n"; cout << "frac = " << ((float) get_libs_failed_count) / get_libs_count << "\n"; - }