From: Kyle Hale Date: Fri, 13 Apr 2012 21:52:34 +0000 (-0500) Subject: Gears userspace utilities X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=fd1de839d257d3ed2f0a8f27d231432b166b2cc1 Gears userspace utilities --- diff --git a/linux_usr/v3_env_inject.c b/linux_usr/v3_env_inject.c new file mode 100644 index 0000000..466e8a5 --- /dev/null +++ b/linux_usr/v3_env_inject.c @@ -0,0 +1,87 @@ +/* + * V3 Environment Variable Injection Utility + * This code allows a user to inject environment variables into a process + * marked by a specific binary name in a running guest. + * + * (c) Kyle C. Hale, 2012 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "iface-env-inject.h" + + +static void usage (char* bin) { + fprintf(stderr, "Usage: %s /dev/v3-vm env-file inject-point-exe\n", bin); +} + +int main (int argc, char **argv) { + char *vm_dev, *env_file, *bin_name; + int vm_fd, err, bytes_read, num_strings; + struct stat t_stat; + struct env_data env; + char * strings[MAX_NUM_STRINGS]; + char tmp_str[MAX_STRING_LEN]; + int i = 0; + FILE * t_fd; + + if (argc < 4) { + usage(argv[0]); + return -1; + } + + vm_dev = argv[1]; + env_file = argv[2]; + bin_name = argv[3]; + + t_fd = fopen(env_file, "r"); + if (!t_fd) { + fprintf(stderr, "Error opening environment variable file: %s\n", env_file); + return -1; + } + + /* copy in the vars line by line */ + while (fgets(tmp_str, MAX_STRING_LEN, t_fd) != NULL) { + int len = strlen(tmp_str) - 1; + if (tmp_str[len] == '\n') + tmp_str[len] = 0; + strings[i] = (char*)malloc(MAX_STRING_LEN); + strcpy(strings[i], tmp_str); + i++; + } + + env.num_strings = i; + printf("Found %d environment variables to inject\n", i); + + env.strings = (char**) strings; + + if (!bin_name) { + fprintf(stderr, "Error: no binary hook provided\n"); + return -1; + } + + strncpy(env.bin_name, bin_name, MAX_STRING_LEN); + + vm_fd = open(vm_dev, O_RDONLY); + if (vm_fd == -1) { + fprintf(stderr, "Error opening VM device: %s\n", vm_dev); + return -1; + } + + printf("Transferring control to Palacios\n"); + err = ioctl(vm_fd, V3_VM_ENV_INJECT, &env); + if (err < 0) { + fprintf(stderr, "Error providing env var data to palacios\n"); + return -1; + } + + close(t_fd); + close(vm_fd); + return 0; +} diff --git a/linux_usr/v3_top_inject.c b/linux_usr/v3_top_inject.c new file mode 100644 index 0000000..2e59202 --- /dev/null +++ b/linux_usr/v3_top_inject.c @@ -0,0 +1,150 @@ +/* + * V3 Top Half Injection Utility + * This code allows a user to inject a "top half" of code into a running guest. + * The "bottom half" (a hypercall handler) is inserted using another utility. + * + * (c) Kyle C. Hale, 2011 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iface-code-inject.h" + +#define __ELF_INJECT_CLASS 32 + +#define ElfW(type) _ElfW (Elf, __ELF_INJECT_CLASS, type) +#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t) +#define _ElfW_1(e,w,t) e##w##t + + +static void usage (char* bin) { + fprintf(stderr, "Usage: %s /dev/v3-vm [inject-point-exe]\n", bin); +} + + +/* look for PT_DYNAMIC to see if it's dynamically linked */ +static int is_dynamic (ElfW(Ehdr) * ehdr) { + int i; + ElfW(Phdr) * phdr = (ElfW(Phdr)*)((char*)ehdr + ehdr->e_phoff); + ElfW(Phdr) * phdr_cursor; + + phdr_cursor = phdr; + + for (i = 0; i < ehdr->e_phnum; i++, phdr_cursor++) { + if (phdr_cursor->p_type == PT_DYNAMIC) + return 1; + } + + return 0; +} + + +int main (int argc, char **argv) { + char *vm_dev = NULL; + char *top_half = NULL; + char *bin_file = NULL; + int vm_fd, t_fd, err, bytes_read, entry; + struct stat t_stat; + struct top_half_data elf; + ElfW(Ehdr) * elf_hdr; + + if (argc < 4 || argc > 5) { + usage(argv[0]); + return -1; + } + + vm_dev = argv[1]; + top_half = argv[2]; + entry = strtol(argv[3], NULL, 0); + if (argv[4]) + bin_file = argv[4]; + + + t_fd = open(top_half, O_RDONLY); + if (t_fd == -1) { + fprintf(stderr, "Error opening top half .o file: %s\n", top_half); + return -1; + } + + if (fstat(t_fd, &t_stat) < 0) { + fprintf(stderr, "Error: could not stat ELF binary file %s\n", top_half); + return -1; + } + + memset(&elf, 0, sizeof(struct top_half_data)); + + elf.elf_size = t_stat.st_size; + + if (bin_file) { + strcpy(elf.bin_file, bin_file); + elf.is_exec_hooked = 1; + } else { + elf.is_exec_hooked = 0; + } + + + /* read in the ELF */ + elf.elf_data = malloc(elf.elf_size); + if (!elf.elf_data) { + fprintf(stderr, "Error allocating memory for ELF data\n"); + return -1; + } + + printf("Loading ELF binary...\n"); + if ((bytes_read = read(t_fd, elf.elf_data, elf.elf_size)) < 0) { + fprintf(stderr, "Error loading ELF binary %s\n", top_half); + return -1; + } + + printf("Loaded. %d Bytes of data read\n", bytes_read); + elf_hdr = (ElfW(Ehdr)*)elf.elf_data; + + /* set the entry point */ + elf.func_offset = entry; + + /* check the ELF magic nr to make sure this is a valid ELF */ + if (elf_hdr->e_ident[EI_MAG0] != 0x7f || + elf_hdr->e_ident[EI_MAG1] != 'E' || + elf_hdr->e_ident[EI_MAG2] != 'L' || + elf_hdr->e_ident[EI_MAG3] != 'F') { + + fprintf(stderr, "Error: Invalid ELF binary %s\n", top_half); + return -1; + } + + /* make sure the ELF is an actual executable file */ + if (elf_hdr->e_type != ET_EXEC) { + fprintf(stderr, "Error: ELF must be an executable file %s\n", top_half); + return -1; + } + + /* is it a dynamically linked executable? */ + elf.is_dyn = is_dynamic(elf_hdr); + + vm_fd = open(vm_dev, O_RDONLY); + if (vm_fd == -1) { + fprintf(stderr, "Error opening VM device: %s\n", vm_dev); + return -1; + } + + printf("Transferring control to Palacios\n"); + err = ioctl(vm_fd, V3_VM_TOPHALF_INJECT, &elf); + if (err < 0) { + fprintf(stderr, "Error providing top half to palacios: %s\n", top_half); + return -1; + } + + free(elf.elf_data); + close(t_fd); + close(vm_fd); + + return 0; +}