status_t load_kernel(stage2_args* args, BootVolume& volume) { const char *name; int fd = find_kernel(volume, &name); if (fd < B_OK) return fd; dprintf("load kernel %s...\n", name); elf_init(); preloaded_image *image; status_t status = elf_load_image(fd, &image); close(fd); if (status < B_OK) { dprintf("loading kernel failed: %lx!\n", status); return status; } gKernelArgs.kernel_image = image; status = elf_relocate_image(gKernelArgs.kernel_image); if (status < B_OK) { dprintf("relocating kernel failed: %lx!\n", status); return status; } gKernelArgs.kernel_image->name = kernel_args_strdup(name); return B_OK; }
void findKernelCodePageByCr3(unsigned startVirtualAddr, Mem * mem, int pageSize, unsigned cr3Pages[]) { unsigned startVirtual = startVirtualAddr; int cr3PageIndex = 0; for (; startVirtual > startVirtualAddr - 1; startVirtual += 0x1000) { // for (; startVirtual < 0x818f0000; startVirtual += 0x1000) { unsigned vAddr = startVirtual; int rw = 0; //read or write int us = 0; //use or system int g = 0; //global(no move out of TLB) or not global int ps = 0; //page size unsigned pAddr = vtopPageProperty(mem->mem, mem->mem_size, mem->pgd, vAddr, &rw, &us, &g, &ps); // IS PHYSICAL ADDRESS VALID? if (pAddr == -1 || pAddr > mem->mem_size) continue; //collect pages which are system access, and global pages if (us == 0 && g == 256) { // printf("r only page %x\n", vAddr); if (find_kernel(mem, vAddr, pageSize) == 0) { //record kernel address cr3Pages[cr3PageIndex++] = vAddr; printf("kernel start at %x\n", vAddr); } } } }
bool is_bootable(Directory *volume) { if (volume->IsEmpty()) return false; // check for the existance of a kernel (for our platform) int fd = find_kernel(volume); if (fd < B_OK) return false; close(fd); return true; }
static struct kvm *kvm_cmd_run_init(int argc, const char **argv) { static char real_cmdline[2048], default_name[20]; unsigned int nr_online_cpus; struct sigaction sa; struct kvm *kvm = kvm__new(); if (IS_ERR(kvm)) return kvm; sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = handle_sigalrm; sigemptyset(&sa.sa_mask); sigaction(SIGALRM, &sa, NULL); nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN); kvm->cfg.custom_rootfs_name = "default"; while (argc != 0) { BUILD_OPTIONS(options, &kvm->cfg, kvm); argc = parse_options(argc, argv, options, run_usage, PARSE_OPT_STOP_AT_NON_OPTION | PARSE_OPT_KEEP_DASHDASH); if (argc != 0) { /* Cusrom options, should have been handled elsewhere */ if (strcmp(argv[0], "--") == 0) { if (kvm_run_wrapper == KVM_RUN_SANDBOX) { kvm->cfg.sandbox = DEFAULT_SANDBOX_FILENAME; kvm_run_write_sandbox_cmd(kvm, argv+1, argc-1); break; } } if ((kvm_run_wrapper == KVM_RUN_DEFAULT && kvm->cfg.kernel_filename) || (kvm_run_wrapper == KVM_RUN_SANDBOX && kvm->cfg.sandbox)) { fprintf(stderr, "Cannot handle parameter: " "%s\n", argv[0]); usage_with_options(run_usage, options); free(kvm); return ERR_PTR(-EINVAL); } if (kvm_run_wrapper == KVM_RUN_SANDBOX) { /* * first unhandled parameter is treated as * sandbox command */ kvm->cfg.sandbox = DEFAULT_SANDBOX_FILENAME; kvm_run_write_sandbox_cmd(kvm, argv, argc); } else { /* * first unhandled parameter is treated as a kernel * image */ kvm->cfg.kernel_filename = argv[0]; } argv++; argc--; } } kvm->nr_disks = kvm->cfg.image_count; if (!kvm->cfg.kernel_filename) kvm->cfg.kernel_filename = find_kernel(); if (!kvm->cfg.kernel_filename) { kernel_usage_with_options(); return ERR_PTR(-EINVAL); } kvm->cfg.vmlinux_filename = find_vmlinux(); kvm->vmlinux = kvm->cfg.vmlinux_filename; if (kvm->cfg.nrcpus == 0) kvm->cfg.nrcpus = nr_online_cpus; if (!kvm->cfg.ram_size) kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus); if (kvm->cfg.ram_size < MIN_RAM_SIZE_MB) die("Not enough memory specified: %lluMB (min %lluMB)", (unsigned long long)kvm->cfg.ram_size, MIN_RAM_SIZE_MB); if (kvm->cfg.ram_size > host_ram_size()) pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB", (unsigned long long)kvm->cfg.ram_size, (unsigned long long)host_ram_size()); kvm->cfg.ram_size <<= MB_SHIFT; if (!kvm->cfg.dev) kvm->cfg.dev = DEFAULT_KVM_DEV; if (!kvm->cfg.console) kvm->cfg.console = DEFAULT_CONSOLE; if (!strncmp(kvm->cfg.console, "virtio", 6)) kvm->cfg.active_console = CONSOLE_VIRTIO; else if (!strncmp(kvm->cfg.console, "serial", 6)) kvm->cfg.active_console = CONSOLE_8250; else if (!strncmp(kvm->cfg.console, "hv", 2)) kvm->cfg.active_console = CONSOLE_HV; else pr_warning("No console!"); if (!kvm->cfg.host_ip) kvm->cfg.host_ip = DEFAULT_HOST_ADDR; if (!kvm->cfg.guest_ip) kvm->cfg.guest_ip = DEFAULT_GUEST_ADDR; if (!kvm->cfg.guest_mac) kvm->cfg.guest_mac = DEFAULT_GUEST_MAC; if (!kvm->cfg.host_mac) kvm->cfg.host_mac = DEFAULT_HOST_MAC; if (!kvm->cfg.script) kvm->cfg.script = DEFAULT_SCRIPT; if (!kvm->cfg.network) kvm->cfg.network = DEFAULT_NETWORK; memset(real_cmdline, 0, sizeof(real_cmdline)); kvm__arch_set_cmdline(real_cmdline, kvm->cfg.vnc || kvm->cfg.sdl); if (strlen(real_cmdline) > 0) strcat(real_cmdline, " "); if (kvm->cfg.kernel_cmdline) strlcat(real_cmdline, kvm->cfg.kernel_cmdline, sizeof(real_cmdline)); if (!kvm->cfg.guest_name) { if (kvm->cfg.custom_rootfs) { kvm->cfg.guest_name = kvm->cfg.custom_rootfs_name; } else { sprintf(default_name, "guest-%u", getpid()); kvm->cfg.guest_name = default_name; } } if (!kvm->cfg.using_rootfs && !kvm->cfg.disk_image[0].filename && !kvm->cfg.initrd_filename) { char tmp[PATH_MAX]; kvm_setup_create_new(kvm->cfg.custom_rootfs_name); kvm_setup_resolv(kvm->cfg.custom_rootfs_name); snprintf(tmp, PATH_MAX, "%s%s", kvm__get_dir(), "default"); if (virtio_9p__register(kvm, tmp, "/dev/root") < 0) die("Unable to initialize virtio 9p"); if (virtio_9p__register(kvm, "/", "hostfs") < 0) die("Unable to initialize virtio 9p"); kvm->cfg.using_rootfs = kvm->cfg.custom_rootfs = 1; } #ifndef CONFIG_MIPS if (kvm->cfg.using_rootfs) { strcat(real_cmdline, " root=/dev/root rw rootflags=rw,trans=virtio,version=9p2000.L rootfstype=9p"); if (kvm->cfg.custom_rootfs) { kvm_run_set_sandbox(kvm); strcat(real_cmdline, " init=/virt/init"); if (!kvm->cfg.no_dhcp) strcat(real_cmdline, " ip=dhcp"); if (kvm_setup_guest_init(kvm)) die("Failed to setup init for guest."); } } else #endif if (!strstr(real_cmdline, "root=")) { strlcat(real_cmdline, " root=/dev/vda rw ", sizeof(real_cmdline)); } kvm->cfg.real_cmdline = real_cmdline; printf(" # %s run -k %s -m %u -c %d --name %s\n", KVM_BINARY_NAME, kvm->cfg.kernel_filename, (unsigned)(kvm->cfg.ram_size / 1024 / 1024), kvm->cfg.nrcpus, kvm->cfg.guest_name); if (init_list__init(kvm) < 0) die ("Initialisation failed"); return kvm; }
/* determine version of OS by mem * 1.To get signature of multiply versions of os, which is the md5 of kernel code * 2.Compared by a decision tree. * 3.Done!*/ void determineOsVersion(Mem * mem) { int i; int pageSize = 4 * 1024; //4k int totalPageNumber = mem->mem_size / (4 * 1024); //assume that every page has 4k unsigned codePageNo = 0; //record when two page have different page index and the same sharp int calledPages[totalPageNumber]; int dsmPages[totalPageNumber]; //record virtual address unsigned virtualAddrs[totalPageNumber]; for (i = 0; i < totalPageNumber; i++) { calledPages[i] = 0; dsmPages[i] = 0; virtualAddrs[i] = 0; } //start address unsigned startVirtualAddr = KERNEL_START_ADDRESS; //with dissemble or not int withDissemble = 1; int cr3PageIndex = 0; unsigned cr3Pages[20]; for (i = 0; i < 20; i++) { cr3Pages[i] = 0; } struct timeval earlier; struct timeval later; if (gettimeofday(&earlier, NULL)) { perror("gettimeofday() error"); exit(1); } //generate step 1 clusters clusters[0].end = 0; int pre_rw = -1; //read or write int pre_us = -1; //use or system int pre_g = -1; //global, no move out of TLB int pre_ps = -1; //page size unsigned cluster_index = 0; newstart = 1; unsigned vAddr = startVirtualAddr; for (; vAddr > KERNEL_START_ADDRESS - 1; vAddr += 0x1000) { //printf("startvirtual %x:\n",startVirtualAddr); int rw = 0; //read or write int us = 0; //use or system int g = 0; //global, no move out of TLB int ps = 0; //page size 4M or 4k unsigned pAddr = vtopPageProperty(mem->mem, mem->mem_size, mem->pgd, vAddr, &rw, &us, &g, &ps); //if PHYSICAL ADDRESS is not VALID, then start a new cluster if (pAddr < 0 || pAddr > mem->mem_size || us != 0 || g != 256) { if (newstart == 0) { clusters[cluster_index].end = vAddr - 1; //printf("err address end is %x %x\n", vAddr, ranges[range_index].end); newstart = 1; } continue; } //if any property changes, then start a new cluster if (rw != pre_rw || us != pre_us || g != pre_g || ps != pre_ps) { if (newstart == 0) { clusters[cluster_index].end = vAddr - 1; //printf("property change end is %x %x\n", vAddr, ranges[range_index].end); newstart = 1; } } //update pre properties pre_rw = rw; pre_us = us; pre_g = g; pre_ps = ps; //collect pages with continuous properties; if (newstart) { clusters[++cluster_index].start = vAddr; clusters[cluster_index].end = vAddr + pageSize - 1; newstart = 0; } else clusters[cluster_index].end = vAddr + pageSize - 1; } if (gettimeofday(&later, NULL)) { perror("gettimeofday() error"); exit(1); } printf("step1, cluster: %d,time cost is %d milliseconds\n", cluster_index, timeval_diff(NULL, &later, &earlier) / 1000); //step2. kernel code page clusters with cr3 if (gettimeofday(&earlier, NULL)) { perror("gettimeofday() error"); exit(1); } unsigned startVirtual = startVirtualAddr; for (; startVirtual > startVirtualAddr - 1; startVirtual += 0x1000) { // for (; startVirtual < 0x818f0000; startVirtual += 0x1000) { unsigned vAddr = startVirtual; int rw = 0; //read or write int us = 0; //use or system int g = 0; //global(no move out of TLB) or not global int ps = 0; //page size unsigned pAddr = vtopPageProperty(mem->mem, mem->mem_size, mem->pgd, vAddr, &rw, &us, &g, &ps); // IS PHYSICAL ADDRESS VALID? if (pAddr == -1 || pAddr > mem->mem_size) continue; //collect pages which are system access, and global pages if (us == 0 && g == 256) { // printf("r only page %x\n", vAddr); if (find_kernel(mem, vAddr, pageSize) == 0) { //record kernel address cr3Pages[cr3PageIndex++] = vAddr; printf("kernel start at %x\n", vAddr); } } } if (gettimeofday(&later, NULL)) { perror("gettimeofday() error"); exit(1); } printf("step2 time cost is %d milliseconds\n", timeval_diff(NULL, &later, &earlier) / 1000); //step 3. clusters if (gettimeofday(&earlier, NULL)) { perror("gettimeofday() error"); exit(1); } int cr3PagesNo = 0; ranges[0].end = 0; newstart = 1; for (i = 1; i <= cluster_index; i++) { //:w printf("%x %x\n", clusters[i].start, clusters[i].end); if (containKernelAddres(clusters[i], cr3Pages) == -1) { continue; } cr3PagesNo++; unsigned vAddr = clusters[i].start; // printf("%x %x\n", clusters[i].start, clusters[i].end); newstart = 1; for (; vAddr < clusters[i].end; vAddr += 0x1000) { unsigned pAddr = vtop(mem->mem, mem->mem_size, mem->pgd, vAddr); if (vAddr == out_pc) code_init(mem, vAddr, pageSize, dsmPages, virtualAddrs, 1, calledPages, &codePageNo); else code_init(mem, vAddr, pageSize, dsmPages, virtualAddrs, 0, calledPages, &codePageNo); } ranges[range_index].end = clusters[i].end; } if (gettimeofday(&later, NULL)) { perror("gettimeofday() error"); exit(1); } printf("step2, cluster: %d\n", cr3PagesNo); printf("step3, cluster: %d,time cost is %d milliseconds\n", range_index, timeval_diff(NULL, &later, &earlier) / 1000); //3.find the kernel core code page cluster, and print it int osNumber = initDb(); if (gettimeofday(&earlier, NULL)) { perror("gettimeofday() error"); exit(1); } int max_len = 0, max_index = 0; for (i = 1; i <= range_index; i++) { // printf("start:%x, end:%x: len:%x kernel\n", ranges[i].start, ranges[i].end, ranges[i].len); if (ranges[i].len > max_len) { max_index = i; max_len = ranges[i].len; } } //4.print md5 of pages that can be disassembled int availableOs[FINGERPRINT_NO], matchCounts[FINGERPRINT_NO]; for (i = 0; i < FINGERPRINT_NO; i++) { availableOs[i] = 1; matchCounts[i] = 0; } startVirtualAddr = ranges[max_index].start; unsigned disasPageNo = 0; unsigned totalPageNo = 0; for (; startVirtualAddr <= ranges[max_index].end; startVirtualAddr += 0x1000) { totalPageNo++; unsigned pAddr = vtop(mem->mem, mem->mem_size, mem->pgd, startVirtualAddr); if (pAddr == -1 || pAddr > mem->mem_size) continue; int pageIndex = pAddr / pageSize; if (dsmPages[pageIndex] == 1) { int offset = (startVirtualAddr - ranges[max_index].start) / 4096; void *startAdress = (void *) ((unsigned) mem->mem + pageIndex * pageSize); unsigned char md5digest[16]; MDMem(startAdress, pageSize, md5digest); // printf("%x ", vaddr); //print vaddr MDPrint(md5digest); printf("\n"); //search hash table int ret = matchByIndex(osNumber, md5digest, offset, availableOs, matchCounts); // genMd5WithOffset(startAdress, pageSize, startVirtualAddr, offset); disasPageNo++; } } if (gettimeofday(&later, NULL)) { perror("gettimeofday() error"); exit(1); } printf("step4.time cost is %d milliseconds\n", timeval_diff(NULL, &later, &earlier) / 1000); int maxIndex = -1; int maxMatch = 0; for (i = 0; i < FINGERPRINT_NO; i++) { if (matchCounts[i] > maxMatch) { maxIndex = i; maxMatch = matchCounts[i]; } } if (maxMatch > 0) printf("Os is %s, match count is %d\n", fingerprints[maxIndex].osVersion, maxMatch); else puts("Unknown OS!"); return; }
int kvm_cmd_run(int argc, const char **argv, const char *prefix) { struct virtio_net_parameters net_params; static char real_cmdline[2048]; struct framebuffer *fb = NULL; unsigned int nr_online_cpus; int exit_code = 0; int max_cpus; char *hi; int i; void *ret; signal(SIGALRM, handle_sigalrm); signal(SIGQUIT, handle_sigquit); signal(SIGUSR1, handle_sigusr1); signal(SIGUSR2, handle_sigusr2); nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN); while (argc != 0) { argc = parse_options(argc, argv, options, run_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (argc != 0) { if (kernel_filename) { fprintf(stderr, "Cannot handle parameter: " "%s\n", argv[0]); usage_with_options(run_usage, options); return EINVAL; } /* first unhandled parameter is treated as a kernel image */ kernel_filename = argv[0]; argv++; argc--; } } if (!kernel_filename) kernel_filename = find_kernel(); if (!kernel_filename) { kernel_usage_with_options(); return EINVAL; } vmlinux_filename = find_vmlinux(); if (nrcpus == 0) nrcpus = nr_online_cpus; else if (nrcpus < 1 || nrcpus > KVM_NR_CPUS) die("Number of CPUs %d is out of [1;%d] range", nrcpus, KVM_NR_CPUS); if (!ram_size) ram_size = get_ram_size(nrcpus); if (ram_size < MIN_RAM_SIZE_MB) die("Not enough memory specified: %lluMB (min %lluMB)", ram_size, MIN_RAM_SIZE_MB); if (ram_size > host_ram_size()) pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB", ram_size, host_ram_size()); ram_size <<= MB_SHIFT; if (!kvm_dev) kvm_dev = DEFAULT_KVM_DEV; if (!console) console = DEFAULT_CONSOLE; if (!strncmp(console, "virtio", 6)) active_console = CONSOLE_VIRTIO; else active_console = CONSOLE_8250; if (!host_ip_addr) host_ip_addr = DEFAULT_HOST_ADDR; if (!guest_mac) guest_mac = DEFAULT_GUEST_MAC; if (!script) script = DEFAULT_SCRIPT; if (virtio_9p_dir) { char tmp[PATH_MAX]; if (realpath(virtio_9p_dir, tmp)) virtio_9p__init(kvm, tmp); else die("Failed resolving 9p path"); } symbol__init(vmlinux_filename); term_init(); kvm = kvm__init(kvm_dev, ram_size); ioeventfd__init(); max_cpus = kvm__max_cpus(kvm); if (nrcpus > max_cpus) { printf(" # Limit the number of CPUs to %d\n", max_cpus); kvm->nrcpus = max_cpus; } kvm->nrcpus = nrcpus; /* * vidmode should be either specified * either set by default */ if (vnc || sdl) { if (vidmode == -1) vidmode = 0x312; } else vidmode = 0; memset(real_cmdline, 0, sizeof(real_cmdline)); strcpy(real_cmdline, "notsc noapic noacpi pci=conf1"); if (vnc || sdl) { strcat(real_cmdline, " video=vesafb console=tty0"); } else strcat(real_cmdline, " console=ttyS0 earlyprintk=serial"); strcat(real_cmdline, " "); if (kernel_cmdline) strlcat(real_cmdline, kernel_cmdline, sizeof(real_cmdline)); hi = NULL; if (!image_filename[0]) { hi = host_image(real_cmdline, sizeof(real_cmdline)); if (hi) { image_filename[0] = hi; readonly_image[0] = true; image_count++; } } if (!strstr(real_cmdline, "root=")) strlcat(real_cmdline, " root=/dev/vda rw ", sizeof(real_cmdline)); if (image_count) { kvm->nr_disks = image_count; kvm->disks = disk_image__open_all(image_filename, readonly_image, image_count); if (!kvm->disks) die("Unable to load all disk images."); virtio_blk__init_all(kvm); } free(hi); printf(" # kvm run -k %s -m %Lu -c %d\n", kernel_filename, ram_size / 1024 / 1024, nrcpus); if (!kvm__load_kernel(kvm, kernel_filename, initrd_filename, real_cmdline, vidmode)) die("unable to load kernel %s", kernel_filename); kvm->vmlinux = vmlinux_filename; ioport__setup_legacy(); rtc__init(); serial8250__init(kvm); pci__init(); if (active_console == CONSOLE_VIRTIO) virtio_console__init(kvm); if (virtio_rng) while (virtio_rng--) virtio_rng__init(kvm); if (!network) network = DEFAULT_NETWORK; if (!strncmp(network, "virtio", 6)) { net_params = (struct virtio_net_parameters) { .host_ip = host_ip_addr, .kvm = kvm, .script = script }; sscanf(guest_mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", net_params.guest_mac, net_params.guest_mac+1, net_params.guest_mac+2, net_params.guest_mac+3, net_params.guest_mac+4, net_params.guest_mac+5); virtio_net__init(&net_params); }
/** * Set command. */ void command_set(const char* line) { char cmd[MAX_BUFFER]; char key[MAX_BUFFER]; char func[MAX_BUFFER]; char arg1[MAX_BUFFER]; char arg2[MAX_BUFFER]; int argc = sscanf(line, "%s %s = %s %s %s", cmd, key, func, arg1, arg2); if (argc < 3) { puts("invalid arguments"); return; } float* matrix = NULL; switch (argc) { case 3: if (strcasecmp(func, "identity") == 0) { matrix = identity_matrix(); } else { goto invalid; } break; case 4: if (strcasecmp(func, "random") == 0) { int seed = atol(arg1); matrix = random_matrix(seed); } else if (strcasecmp(func, "uniform") == 0) { float value = atof(arg1); matrix = uniform_matrix(value); } else if (strcasecmp(func, "cloned") == 0) { MATRIX_GUARD(arg1); matrix = cloned(m); } else if (strcasecmp(func, "sorted") == 0) { MATRIX_GUARD(arg1); matrix = sorted(m); } else if (strcasecmp(func, "rotated") == 0) { MATRIX_GUARD(arg1); matrix = rotated(m); } else if (strcasecmp(func, "reversed") == 0) { MATRIX_GUARD(arg1); matrix = reversed(m); } else if (strcasecmp(func, "transposed") == 0) { MATRIX_GUARD(arg1); matrix = transposed(m); } else { goto invalid; } break; case 5: if (strcasecmp(func, "sequence") == 0) { float start = atof(arg1); float step = atof(arg2); matrix = sequence_matrix(start, step); } else if (strcasecmp(func, "scalar.add") == 0) { MATRIX_GUARD(arg1); float value = atof(arg2); matrix = scalar_add(m, value); } else if (strcasecmp(func, "scalar.mul") == 0) { MATRIX_GUARD(arg1); float value = atof(arg2); matrix = scalar_mul(m, value); } else if (strcasecmp(func, "matrix.add") == 0) { MATRIX_GUARD_PAIR(arg1, arg2); matrix = matrix_add(m1, m2); } else if (strcasecmp(func, "matrix.mul") == 0) { MATRIX_GUARD_PAIR(arg1, arg2); matrix = matrix_mul(m1, m2); } else if (strcasecmp(func, "matrix.pow") == 0) { MATRIX_GUARD(arg1); float exponent = atof(arg2); matrix = matrix_pow(m, exponent); } else if (strcasecmp(func, "matrix.conv") == 0) { MATRIX_GUARD(arg1); const float* kernel = find_kernel(arg2); if (kernel == NULL) { puts("no such kernel"); } matrix = matrix_conv(m, kernel); } else { goto invalid; } break; } entry* e = find_entry(key); if (e == NULL) { e = add_entry(key); } else { free(e->matrix); } e->matrix = matrix; puts("ok"); return; invalid: puts("invalid arguments"); }