/* * cmp(): * File Compare... * Use the standard TFS facilities to compare two different incoming files. * Return 0 if files match, else -1. */ int cmp(char *f1, char *f2) { TFILE finfo1, *tfp1; TFILE finfo2, *tfp2; int fd1, fd2, size, ret; char *buf1, *buf2; /* Check sizes first: */ tfp1 = &finfo1; if (mon_tfsfstat(f1,tfp1) == -1) die(); tfp2 = &finfo2; if (mon_tfsfstat(f2,tfp2) == -1) die(); if (tfp1->filsize != tfp2->filsize) return(-1); /* Copy f1 to buffer: */ buf1 = mon_malloc(TFS_SIZE(tfp1)); if (!buf1) die(); fd1 = mon_tfsopen(f1,TFS_RDONLY,0); if (fd1 < 0) tfsdie(fd1); size = mon_tfsread(fd1,buf1,TFS_SIZE(tfp1)); if (size != TFS_SIZE(tfp1)) tfsdie(size); ret = mon_tfsclose(fd1,0); if (ret != TFS_OKAY) tfsdie(ret); /* Copy f2 to buffer: */ buf2 = mon_malloc(TFS_SIZE(tfp2)); if (!buf2) die(); fd2 = mon_tfsopen(f2,TFS_RDONLY,0); if (fd2 < 0) tfsdie(fd2); size = mon_tfsread(fd2,buf2,TFS_SIZE(tfp2)); if (size != TFS_SIZE(tfp2)) tfsdie(size); ret = mon_tfsclose(fd2,0); if (ret != TFS_OKAY) tfsdie(ret); /* Compare the buffers: */ if (memcmp(buf1,buf2,TFS_SIZE(tfp2))) ret = -1; else ret = 0; mon_free(buf1); mon_free(buf2); return(ret); }
/* Following functions- ikgt_malloc() and ikgt_free() have been extended to * use mon_page_alloc() and mon_page_free() as a temporary solution for * allocation of more than 2040 bytes using page alignment of buffer for * differentiating between mon_malloc allocation() and mon_page_alloc() */ API uint64_t *ikgt_malloc(IN uint32_t size) { uint64_t *buf = NULL; uint32_t num_pages = 0; if (0 == size) { MON_LOG(mask_plugin, level_trace, "%s: size must be greater than 0.\n", __FUNCTION__); return NULL; } /* Internal function requirement. Max block is 2048 bytes, * including 8 byte mem_allocation_info_t structure. */ if (size <= IKGT_MALLOC_MAX_SIZE) { buf = mon_malloc(size); } else { /* If size is more than 2040 bytes, then find number of pages * needed and use mon_page_alloc */ MON_LOG(mask_plugin, level_info, "%s: Using mon_page_alloc\n", __FUNCTION__); num_pages = PAGE_ROUNDUP(size); buf = mon_page_alloc(num_pages); } return buf; }
/* handle int15 from real mode code * we use CS:IP for vmcall instruction to get indication that there is int15 * check for E820 function, if true, then handle it * no other int15 function should come here */ boolean_t handle_int15_vmcall(guest_cpu_handle_t gcpu) { uint16_t selector = 0; uint64_t base = 0; uint32_t limit = 0; uint32_t attr = 0; uint32_t expected_lnr_addr; uint32_t vmcall_lnr_addr; volatile uint64_t r_rax = 0, r_rdx = 0, r_rip = 0; if (!(0x1 & gcpu_get_guest_visible_control_reg(gcpu, IA32_CTRL_CR0))) { /* PE = 0? then real mode * need to get CS:IP to make sure that this VMCALL from INT15 handler */ gcpu_get_segment_reg(gcpu, IA32_SEG_CS, &selector, &base, &limit, &attr); r_rip = gcpu_get_gp_reg(gcpu, IA32_REG_RIP); expected_lnr_addr = SEGMENT_OFFSET_TO_LINEAR( g_int15_trapped_page >> 16, g_int15_trapped_page + VMCALL_OFFSET); vmcall_lnr_addr = SEGMENT_OFFSET_TO_LINEAR((uint32_t)selector, (uint32_t)r_rip); /* check to see if the CS:IP is same as expected for VMCALL in INT15 * handler */ if (expected_lnr_addr == vmcall_lnr_addr) { r_rax = gcpu_get_gp_reg(gcpu, IA32_REG_RAX); r_rdx = gcpu_get_gp_reg(gcpu, IA32_REG_RDX); if ((0xE820 == r_rax) && (SMAP == r_rdx)) { if (g_emap == NULL) { g_emap = mon_malloc(sizeof( e820_map_state_t)); MON_ASSERT(g_emap != NULL); mon_memset(g_emap, 0, sizeof(e820_map_state_t)); } e820_save_guest_state(gcpu, g_emap); g_emap->guest_handle = mon_gcpu_guest_handle( gcpu); e820_int15_handler(g_emap); e820_restore_guest_state(gcpu, g_emap); gcpu_skip_guest_instruction(gcpu); return TRUE; } else { MON_LOG(mask_anonymous, level_error, "INT15 wasn't handled for function 0x%x\n", r_rax); MON_DEADLOOP(); /* Should not get here */ return FALSE; } } }
view_handle_t xmon_initialize_view(void) { guest_view_t *guest_view; guest_view = (guest_view_t *)mon_malloc(sizeof(guest_view_t)); MON_ASSERT(guest_view); guest_view->gpm = GPM_INVALID_HANDLE; guest_view->address_space = MAM_INVALID_HANDLE; guest_view->ept_root_table_hpa = 0; guest_view->gaw = (uint32_t)-1; return (view_handle_t)guest_view; }
/* * cp(): * File Copy... * Use standard TFS facilities to copy one file to another. * If successful, return the size of the copy; else die. */ int cp(char *to, char *from) { TFILE finfo, *tfp; int ffd, tfd, size, ret; char *buffer; /* Open the source file: */ ffd = mon_tfsopen(from,TFS_RDONLY,0); if (ffd < 0) tfsdie(ffd); /* Retrieve stats of the source file: */ tfp = &finfo; if (mon_tfsfstat(from,tfp) == -1) die(); /* The buffer used to open the destination file must be as large as * the source file ... */ buffer = mon_malloc(TFS_SIZE(tfp)); if (!buffer) die(); /* Open the destination file for creation with the same flags * as the source file: */ tfd = mon_tfsopen(to,TFS_CREATE | finfo.flags,buffer); if (tfd < 0) tfsdie(tfd); /* Read the entire source file into buffer, then write the entire * buffer to the destination file... */ size = mon_tfsread(ffd,buffer,TFS_SIZE(tfp)); if (size < 0) tfsdie(size); ret = mon_tfswrite(tfd,buffer,TFS_SIZE(tfp)); if (ret != TFS_OKAY) tfsdie(ret); mon_tfsclose(ffd,0); mon_tfsclose(tfd,finfo.info); mon_free(buffer); return(TFS_SIZE(tfp)); }