2 * V3 Top Half Injection Utility
3 * This code allows a user to inject a "top half" of code into a running guest.
4 * The "bottom half" (a hypercall handler) is inserted using another utility.
6 * (c) Kyle C. Hale, 2011
16 #include <sys/types.h>
17 #include <sys/ioctl.h>
19 #include "iface-code-inject.h"
21 #define __ELF_INJECT_CLASS 32
23 #define ElfW(type) _ElfW (Elf, __ELF_INJECT_CLASS, type)
24 #define _ElfW(e,w,t) _ElfW_1 (e, w, _##t)
25 #define _ElfW_1(e,w,t) e##w##t
28 static void usage (char* bin) {
29 fprintf(stderr, "Usage: %s /dev/v3-vm<N> <inject-code> <code-entry-offset> [inject-point-exe]\n", bin);
33 /* look for PT_DYNAMIC to see if it's dynamically linked */
34 static int is_dynamic (ElfW(Ehdr) * ehdr) {
36 ElfW(Phdr) * phdr = (ElfW(Phdr)*)((char*)ehdr + ehdr->e_phoff);
37 ElfW(Phdr) * phdr_cursor;
41 for (i = 0; i < ehdr->e_phnum; i++, phdr_cursor++) {
42 if (phdr_cursor->p_type == PT_DYNAMIC)
50 int main (int argc, char **argv) {
52 char *top_half = NULL;
53 char *bin_file = NULL;
54 int vm_fd, t_fd, err, bytes_read, entry;
56 struct top_half_data elf;
59 if (argc < 4 || argc > 5) {
66 entry = strtol(argv[3], NULL, 0);
71 t_fd = open(top_half, O_RDONLY);
73 fprintf(stderr, "Error opening top half .o file: %s\n", top_half);
77 if (fstat(t_fd, &t_stat) < 0) {
78 fprintf(stderr, "Error: could not stat ELF binary file %s\n", top_half);
82 memset(&elf, 0, sizeof(struct top_half_data));
84 elf.elf_size = t_stat.st_size;
87 strcpy(elf.bin_file, bin_file);
88 elf.is_exec_hooked = 1;
90 elf.is_exec_hooked = 0;
95 elf.elf_data = malloc(elf.elf_size);
97 fprintf(stderr, "Error allocating memory for ELF data\n");
101 printf("Loading ELF binary...\n");
102 if ((bytes_read = read(t_fd, elf.elf_data, elf.elf_size)) < 0) {
103 fprintf(stderr, "Error loading ELF binary %s\n", top_half);
107 printf("Loaded. %d Bytes of data read\n", bytes_read);
108 elf_hdr = (ElfW(Ehdr)*)elf.elf_data;
110 /* set the entry point */
111 elf.func_offset = entry;
113 /* check the ELF magic nr to make sure this is a valid ELF */
114 if (elf_hdr->e_ident[EI_MAG0] != 0x7f ||
115 elf_hdr->e_ident[EI_MAG1] != 'E' ||
116 elf_hdr->e_ident[EI_MAG2] != 'L' ||
117 elf_hdr->e_ident[EI_MAG3] != 'F') {
119 fprintf(stderr, "Error: Invalid ELF binary %s\n", top_half);
123 /* make sure the ELF is an actual executable file */
124 if (elf_hdr->e_type != ET_EXEC) {
125 fprintf(stderr, "Error: ELF must be an executable file %s\n", top_half);
129 /* is it a dynamically linked executable? */
130 elf.is_dyn = is_dynamic(elf_hdr);
132 vm_fd = open(vm_dev, O_RDONLY);
134 fprintf(stderr, "Error opening VM device: %s\n", vm_dev);
138 printf("Transferring control to Palacios\n");
139 err = ioctl(vm_fd, V3_VM_TOPHALF_INJECT, &elf);
141 fprintf(stderr, "Error providing top half to palacios: %s\n", top_half);