--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "iface-env-inject.h"
+
+
+static void usage (char* bin) {
+ fprintf(stderr, "Usage: %s /dev/v3-vm<N> 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;
+}
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include <elf.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#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<N> <inject-code> <code-entry-offset> [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;
+}