├── AUTHORS ├── KVM-PT ├── .gitignore ├── Kconfig ├── Makefile.template ├── README ├── cpuid.c ├── cpuid.h ├── debugfs.c ├── emulate.c ├── header │ ├── asm-generic │ │ └── kvm_para.h │ ├── kvm │ │ └── iodev.h │ ├── linux │ │ ├── kvm_host.h │ │ ├── kvm_irqfd.h │ │ ├── kvm_para.h │ │ └── kvm_types.h │ ├── uapi │ │ ├── asm-generic │ │ │ └── kvm_para.h │ │ ├── asm │ │ │ └── kvm.h │ │ └── linux │ │ │ ├── kvm.h │ │ │ └── kvm_para.h │ └── x86 │ │ ├── include │ │ ├── asm │ │ │ ├── kvm_emulate.h │ │ │ ├── kvm_host.h │ │ │ ├── kvm_page_track.h │ │ │ └── kvm_para.h │ │ └── uapi │ │ │ └── asm │ │ │ └── kvm_para.h │ │ └── kvm │ │ └── kvm_cache_regs.h ├── hyperv.c ├── hyperv.h ├── i8254.c ├── i8254.h ├── i8259.c ├── ioapic.c ├── ioapic.h ├── irq.c ├── irq.h ├── irq_comm.c ├── lapic.c ├── lapic.h ├── load.sh ├── mmu.c ├── mmu.h ├── mmu_audit.c ├── mtrr.c ├── page_track.c ├── paging_tmpl.h ├── pmu.c ├── pmu.h ├── pmu_amd.c ├── pmu_intel.c ├── tss.h ├── usermode_test │ ├── .gitignore │ ├── compile.sh │ ├── support_test.c │ ├── test.c │ └── test_signal.c ├── virt │ ├── kvm │ │ ├── Kconfig │ │ ├── async_pf.c │ │ ├── async_pf.h │ │ ├── coalesced_mmio.c │ │ ├── coalesced_mmio.h │ │ ├── eventfd.c │ │ ├── irqbypass.c │ │ ├── irqchip.c │ │ ├── kvm_main.c │ │ ├── vfio.c │ │ └── vfio.h │ └── lib │ │ ├── Kconfig │ │ └── irqbypass.c ├── vmx.c ├── vmx.h ├── vmx_evmcs.h ├── vmx_fdl.c ├── vmx_fdl.h ├── vmx_pt.c ├── vmx_pt.h ├── vmx_shadow_fields.h ├── x86.c └── x86.h ├── LICENSE ├── Makefile ├── QEMU-PT ├── .gitignore ├── compile_qemu_pt.sh ├── qemu-4.2.50.zip └── qemu_pt.patch ├── README.md ├── Targets ├── bhyve │ ├── .gitignore │ ├── VM │ │ ├── .gitignore │ │ ├── copy_install_files.sh │ │ ├── create_pre_snapshot.sh │ │ ├── pre_snapshot │ │ │ └── .keep │ │ └── prepare.sh │ ├── agent │ │ ├── bin │ │ │ ├── loader │ │ │ ├── req_data │ │ │ ├── set_ip_range │ │ │ └── set_vmm_ip_range │ │ ├── compile.sh │ │ └── src │ │ │ ├── install.sh │ │ │ ├── loader.c │ │ │ ├── req_data.c │ │ │ ├── run.sh │ │ │ ├── run_asan.sh │ │ │ ├── set_ip_range.c │ │ │ └── set_vmm_ip_range.c │ ├── config_template.ron │ └── sharedir │ │ ├── hypertrash_crash_detector.c │ │ ├── kafl_user.h │ │ ├── req_data │ │ ├── run.sh │ │ └── set_ip_range.c └── qemu │ ├── .gitignore │ ├── VM │ ├── .gitignore │ ├── copy_install_files.sh │ ├── create_pre_snapshot.sh │ └── prepare.sh │ ├── agent │ ├── bin │ │ └── .keep │ ├── build_sharedir.sh │ ├── compile.sh │ ├── kafl_user.h │ └── src │ │ ├── hypertrash_crash_detector.c │ │ ├── hypertrash_crash_detector_asan.c │ │ ├── loader.c │ │ ├── req_data.c │ │ ├── run.sh │ │ ├── run_asan.sh │ │ ├── set_ip_range.c │ │ └── set_kvm_ip_range.c │ ├── config_template.ron │ ├── misc │ ├── grub.cfg │ ├── install.sh │ └── sources.list │ ├── sharedir │ └── .keep │ └── sharedir_asan │ └── .keep ├── nyx_fuzzer ├── .gitignore ├── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── fuzz_runner │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── exitreason.rs │ │ ├── forksrv │ │ ├── error.rs │ │ ├── mod.rs │ │ └── newtypes.rs │ │ ├── lib.rs │ │ └── nyx │ │ ├── aux_buffer.rs │ │ ├── mem_barrier.rs │ │ ├── mod.rs │ │ ├── params.rs │ │ └── qemu_process.rs ├── helpers │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── hash_by_ref.rs │ │ └── lib.rs ├── hypervisor_spec │ ├── .gitignore │ ├── build │ │ ├── .gitignore │ │ ├── custom_includes.h │ │ ├── hypertrash_os │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── bin │ │ │ │ └── .keep │ │ │ ├── grub │ │ │ │ ├── .gitignore │ │ │ │ ├── grub.zip │ │ │ │ ├── install.sh │ │ │ │ └── patches │ │ │ │ │ ├── kern_efi_mm.patch │ │ │ │ │ ├── loader_multiboot.patch │ │ │ │ │ └── video_video.patch │ │ │ ├── include │ │ │ │ ├── acpi.h │ │ │ │ ├── apic.h │ │ │ │ ├── bmp.h │ │ │ │ ├── config.h │ │ │ │ ├── cpuid.h │ │ │ │ ├── efi.h │ │ │ │ ├── fuzz.h │ │ │ │ ├── hypercube_opcodes.h │ │ │ │ ├── io.h │ │ │ │ ├── isa.h │ │ │ │ ├── isr.h │ │ │ │ ├── kafl_user.h │ │ │ │ ├── libk.h │ │ │ │ ├── mboot.h │ │ │ │ ├── mbootv1.h │ │ │ │ ├── mem.h │ │ │ │ ├── mmio.h │ │ │ │ ├── msr.h │ │ │ │ ├── panic.h │ │ │ │ ├── pci.h │ │ │ │ ├── pic.h │ │ │ │ ├── serial.h │ │ │ │ ├── smp.h │ │ │ │ ├── system.h │ │ │ │ ├── test.h │ │ │ │ ├── tty.h │ │ │ │ └── vga.h │ │ │ ├── iso │ │ │ │ └── hypertrash_os_bios.iso │ │ │ ├── misc │ │ │ │ ├── crash.hexa │ │ │ │ ├── grub.cfg │ │ │ │ ├── linker.ld │ │ │ │ └── logo.bmp │ │ │ ├── src │ │ │ │ ├── acpi.c │ │ │ │ ├── apic.c │ │ │ │ ├── asm │ │ │ │ │ ├── ap_boot.s │ │ │ │ │ ├── boot.s │ │ │ │ │ ├── boot_v2.s │ │ │ │ │ ├── bootv1.s │ │ │ │ │ └── cpu_tables.s │ │ │ │ ├── cpuid.c │ │ │ │ ├── efi.c │ │ │ │ ├── fuzz.c │ │ │ │ ├── gdt.c │ │ │ │ ├── hypercube_opcodes.c │ │ │ │ ├── idt.c │ │ │ │ ├── isa.c │ │ │ │ ├── isr.c │ │ │ │ ├── kernel.c │ │ │ │ ├── libk.c │ │ │ │ ├── mboot.c │ │ │ │ ├── mem.c │ │ │ │ ├── msr.c │ │ │ │ ├── panic.c │ │ │ │ ├── pci.c │ │ │ │ ├── pic.c │ │ │ │ ├── serial.c │ │ │ │ ├── smp.c │ │ │ │ └── tty.c │ │ │ ├── tesseract │ │ │ │ ├── compile.sh │ │ │ │ ├── core.c │ │ │ │ ├── core.h │ │ │ │ ├── decompiler.c │ │ │ │ ├── decompiler.h │ │ │ │ ├── dict.c │ │ │ │ ├── dict.h │ │ │ │ ├── generate_config.c │ │ │ │ ├── io.h │ │ │ │ ├── main.c │ │ │ │ ├── mmio.h │ │ │ │ ├── opcodes.c │ │ │ │ ├── opcodes.h │ │ │ │ ├── state.c │ │ │ │ └── state.h │ │ │ └── xorriso │ │ └── userspace_tester.c │ ├── gen_spec.py │ ├── hexa_spec │ │ ├── .gitignore │ │ ├── __init__.py │ │ ├── ahci.py │ │ ├── legacy.py │ │ └── xhci.py │ ├── make.sh │ └── make_sharedirs.sh ├── rust_fuzzer │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── config.ron │ ├── config_forkserver.ron │ ├── config_kernel.ron │ ├── config_snapshot.ron │ ├── config_snapshot_cluster_ubuntu.ron │ ├── deploy.sh │ ├── spec.msgp │ └── src │ │ ├── bitmap.rs │ │ ├── fuzzer.rs │ │ ├── input.rs │ │ ├── main.rs │ │ ├── queue.rs │ │ └── romu.rs ├── rust_fuzzer_debug │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs └── structured_fuzzer │ ├── .gitignore │ ├── Cargo.toml │ ├── examples │ ├── display.rs │ └── gen.rs │ ├── interpreter │ ├── build │ │ ├── .gitignore │ │ ├── a.out │ │ ├── bytecode_spec.h │ │ ├── bytecode_spec.template.h │ │ ├── data_include.h │ │ ├── interpreter.h │ │ ├── interpreter_main.c │ │ ├── make.sh │ │ └── spec.msgp │ ├── example_spec.msgp │ ├── example_spec.py │ ├── spec_lib │ │ ├── .gitignore │ │ ├── __init__.py │ │ ├── data_spec.py │ │ ├── generators.py │ │ ├── graph_builder.py │ │ ├── graph_spec.py │ │ └── templates │ │ │ ├── bytecode_spec.jinja.h │ │ │ ├── data_include.jinja.h │ │ │ ├── data_struct.jinja.h │ │ │ └── interpreter.jinja.h │ ├── spec_vec_u8.msgp │ ├── spec_vec_u8.py │ ├── test_spec.msgp │ └── test_spec.py │ └── src │ ├── custom_dict.rs │ ├── data_buff.rs │ ├── graph_mutator │ ├── atomic_data.rs │ ├── generators.rs │ ├── graph_builder.rs │ ├── graph_iter.rs │ ├── graph_storage.rs │ ├── mod.rs │ ├── newtypes.rs │ ├── spec.rs │ └── spec_loader.rs │ ├── lib.rs │ ├── mutator.rs │ ├── primitive_mutator │ ├── .gitignore │ ├── inplace_mutation.rs │ ├── mod.rs │ ├── mutations.txt │ ├── mutator.rs │ └── size_changing_mutation.rs │ └── random │ ├── choices.rs │ ├── distributions.rs │ ├── mod.rs │ └── romu.rs └── paper.png /AUTHORS: -------------------------------------------------------------------------------- 1 | Sergej Schumilo 2 | Cornelius Aschermann 3 | -------------------------------------------------------------------------------- /KVM-PT/.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE! Don't add files that are generated in specific 3 | # subdirectories here. Add them in the ".gitignore" file 4 | # in that subdirectory instead. 5 | # 6 | # NOTE! Please use 'git ls-files -i --exclude-standard' 7 | # command after changing this file, to see if there are 8 | # any tracked files which get ignored after the change. 9 | # 10 | # Normal rules 11 | # 12 | 13 | oldconfig.log 14 | 15 | .* 16 | *.o 17 | *.o.* 18 | *.a 19 | *.s 20 | *.ko 21 | *.so 22 | *.so.dbg 23 | *.mod.c 24 | *.i 25 | *.lst 26 | *.symtypes 27 | *.order 28 | *.elf 29 | *.bin 30 | *.tar 31 | *.gz 32 | *.bz2 33 | *.lzma 34 | *.xz 35 | *.lz4 36 | *.lzo 37 | *.patch 38 | *.gcno 39 | modules.builtin 40 | Module.symvers 41 | *.dwo 42 | *.su 43 | 44 | # 45 | # Top-level generic files 46 | # 47 | /tags 48 | /TAGS 49 | /linux 50 | /vmlinux 51 | /vmlinux.32 52 | /vmlinux-gdb.py 53 | /vmlinuz 54 | /System.map 55 | /Module.markers 56 | 57 | # 58 | # Debian directory (make deb-pkg) 59 | # 60 | /debian/ 61 | 62 | # 63 | # tar directory (make tar*-pkg) 64 | # 65 | /tar-install/ 66 | 67 | # 68 | # git files that we don't want to ignore even it they are dot-files 69 | # 70 | !.gitignore 71 | !.mailmap 72 | 73 | # 74 | # Generated include files 75 | # 76 | include/config 77 | include/generated 78 | arch/*/include/generated 79 | 80 | # stgit generated dirs 81 | patches-* 82 | 83 | # quilt's files 84 | patches 85 | series 86 | 87 | # cscope files 88 | cscope.* 89 | ncscope.* 90 | 91 | # gnu global files 92 | GPATH 93 | GRTAGS 94 | GSYMS 95 | GTAGS 96 | 97 | # id-utils files 98 | ID 99 | 100 | *.orig 101 | *~ 102 | \#*# 103 | 104 | # 105 | # Leavings from module signing 106 | # 107 | extra_certificates 108 | signing_key.pem 109 | signing_key.priv 110 | signing_key.x509 111 | x509.genkey 112 | 113 | # Kconfig presets 114 | all.config 115 | 116 | # Kdevelop4 117 | *.kdev4 118 | 119 | Makefile 120 | -------------------------------------------------------------------------------- /KVM-PT/Makefile.template: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0 2 | 3 | ccflags-y += -Iarch/x86/kvm -Iinclude/ -DCONFIG_KVM_VMX_PT -DCONFIG_KVM_VMX_FDL -IPWD 4 | 5 | CFLAGS_x86.o := -I. 6 | CFLAGS_svm.o := -I. 7 | CFLAGS_vmx.o := -I. 8 | 9 | KVM := ./virt/kvm 10 | 11 | 12 | kvm-pt-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ 13 | $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o 14 | kvm-pt-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o 15 | 16 | kvm-pt-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ 17 | i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \ 18 | hyperv.o page_track.o debugfs.o 19 | 20 | kvm-pt-y += vmx.o pmu_intel.o 21 | kvm-pt-y += vmx_pt.o 22 | kvm-pt-y += vmx_fdl.o 23 | 24 | 25 | obj-$(CONFIG_KVM) += kvm-pt.o 26 | -------------------------------------------------------------------------------- /KVM-PT/README: -------------------------------------------------------------------------------- 1 | # Kernel 4.19 Setup 2 | 3 | ``` 4 | cd /tmp/ 5 | wget -c http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.19/linux-headers-4.19.0-041900_4.19.0-041900.201810221809_all.deb 6 | wget -c http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.19/linux-headers-4.19.0-041900-generic_4.19.0-041900.201810221809_amd64.deb 7 | wget -c http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.19/linux-image-unsigned-4.19.0-041900-generic_4.19.0-041900.201810221809_amd64.deb 8 | wget -c http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.19/linux-modules-4.19.0-041900-generic_4.19.0-041900.201810221809_amd64.deb 9 | sudo dpkg -i *.deb 10 | ``` 11 | 12 | # KVM-PT OOT Build 13 | 14 | ``` 15 | sh load.sh 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /KVM-PT/debugfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel-based Virtual Machine driver for Linux 3 | * 4 | * Copyright 2016 Red Hat, Inc. and/or its affiliates. 5 | * 6 | * This work is licensed under the terms of the GNU GPL, version 2. See 7 | * the COPYING file in the top-level directory. 8 | * 9 | */ 10 | #include "header/linux/kvm_host.h" 11 | #include 12 | 13 | bool kvm_arch_has_vcpu_debugfs(void) 14 | { 15 | return true; 16 | } 17 | 18 | static int vcpu_get_tsc_offset(void *data, u64 *val) 19 | { 20 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *) data; 21 | *val = vcpu->arch.tsc_offset; 22 | return 0; 23 | } 24 | 25 | DEFINE_SIMPLE_ATTRIBUTE(vcpu_tsc_offset_fops, vcpu_get_tsc_offset, NULL, "%lld\n"); 26 | 27 | static int vcpu_get_tsc_scaling_ratio(void *data, u64 *val) 28 | { 29 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *) data; 30 | *val = vcpu->arch.tsc_scaling_ratio; 31 | return 0; 32 | } 33 | 34 | DEFINE_SIMPLE_ATTRIBUTE(vcpu_tsc_scaling_fops, vcpu_get_tsc_scaling_ratio, NULL, "%llu\n"); 35 | 36 | static int vcpu_get_tsc_scaling_frac_bits(void *data, u64 *val) 37 | { 38 | *val = kvm_tsc_scaling_ratio_frac_bits; 39 | return 0; 40 | } 41 | 42 | DEFINE_SIMPLE_ATTRIBUTE(vcpu_tsc_scaling_frac_fops, vcpu_get_tsc_scaling_frac_bits, NULL, "%llu\n"); 43 | 44 | int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu) 45 | { 46 | struct dentry *ret; 47 | 48 | ret = debugfs_create_file("tsc-offset", 0444, 49 | vcpu->debugfs_dentry, 50 | vcpu, &vcpu_tsc_offset_fops); 51 | if (!ret) 52 | return -ENOMEM; 53 | 54 | if (kvm_has_tsc_control) { 55 | ret = debugfs_create_file("tsc-scaling-ratio", 0444, 56 | vcpu->debugfs_dentry, 57 | vcpu, &vcpu_tsc_scaling_fops); 58 | if (!ret) 59 | return -ENOMEM; 60 | ret = debugfs_create_file("tsc-scaling-ratio-frac-bits", 0444, 61 | vcpu->debugfs_dentry, 62 | vcpu, &vcpu_tsc_scaling_frac_fops); 63 | if (!ret) 64 | return -ENOMEM; 65 | 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /KVM-PT/header/asm-generic/kvm_para.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef _ASM_GENERIC_KVM_PARA_H 3 | #define _ASM_GENERIC_KVM_PARA_H 4 | 5 | 6 | #include "header/uapi/asm-generic/kvm_para.h" 7 | //#include 8 | 9 | 10 | /* 11 | * This function is used by architectures that support kvm to avoid issuing 12 | * false soft lockup messages. 13 | */ 14 | static inline bool kvm_check_and_clear_guest_paused(void) 15 | { 16 | return false; 17 | } 18 | 19 | static inline unsigned int kvm_arch_para_features(void) 20 | { 21 | return 0; 22 | } 23 | 24 | static inline unsigned int kvm_arch_para_hints(void) 25 | { 26 | return 0; 27 | } 28 | 29 | static inline bool kvm_para_available(void) 30 | { 31 | return false; 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /KVM-PT/header/kvm/iodev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License. 5 | * 6 | * This program is distributed in the hope that it will be useful, 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | * GNU General Public License for more details. 10 | * 11 | * You should have received a copy of the GNU General Public License 12 | * along with this program. If not, see . 13 | */ 14 | 15 | #ifndef __KVM_IODEV_H__ 16 | #define __KVM_IODEV_H__ 17 | 18 | #include "header/linux/kvm_types.h" 19 | //#include 20 | #include 21 | 22 | struct kvm_io_device; 23 | struct kvm_vcpu; 24 | 25 | /** 26 | * kvm_io_device_ops are called under kvm slots_lock. 27 | * read and write handlers return 0 if the transaction has been handled, 28 | * or non-zero to have it passed to the next device. 29 | **/ 30 | struct kvm_io_device_ops { 31 | int (*read)(struct kvm_vcpu *vcpu, 32 | struct kvm_io_device *this, 33 | gpa_t addr, 34 | int len, 35 | void *val); 36 | int (*write)(struct kvm_vcpu *vcpu, 37 | struct kvm_io_device *this, 38 | gpa_t addr, 39 | int len, 40 | const void *val); 41 | void (*destructor)(struct kvm_io_device *this); 42 | }; 43 | 44 | 45 | struct kvm_io_device { 46 | const struct kvm_io_device_ops *ops; 47 | }; 48 | 49 | static inline void kvm_iodevice_init(struct kvm_io_device *dev, 50 | const struct kvm_io_device_ops *ops) 51 | { 52 | dev->ops = ops; 53 | } 54 | 55 | static inline int kvm_iodevice_read(struct kvm_vcpu *vcpu, 56 | struct kvm_io_device *dev, gpa_t addr, 57 | int l, void *v) 58 | { 59 | return dev->ops->read ? dev->ops->read(vcpu, dev, addr, l, v) 60 | : -EOPNOTSUPP; 61 | } 62 | 63 | static inline int kvm_iodevice_write(struct kvm_vcpu *vcpu, 64 | struct kvm_io_device *dev, gpa_t addr, 65 | int l, const void *v) 66 | { 67 | return dev->ops->write ? dev->ops->write(vcpu, dev, addr, l, v) 68 | : -EOPNOTSUPP; 69 | } 70 | 71 | static inline void kvm_iodevice_destructor(struct kvm_io_device *dev) 72 | { 73 | if (dev->ops->destructor) 74 | dev->ops->destructor(dev); 75 | } 76 | 77 | #endif /* __KVM_IODEV_H__ */ 78 | -------------------------------------------------------------------------------- /KVM-PT/header/linux/kvm_irqfd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License. 5 | * 6 | * This program is distributed in the hope that it will be useful, 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | * GNU General Public License for more details. 10 | * 11 | * irqfd: Allows an fd to be used to inject an interrupt to the guest 12 | * Credit goes to Avi Kivity for the original idea. 13 | */ 14 | 15 | #ifndef __LINUX_KVM_IRQFD_H 16 | #define __LINUX_KVM_IRQFD_H 17 | 18 | #include "header/linux/kvm_host.h" 19 | //#include 20 | #include 21 | 22 | /* 23 | * Resampling irqfds are a special variety of irqfds used to emulate 24 | * level triggered interrupts. The interrupt is asserted on eventfd 25 | * trigger. On acknowledgment through the irq ack notifier, the 26 | * interrupt is de-asserted and userspace is notified through the 27 | * resamplefd. All resamplers on the same gsi are de-asserted 28 | * together, so we don't need to track the state of each individual 29 | * user. We can also therefore share the same irq source ID. 30 | */ 31 | struct kvm_kernel_irqfd_resampler { 32 | struct kvm *kvm; 33 | /* 34 | * List of resampling struct _irqfd objects sharing this gsi. 35 | * RCU list modified under kvm->irqfds.resampler_lock 36 | */ 37 | struct list_head list; 38 | struct kvm_irq_ack_notifier notifier; 39 | /* 40 | * Entry in list of kvm->irqfd.resampler_list. Use for sharing 41 | * resamplers among irqfds on the same gsi. 42 | * Accessed and modified under kvm->irqfds.resampler_lock 43 | */ 44 | struct list_head link; 45 | }; 46 | 47 | struct kvm_kernel_irqfd { 48 | /* Used for MSI fast-path */ 49 | struct kvm *kvm; 50 | wait_queue_entry_t wait; 51 | /* Update side is protected by irqfds.lock */ 52 | struct kvm_kernel_irq_routing_entry irq_entry; 53 | seqcount_t irq_entry_sc; 54 | /* Used for level IRQ fast-path */ 55 | int gsi; 56 | struct work_struct inject; 57 | /* The resampler used by this irqfd (resampler-only) */ 58 | struct kvm_kernel_irqfd_resampler *resampler; 59 | /* Eventfd notified on resample (resampler-only) */ 60 | struct eventfd_ctx *resamplefd; 61 | /* Entry in list of irqfds for a resampler (resampler-only) */ 62 | struct list_head resampler_link; 63 | /* Used for setup/shutdown */ 64 | struct eventfd_ctx *eventfd; 65 | struct list_head list; 66 | poll_table pt; 67 | struct work_struct shutdown; 68 | struct irq_bypass_consumer consumer; 69 | struct irq_bypass_producer *producer; 70 | }; 71 | 72 | #endif /* __LINUX_KVM_IRQFD_H */ 73 | -------------------------------------------------------------------------------- /KVM-PT/header/linux/kvm_para.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef __LINUX_KVM_PARA_H 3 | #define __LINUX_KVM_PARA_H 4 | 5 | #include "header/x86/include/asm/kvm_para.h" 6 | //#include "header/uapi/linux/kvm_para.h" 7 | 8 | 9 | static inline bool kvm_para_has_feature(unsigned int feature) 10 | { 11 | return !!(kvm_arch_para_features() & (1UL << feature)); 12 | } 13 | 14 | static inline bool kvm_para_has_hint(unsigned int feature) 15 | { 16 | return !!(kvm_arch_para_hints() & (1UL << feature)); 17 | } 18 | #endif /* __LINUX_KVM_PARA_H */ 19 | -------------------------------------------------------------------------------- /KVM-PT/header/linux/kvm_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License. 5 | * 6 | * This program is distributed in the hope that it will be useful, 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | * GNU General Public License for more details. 10 | * 11 | * You should have received a copy of the GNU General Public License 12 | * along with this program; if not, write to the Free Software 13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 14 | * 15 | */ 16 | 17 | #ifndef __KVM_TYPES_H__ 18 | #define __KVM_TYPES_H__ 19 | 20 | struct kvm; 21 | struct kvm_async_pf; 22 | struct kvm_device_ops; 23 | struct kvm_interrupt; 24 | struct kvm_irq_routing_table; 25 | struct kvm_memory_slot; 26 | struct kvm_one_reg; 27 | struct kvm_run; 28 | struct kvm_userspace_memory_region; 29 | struct kvm_vcpu; 30 | struct kvm_vcpu_init; 31 | struct kvm_memslots; 32 | 33 | enum kvm_mr_change; 34 | 35 | #include 36 | 37 | /* 38 | * Address types: 39 | * 40 | * gva - guest virtual address 41 | * gpa - guest physical address 42 | * gfn - guest frame number 43 | * hva - host virtual address 44 | * hpa - host physical address 45 | * hfn - host frame number 46 | */ 47 | 48 | typedef unsigned long gva_t; 49 | typedef u64 gpa_t; 50 | typedef u64 gfn_t; 51 | 52 | typedef unsigned long hva_t; 53 | typedef u64 hpa_t; 54 | typedef u64 hfn_t; 55 | 56 | typedef hfn_t kvm_pfn_t; 57 | 58 | struct gfn_to_hva_cache { 59 | u64 generation; 60 | gpa_t gpa; 61 | unsigned long hva; 62 | unsigned long len; 63 | struct kvm_memory_slot *memslot; 64 | }; 65 | 66 | #endif /* __KVM_TYPES_H__ */ 67 | -------------------------------------------------------------------------------- /KVM-PT/header/uapi/asm-generic/kvm_para.h: -------------------------------------------------------------------------------- 1 | /* 2 | * There isn't anything here, but the file must not be empty or patch 3 | * will delete it. 4 | */ 5 | -------------------------------------------------------------------------------- /KVM-PT/header/uapi/linux/kvm_para.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 | #ifndef _UAPI__LINUX_KVM_PARA_H 3 | #define _UAPI__LINUX_KVM_PARA_H 4 | 5 | /* 6 | * This header file provides a method for making a hypercall to the host 7 | * Architectures should define: 8 | * - kvm_hypercall0, kvm_hypercall1... 9 | * - kvm_arch_para_features 10 | * - kvm_para_available 11 | */ 12 | 13 | /* Return values for hypercalls */ 14 | #define KVM_ENOSYS 1000 15 | #define KVM_EFAULT EFAULT 16 | #define KVM_EINVAL EINVAL 17 | #define KVM_E2BIG E2BIG 18 | #define KVM_EPERM EPERM 19 | #define KVM_EOPNOTSUPP 95 20 | 21 | #define KVM_HC_VAPIC_POLL_IRQ 1 22 | #define KVM_HC_MMU_OP 2 23 | #define KVM_HC_FEATURES 3 24 | #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 25 | #define KVM_HC_KICK_CPU 5 26 | #define KVM_HC_MIPS_GET_CLOCK_FREQ 6 27 | #define KVM_HC_MIPS_EXIT_VM 7 28 | #define KVM_HC_MIPS_CONSOLE_OUTPUT 8 29 | #define KVM_HC_CLOCK_PAIRING 9 30 | #define KVM_HC_SEND_IPI 10 31 | 32 | /* 33 | * hypercalls use architecture specific 34 | */ 35 | #include 36 | 37 | #endif /* _UAPI__LINUX_KVM_PARA_H */ 38 | -------------------------------------------------------------------------------- /KVM-PT/header/x86/include/asm/kvm_page_track.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef _ASM_X86_KVM_PAGE_TRACK_H 3 | #define _ASM_X86_KVM_PAGE_TRACK_H 4 | 5 | enum kvm_page_track_mode { 6 | KVM_PAGE_TRACK_WRITE, 7 | KVM_PAGE_TRACK_MAX, 8 | }; 9 | 10 | /* 11 | * The notifier represented by @kvm_page_track_notifier_node is linked into 12 | * the head which will be notified when guest is triggering the track event. 13 | * 14 | * Write access on the head is protected by kvm->mmu_lock, read access 15 | * is protected by track_srcu. 16 | */ 17 | struct kvm_page_track_notifier_head { 18 | struct srcu_struct track_srcu; 19 | struct hlist_head track_notifier_list; 20 | }; 21 | 22 | struct kvm_page_track_notifier_node { 23 | struct hlist_node node; 24 | 25 | /* 26 | * It is called when guest is writing the write-tracked page 27 | * and write emulation is finished at that time. 28 | * 29 | * @vcpu: the vcpu where the write access happened. 30 | * @gpa: the physical address written by guest. 31 | * @new: the data was written to the address. 32 | * @bytes: the written length. 33 | * @node: this node 34 | */ 35 | void (*track_write)(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, 36 | int bytes, struct kvm_page_track_notifier_node *node); 37 | /* 38 | * It is called when memory slot is being moved or removed 39 | * users can drop write-protection for the pages in that memory slot 40 | * 41 | * @kvm: the kvm where memory slot being moved or removed 42 | * @slot: the memory slot being moved or removed 43 | * @node: this node 44 | */ 45 | void (*track_flush_slot)(struct kvm *kvm, struct kvm_memory_slot *slot, 46 | struct kvm_page_track_notifier_node *node); 47 | }; 48 | 49 | void kvm_page_track_init(struct kvm *kvm); 50 | void kvm_page_track_cleanup(struct kvm *kvm); 51 | 52 | void kvm_page_track_free_memslot(struct kvm_memory_slot *free, 53 | struct kvm_memory_slot *dont); 54 | int kvm_page_track_create_memslot(struct kvm_memory_slot *slot, 55 | unsigned long npages); 56 | 57 | void kvm_slot_page_track_add_page(struct kvm *kvm, 58 | struct kvm_memory_slot *slot, gfn_t gfn, 59 | enum kvm_page_track_mode mode); 60 | void kvm_slot_page_track_remove_page(struct kvm *kvm, 61 | struct kvm_memory_slot *slot, gfn_t gfn, 62 | enum kvm_page_track_mode mode); 63 | bool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn, 64 | enum kvm_page_track_mode mode); 65 | 66 | void 67 | kvm_page_track_register_notifier(struct kvm *kvm, 68 | struct kvm_page_track_notifier_node *n); 69 | void 70 | kvm_page_track_unregister_notifier(struct kvm *kvm, 71 | struct kvm_page_track_notifier_node *n); 72 | void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, 73 | int bytes); 74 | void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot); 75 | #endif 76 | -------------------------------------------------------------------------------- /KVM-PT/i8254.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef __I8254_H 3 | #define __I8254_H 4 | 5 | #include 6 | 7 | #include "header/kvm/iodev.h" 8 | 9 | struct kvm_kpit_channel_state { 10 | u32 count; /* can be 65536 */ 11 | u16 latched_count; 12 | u8 count_latched; 13 | u8 status_latched; 14 | u8 status; 15 | u8 read_state; 16 | u8 write_state; 17 | u8 write_latch; 18 | u8 rw_mode; 19 | u8 mode; 20 | u8 bcd; /* not supported */ 21 | u8 gate; /* timer start */ 22 | ktime_t count_load_time; 23 | }; 24 | 25 | struct kvm_kpit_state { 26 | /* All members before "struct mutex lock" are protected by the lock. */ 27 | struct kvm_kpit_channel_state channels[3]; 28 | u32 flags; 29 | bool is_periodic; 30 | s64 period; /* unit: ns */ 31 | struct hrtimer timer; 32 | u32 speaker_data_on; 33 | 34 | struct mutex lock; 35 | atomic_t reinject; 36 | atomic_t pending; /* accumulated triggered timers */ 37 | atomic_t irq_ack; 38 | struct kvm_irq_ack_notifier irq_ack_notifier; 39 | }; 40 | 41 | struct kvm_pit { 42 | struct kvm_io_device dev; 43 | struct kvm_io_device speaker_dev; 44 | struct kvm *kvm; 45 | struct kvm_kpit_state pit_state; 46 | int irq_source_id; 47 | struct kvm_irq_mask_notifier mask_notifier; 48 | struct kthread_worker *worker; 49 | struct kthread_work expired; 50 | }; 51 | 52 | #define KVM_PIT_BASE_ADDRESS 0x40 53 | #define KVM_SPEAKER_BASE_ADDRESS 0x61 54 | #define KVM_PIT_MEM_LENGTH 4 55 | #define KVM_PIT_FREQ 1193181 56 | #define KVM_MAX_PIT_INTR_INTERVAL HZ / 100 57 | #define KVM_PIT_CHANNEL_MASK 0x3 58 | 59 | struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags); 60 | void kvm_free_pit(struct kvm *kvm); 61 | 62 | void kvm_pit_load_count(struct kvm_pit *pit, int channel, u32 val, 63 | int hpet_legacy_start); 64 | void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /KVM-PT/load.sh: -------------------------------------------------------------------------------- 1 | path=$PWD 2 | cp Makefile.template Makefile 3 | sed -i "s|-IPWD|-I"$path"|g" Makefile 4 | make -C /lib/modules/`uname -r`/build M=$PWD 5 | sudo rmmod kvm-pt 2> /dev/null 6 | sudo insmod kvm-pt.ko #pml=n 7 | sudo rmmod kvm-pt 8 | sudo insmod kvm-pt.ko #pml=n 9 | sudo chmod 777 /dev/kvm-pt 10 | -------------------------------------------------------------------------------- /KVM-PT/tss.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef __TSS_SEGMENT_H 3 | #define __TSS_SEGMENT_H 4 | 5 | struct tss_segment_32 { 6 | u32 prev_task_link; 7 | u32 esp0; 8 | u32 ss0; 9 | u32 esp1; 10 | u32 ss1; 11 | u32 esp2; 12 | u32 ss2; 13 | u32 cr3; 14 | u32 eip; 15 | u32 eflags; 16 | u32 eax; 17 | u32 ecx; 18 | u32 edx; 19 | u32 ebx; 20 | u32 esp; 21 | u32 ebp; 22 | u32 esi; 23 | u32 edi; 24 | u32 es; 25 | u32 cs; 26 | u32 ss; 27 | u32 ds; 28 | u32 fs; 29 | u32 gs; 30 | u32 ldt_selector; 31 | u16 t; 32 | u16 io_map; 33 | }; 34 | 35 | struct tss_segment_16 { 36 | u16 prev_task_link; 37 | u16 sp0; 38 | u16 ss0; 39 | u16 sp1; 40 | u16 ss1; 41 | u16 sp2; 42 | u16 ss2; 43 | u16 ip; 44 | u16 flag; 45 | u16 ax; 46 | u16 cx; 47 | u16 dx; 48 | u16 bx; 49 | u16 sp; 50 | u16 bp; 51 | u16 si; 52 | u16 di; 53 | u16 es; 54 | u16 cs; 55 | u16 ss; 56 | u16 ds; 57 | u16 ldt; 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /KVM-PT/usermode_test/.gitignore: -------------------------------------------------------------------------------- 1 | support_test 2 | test 3 | test_loop 4 | test_loop_verbose 5 | test_signal 6 | test_verbose 7 | -------------------------------------------------------------------------------- /KVM-PT/usermode_test/compile.sh: -------------------------------------------------------------------------------- 1 | gcc test.c -D EXECUTE_LOOP_CODE -o test_loop 2 | gcc test.c -o test 3 | gcc test.c -D EXECUTE_LOOP_CODE -D VERBOSE -o test_loop_verbose 4 | gcc test.c -D VERBOSE -o test_verbose 5 | gcc support_test.c -o support_test 6 | gcc test_signal.c -D EXECUTE_LOOP_CODE -o test_signal 7 | -------------------------------------------------------------------------------- /KVM-PT/usermode_test/support_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * KVM-PT userspace support test program 3 | * (c) Sergej Schumilo, 2016 4 | * 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #define KVM_VMX_PT_SUPPORTED _IO(KVMIO, 0xe4) 38 | 39 | int main(){ 40 | int kvm, ret; 41 | 42 | kvm = open("/dev/kvm-pt", O_RDWR | O_CLOEXEC); 43 | if (kvm == -1){ 44 | printf("ERROR: KVM is not loaded!\n"); 45 | exit(1); 46 | } 47 | 48 | ret = ioctl(kvm, KVM_VMX_PT_SUPPORTED, NULL); 49 | if (ret == -1){ 50 | printf("ERROR: KVM-PT is not loaded!\n"); 51 | exit(2); 52 | } 53 | if (ret == -2){ 54 | printf("ERROR: Intel PT is not supported on this CPU!\n"); 55 | exit(3); 56 | } 57 | printf("KVM-PT is ready!\n"); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /KVM-PT/virt/kvm/Kconfig: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0 2 | # KVM common configuration items and defaults 3 | 4 | config HAVE_KVM 5 | bool 6 | 7 | config HAVE_KVM_IRQCHIP 8 | bool 9 | 10 | config HAVE_KVM_IRQFD 11 | bool 12 | 13 | config HAVE_KVM_IRQ_ROUTING 14 | bool 15 | 16 | config HAVE_KVM_EVENTFD 17 | bool 18 | select EVENTFD 19 | 20 | config KVM_MMIO 21 | bool 22 | 23 | config KVM_ASYNC_PF 24 | bool 25 | 26 | # Toggle to switch between direct notification and batch job 27 | config KVM_ASYNC_PF_SYNC 28 | bool 29 | 30 | config HAVE_KVM_MSI 31 | bool 32 | 33 | config HAVE_KVM_CPU_RELAX_INTERCEPT 34 | bool 35 | 36 | config KVM_VFIO 37 | bool 38 | 39 | config HAVE_KVM_ARCH_TLB_FLUSH_ALL 40 | bool 41 | 42 | config HAVE_KVM_INVALID_WAKEUPS 43 | bool 44 | 45 | config KVM_GENERIC_DIRTYLOG_READ_PROTECT 46 | bool 47 | 48 | config KVM_COMPAT 49 | def_bool y 50 | depends on KVM && COMPAT && !(S390 || ARM64) 51 | 52 | config HAVE_KVM_IRQ_BYPASS 53 | bool 54 | 55 | config HAVE_KVM_VCPU_ASYNC_IOCTL 56 | bool 57 | 58 | config HAVE_KVM_VCPU_RUN_PID_CHANGE 59 | bool 60 | -------------------------------------------------------------------------------- /KVM-PT/virt/kvm/async_pf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kvm asynchronous fault support 3 | * 4 | * Copyright 2010 Red Hat, Inc. 5 | * 6 | * Author: 7 | * Gleb Natapov 8 | * 9 | * This file is free software; you can redistribute it and/or modify 10 | * it under the terms of version 2 of the GNU General Public License 11 | * as published by the Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software Foundation, 20 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifndef __KVM_ASYNC_PF_H__ 24 | #define __KVM_ASYNC_PF_H__ 25 | 26 | #ifdef CONFIG_KVM_ASYNC_PF 27 | int kvm_async_pf_init(void); 28 | void kvm_async_pf_deinit(void); 29 | void kvm_async_pf_vcpu_init(struct kvm_vcpu *vcpu); 30 | #else 31 | #define kvm_async_pf_init() (0) 32 | #define kvm_async_pf_deinit() do {} while (0) 33 | #define kvm_async_pf_vcpu_init(C) do {} while (0) 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /KVM-PT/virt/kvm/coalesced_mmio.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef __KVM_COALESCED_MMIO_H__ 3 | #define __KVM_COALESCED_MMIO_H__ 4 | 5 | /* 6 | * KVM coalesced MMIO 7 | * 8 | * Copyright (c) 2008 Bull S.A.S. 9 | * 10 | * Author: Laurent Vivier 11 | * 12 | */ 13 | 14 | #ifdef CONFIG_KVM_MMIO 15 | 16 | #include 17 | 18 | struct kvm_coalesced_mmio_dev { 19 | struct list_head list; 20 | struct kvm_io_device dev; 21 | struct kvm *kvm; 22 | struct kvm_coalesced_mmio_zone zone; 23 | }; 24 | 25 | int kvm_coalesced_mmio_init(struct kvm *kvm); 26 | void kvm_coalesced_mmio_free(struct kvm *kvm); 27 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, 28 | struct kvm_coalesced_mmio_zone *zone); 29 | int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, 30 | struct kvm_coalesced_mmio_zone *zone); 31 | 32 | #else 33 | 34 | static inline int kvm_coalesced_mmio_init(struct kvm *kvm) { return 0; } 35 | static inline void kvm_coalesced_mmio_free(struct kvm *kvm) { } 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /KVM-PT/virt/kvm/vfio.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef __KVM_VFIO_H 3 | #define __KVM_VFIO_H 4 | 5 | #ifdef CONFIG_KVM_VFIO 6 | int kvm_vfio_ops_init(void); 7 | void kvm_vfio_ops_exit(void); 8 | #else 9 | static inline int kvm_vfio_ops_init(void) 10 | { 11 | return 0; 12 | } 13 | static inline void kvm_vfio_ops_exit(void) 14 | { 15 | } 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /KVM-PT/virt/lib/Kconfig: -------------------------------------------------------------------------------- 1 | config IRQ_BYPASS_MANAGER 2 | tristate 3 | -------------------------------------------------------------------------------- /KVM-PT/vmx.h: -------------------------------------------------------------------------------- 1 | #ifndef __VMX_H__ 2 | #define __VMX_H__ 3 | 4 | #include 5 | #include 6 | 7 | struct vcpu_vmx; 8 | void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, u64 guest_val, u64 host_val, bool entry_only); 9 | void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr); 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /KVM-PT/vmx_fdl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel AFL Fast Dirty Page Logging Driver (KVM Extension) 3 | * (c) Sergej Schumilo 2017 - sergej@schumilo.de 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms and conditions of the GNU General Public License, 7 | * version 2, as published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | */ 15 | 16 | #ifndef __VMX_FDL_H__ 17 | #define __VMX_FDL_H__ 18 | 19 | #include "header/uapi/linux/kvm.h" 20 | //#include 21 | #include 22 | #include "header/linux/kvm_host.h" 23 | //#include 24 | 25 | 26 | void vmx_fdl_set_addr_kvm(void* data, u64 gpa); 27 | void vmx_fdl_set_addr_vpcu(void* data, u64 gpa); 28 | void vmx_fdl_setup(void** vmx_fdl_opaque); 29 | int vmx_fdl_create_fd(void* vmx_fdl_opaque); 30 | void vmx_fdl_destroy(void* vmx_fdl_opaque); 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /KVM-PT/vmx_pt.h: -------------------------------------------------------------------------------- 1 | #ifndef __VMX_PT_H__ 2 | #define __VMX_PT_H__ 3 | 4 | #include "vmx.h" 5 | 6 | struct vcpu_vmx_pt; 7 | 8 | 9 | void vmx_pt_toggle_entry(struct vcpu_vmx_pt *vmx_pt_config); 10 | void vmx_pt_toggle_exit(struct vcpu_vmx_pt *vmx_pt_config); 11 | 12 | bool vmx_pt_multi_cr3_enabled(struct vcpu_vmx_pt *vmx_pt_config); 13 | 14 | int vmx_pt_create_fd(struct vcpu_vmx_pt *vmx_pt_config); 15 | 16 | bool vmx_pt_vmentry(struct vcpu_vmx_pt *vmx_pt); 17 | void vmx_pt_vmexit(struct vcpu_vmx_pt *vmx_pt); 18 | 19 | bool topa_full(struct vcpu_vmx_pt *vmx_pt); 20 | 21 | int vmx_pt_setup(struct vcpu_vmx *vmx, struct vcpu_vmx_pt **vmx_pt_config); 22 | void vmx_pt_destroy(struct vcpu_vmx *vmx, struct vcpu_vmx_pt **vmx_pt_config); 23 | 24 | void vmx_pt_init(void); 25 | void vmx_pt_exit(void); 26 | 27 | int vmx_pt_enabled(void); 28 | int vmx_pt_get_addrn_value(void); 29 | 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /KVM-PT/vmx_shadow_fields.h: -------------------------------------------------------------------------------- 1 | #ifndef SHADOW_FIELD_RO 2 | #define SHADOW_FIELD_RO(x) 3 | #endif 4 | #ifndef SHADOW_FIELD_RW 5 | #define SHADOW_FIELD_RW(x) 6 | #endif 7 | 8 | /* 9 | * We do NOT shadow fields that are modified when L0 10 | * traps and emulates any vmx instruction (e.g. VMPTRLD, 11 | * VMXON...) executed by L1. 12 | * For example, VM_INSTRUCTION_ERROR is read 13 | * by L1 if a vmx instruction fails (part of the error path). 14 | * Note the code assumes this logic. If for some reason 15 | * we start shadowing these fields then we need to 16 | * force a shadow sync when L0 emulates vmx instructions 17 | * (e.g. force a sync if VM_INSTRUCTION_ERROR is modified 18 | * by nested_vmx_failValid) 19 | * 20 | * When adding or removing fields here, note that shadowed 21 | * fields must always be synced by prepare_vmcs02, not just 22 | * prepare_vmcs02_full. 23 | */ 24 | 25 | /* 26 | * Keeping the fields ordered by size is an attempt at improving 27 | * branch prediction in vmcs_read_any and vmcs_write_any. 28 | */ 29 | 30 | /* 16-bits */ 31 | SHADOW_FIELD_RW(GUEST_INTR_STATUS) 32 | SHADOW_FIELD_RW(GUEST_PML_INDEX) 33 | SHADOW_FIELD_RW(HOST_FS_SELECTOR) 34 | SHADOW_FIELD_RW(HOST_GS_SELECTOR) 35 | 36 | /* 32-bits */ 37 | SHADOW_FIELD_RO(VM_EXIT_REASON) 38 | SHADOW_FIELD_RO(VM_EXIT_INTR_INFO) 39 | SHADOW_FIELD_RO(VM_EXIT_INSTRUCTION_LEN) 40 | SHADOW_FIELD_RO(IDT_VECTORING_INFO_FIELD) 41 | SHADOW_FIELD_RO(IDT_VECTORING_ERROR_CODE) 42 | SHADOW_FIELD_RO(VM_EXIT_INTR_ERROR_CODE) 43 | SHADOW_FIELD_RW(CPU_BASED_VM_EXEC_CONTROL) 44 | SHADOW_FIELD_RW(EXCEPTION_BITMAP) 45 | SHADOW_FIELD_RW(VM_ENTRY_EXCEPTION_ERROR_CODE) 46 | SHADOW_FIELD_RW(VM_ENTRY_INTR_INFO_FIELD) 47 | SHADOW_FIELD_RW(VM_ENTRY_INSTRUCTION_LEN) 48 | SHADOW_FIELD_RW(TPR_THRESHOLD) 49 | SHADOW_FIELD_RW(GUEST_CS_AR_BYTES) 50 | SHADOW_FIELD_RW(GUEST_SS_AR_BYTES) 51 | SHADOW_FIELD_RW(GUEST_INTERRUPTIBILITY_INFO) 52 | SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE) 53 | 54 | /* Natural width */ 55 | SHADOW_FIELD_RO(EXIT_QUALIFICATION) 56 | SHADOW_FIELD_RO(GUEST_LINEAR_ADDRESS) 57 | SHADOW_FIELD_RW(GUEST_RIP) 58 | SHADOW_FIELD_RW(GUEST_RSP) 59 | SHADOW_FIELD_RW(GUEST_CR0) 60 | SHADOW_FIELD_RW(GUEST_CR3) 61 | SHADOW_FIELD_RW(GUEST_CR4) 62 | SHADOW_FIELD_RW(GUEST_RFLAGS) 63 | SHADOW_FIELD_RW(CR0_GUEST_HOST_MASK) 64 | SHADOW_FIELD_RW(CR0_READ_SHADOW) 65 | SHADOW_FIELD_RW(CR4_READ_SHADOW) 66 | SHADOW_FIELD_RW(HOST_FS_BASE) 67 | SHADOW_FIELD_RW(HOST_GS_BASE) 68 | 69 | /* 64-bit */ 70 | SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS) 71 | SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS_HIGH) 72 | 73 | #undef SHADOW_FIELD_RO 74 | #undef SHADOW_FIELD_RW 75 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0 2 | 3 | ccflags-y += -Iarch/x86/kvm -Iinclude/ -DCONFIG_KVM_VMX_PT -DCONFIG_KVM_VMX_FDL -I/home/kafl/release/KVM-PT 4 | 5 | CFLAGS_x86.o := -I. 6 | CFLAGS_svm.o := -I. 7 | CFLAGS_vmx.o := -I. 8 | 9 | KVM := ./virt/kvm 10 | 11 | 12 | dell-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ 13 | $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o 14 | dell-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o 15 | 16 | dell-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ 17 | i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \ 18 | hyperv.o page_track.o debugfs.o 19 | 20 | 21 | #dell-intel-y += vmx.o pmu_intel.o 22 | #dell-intel-$(CONFIG_KVM_VMX_PT) += vmx_pt.o 23 | #dell-intel-$(CONFIG_KVM_VMX_PT) += vmx_fdl.o 24 | 25 | 26 | dell-y += vmx.o pmu_intel.o 27 | dell-y += vmx_pt.o 28 | dell-y += vmx_fdl.o 29 | 30 | #dell-amd-y += svm.o pmu_amd.o 31 | 32 | obj-$(CONFIG_KVM) += dell.o 33 | #obj-$(CONFIG_KVM_INTEL) += dell-intel.o 34 | #obj-$(CONFIG_KVM_AMD) += dell-amd.o 35 | -------------------------------------------------------------------------------- /QEMU-PT/.gitignore: -------------------------------------------------------------------------------- 1 | qemu/ 2 | -------------------------------------------------------------------------------- /QEMU-PT/compile_qemu_pt.sh: -------------------------------------------------------------------------------- 1 | unzip qemu-4.2.50.zip 2 | patch -p0 < qemu_pt.patch 3 | cd qemu 4 | sh compile.sh 5 | cd - 6 | 7 | -------------------------------------------------------------------------------- /QEMU-PT/qemu-4.2.50.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/QEMU-PT/qemu-4.2.50.zip -------------------------------------------------------------------------------- /Targets/bhyve/.gitignore: -------------------------------------------------------------------------------- 1 | sharedir/hypertrash.iso 2 | sharedir/spec.msgp 3 | config.ron 4 | -------------------------------------------------------------------------------- /Targets/bhyve/VM/.gitignore: -------------------------------------------------------------------------------- 1 | bhyve.qcow2 2 | FreeBSD-11.3-RELEASE-amd64-disc1.iso 3 | 4 | pre_snapshot/INFO.txt 5 | pre_snapshot/fast_snapshot.mem_dump 6 | pre_snapshot/fast_snapshot.mem_meta 7 | pre_snapshot/fast_snapshot.qemu_state 8 | pre_snapshot/fs_cache.meta 9 | pre_snapshot/fs_drv_bhyve.qcow2.khash 10 | pre_snapshot/fs_drv_bhyve.qcow2.pcow 11 | pre_snapshot/global.state 12 | pre_snapshot/ready.lock 13 | -------------------------------------------------------------------------------- /Targets/bhyve/VM/copy_install_files.sh: -------------------------------------------------------------------------------- 1 | scp -P 2222 ../sharedir/kafl_user.h ../agent/src/req_data.c ../agent/src/loader.c ../agent/src/install.sh user@localhost:/home/user/ 2 | 3 | -------------------------------------------------------------------------------- /Targets/bhyve/VM/create_pre_snapshot.sh: -------------------------------------------------------------------------------- 1 | ../../../QEMU-PT/qemu/x86_64-softmmu/qemu-system-x86_64 -hda bhyve.qcow2 -serial mon:stdio -enable-kvm -net none -k de -m 1024 -machine kAFL64-v1 -cpu kAFL64-Hypervisor-v1 -vnc :0 -fast_vm_reload pre_path=pre_snapshot/,load=off 2 | -------------------------------------------------------------------------------- /Targets/bhyve/VM/pre_snapshot/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/bhyve/VM/pre_snapshot/.keep -------------------------------------------------------------------------------- /Targets/bhyve/VM/prepare.sh: -------------------------------------------------------------------------------- 1 | wget https://download.freebsd.org/ftp/releases/ISO-IMAGES/11.3/FreeBSD-11.3-RELEASE-amd64-disc1.iso 2 | 3 | qemu-img create -f qcow2 bhyve.qcow2 20G 4 | 5 | sudo modprobe kvm 6 | sudo modprobe kvm-intel 7 | 8 | sudo chmod 777 /dev/kvm 9 | 10 | qemu-system-x86_64 --enable-kvm -m 1024 -cdrom FreeBSD-11.3-RELEASE-amd64-disc1.iso -k de -hda bhyve.qcow2 -nic user,hostfwd=tcp::2222-:22 -vnc :0 11 | 12 | -------------------------------------------------------------------------------- /Targets/bhyve/agent/bin/loader: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/bhyve/agent/bin/loader -------------------------------------------------------------------------------- /Targets/bhyve/agent/bin/req_data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/bhyve/agent/bin/req_data -------------------------------------------------------------------------------- /Targets/bhyve/agent/bin/set_ip_range: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/bhyve/agent/bin/set_ip_range -------------------------------------------------------------------------------- /Targets/bhyve/agent/bin/set_vmm_ip_range: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/bhyve/agent/bin/set_vmm_ip_range -------------------------------------------------------------------------------- /Targets/bhyve/agent/compile.sh: -------------------------------------------------------------------------------- 1 | mkdir bin/ 2> /dev/null 2 | 3 | printf "\tCompiling Bhyve loader...\n" 4 | clang src/loader.c -I ../ -o bin/loader 5 | 6 | printf "\tCompiling req_data tool...\n" 7 | clang src/req_data.c -I ../ -o bin/req_data 8 | 9 | printf "\tCompiling set_ip_range tool...\n" 10 | clang src/set_ip_range.c -I ../ -o bin/set_ip_range 11 | 12 | printf "\tCompiling set_kvm_ip_range tool...\n" 13 | clang src/set_vmm_ip_range.c -I ../ -o bin/set_vmm_ip_range 14 | -------------------------------------------------------------------------------- /Targets/bhyve/agent/src/install.sh: -------------------------------------------------------------------------------- 1 | cd /home/user 2 | export ASSUME_ALWAYS_YES=yes 3 | yes | pkg install bhyve-firmware 4 | echo "vm.pmap.pti=0" > /boot/loader.conf 5 | clang -I ./ loader.c -o loader 6 | clang -I ./ req_data.c -o req_data 7 | shutdown -h now 8 | -------------------------------------------------------------------------------- /Targets/bhyve/agent/src/req_data.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "kafl_user.h" 5 | #include 6 | 7 | int main(int argc, char** argv){ 8 | 9 | if(argc == 3){ 10 | void* stream_data = mmap((void*)NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 11 | 12 | FILE* f = NULL; 13 | 14 | 15 | uint64_t bytes = 0; 16 | uint64_t total = 0; 17 | 18 | do{ 19 | strcpy(stream_data, argv[1]); 20 | bytes = kAFL_hypercall(HYPERCALL_KAFL_REQ_STREAM_DATA, (uint64_t)stream_data); 21 | 22 | if(bytes == 0xFFFFFFFFFFFFFFFFUL){ 23 | printf("HYPERVISOR: ERROR\n"); 24 | break; 25 | } 26 | 27 | if(f == NULL){ 28 | f = fopen(argv[2], "w+"); 29 | } 30 | 31 | //printf("REQUESTING \"hypertrash.iso\" from hypervisor: %lx\n", bytes); 32 | fwrite(stream_data, 1, bytes, f); 33 | 34 | total += bytes; 35 | 36 | } while(bytes); 37 | 38 | printf("%ld bytes received from hypervisor! (%s)\n", total, argv[1]); 39 | 40 | if(f){ 41 | fclose(f); 42 | return 0; 43 | } 44 | return -1; 45 | 46 | } 47 | printf("Usage: \n"); 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Targets/bhyve/agent/src/run.sh: -------------------------------------------------------------------------------- 1 | chmod +x req_data 2 | du -hs req_data 3 | 4 | ./req_data hypertrash.iso hypertrash.iso 5 | ./req_data hypertrash_crash_detector hypertrash_crash_detector 6 | ./req_data hypertrash_crash_detector_asan hypertrash_crash_detector_asan 7 | ./req_data set_vmm_ip_range set_vmm_ip_range 8 | ./req_data set_ip_range set_ip_range 9 | 10 | chmod +x hypertrash_crash_detector 11 | chmod +x hypertrash_crash_detector_asan 12 | chmod +x set_vnmm_ip_range 13 | chmod +x set_ip_range 14 | 15 | #./set_vmm_ip_range 16 | #./set_ip_range 0x1000 0x7ffffffff000 1 17 | 18 | # disable ASLR 19 | # ASLR is disabled by default ? 20 | 21 | ./set_ip_range 0x1000 0x7ffffffff000 0 22 | 23 | clear 24 | 25 | 26 | bhyvectl --vm=testvm --destroy; 27 | bhyve -w -H -s 0:0,hostbridge -s 1:0,lpc -s 2:0,ahci-cd,hypertrash.iso -l com1,stdio -s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600 -s 30,xhci,tablet -c 1 -m 320M -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CSM.fd testvm 28 | -------------------------------------------------------------------------------- /Targets/bhyve/agent/src/run_asan.sh: -------------------------------------------------------------------------------- 1 | chmod +x req_data 2 | du -hs req_data 3 | 4 | ./req_data hypertrash.iso hypertrash.iso 5 | ./req_data hypertrash_crash_detector hypertrash_crash_detector 6 | ./req_data hypertrash_crash_detector_asan hypertrash_crash_detector_asan 7 | ./req_data set_vmm_ip_range set_vmm_ip_range 8 | ./req_data set_ip_range set_ip_range 9 | 10 | chmod +x hypertrash_crash_detector 11 | chmod +x hypertrash_crash_detector_asan 12 | chmod +x set_vnmm_ip_range 13 | chmod +x set_ip_range 14 | 15 | #./set_vmm_ip_range 16 | #./set_ip_range 0x1000 0x7ffffffff000 1 17 | 18 | # disable ASLR 19 | # ASLR is disabled by default ? 20 | 21 | ./set_ip_range 0x1000 0x7ffffffff000 0 22 | 23 | clear 24 | 25 | 26 | bhyvectl --vm=testvm --destroy; 27 | env LD_PRELOAD=./hypertrash_crash_detector_asan ASAN_OPTIONS=verbosity=1:log_path=/tmp/data.log:abort_on_error=true:detect_leaks=false /usr/src/usr.sbin/bhyve/bhyve.full -w -H -s 0:0,hostbridge -s 1:0,lpc -s 2:0,ahci-cd,hypertrash.iso -l com1,stdio -s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600 -s 30,xhci,tablet -c 1 -m 320M -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CSM.fd testvm 28 | -------------------------------------------------------------------------------- /Targets/bhyve/agent/src/set_ip_range.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "kafl_user.h" 8 | #include 9 | 10 | int main(int argc, char** argv){ 11 | 12 | if(argc == 4){ 13 | uint64_t start = 0; 14 | uint64_t end = 0; 15 | uint64_t range_num = 0; 16 | 17 | start = strtoul(argv[1], NULL, 16); 18 | end = strtoul(argv[2], NULL, 16); 19 | range_num = strtoul(argv[3], NULL, 16); 20 | 21 | printf("RANGE: %lx - %lx\n", start, end), 22 | 23 | assert(range_num <= 3); 24 | assert(start != end && start < end); 25 | 26 | /* lets use our autoconfiguration hypercall */ 27 | uint64_t* range = malloc(sizeof(uint64_t)*3); 28 | memset(range, 0x0, sizeof(uint64_t)*3); 29 | /* userspace */ 30 | range[0] = start; 31 | range[1] = end; 32 | range[2] = range_num; /* range one */ 33 | kAFL_hypercall(HYPERCALL_KAFL_RANGE_SUBMIT, (uintptr_t)range); 34 | 35 | } 36 | else{ 37 | printf("USAGE: IP_A IP_B RANGE\n"); 38 | } 39 | return 1; 40 | } -------------------------------------------------------------------------------- /Targets/bhyve/agent/src/set_vmm_ip_range.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "kafl_user.h" 6 | #include 7 | 8 | static inline bool get_vmm_address(uint64_t* start, uint64_t* end){ 9 | FILE * fp; 10 | char * line = NULL; 11 | uint64_t address = 0x0; 12 | 13 | system("kldstat | grep vmm | cut -d' ' -f7 > /tmp/vmm_start.txt"); 14 | system("kldstat | grep vmm | cut -d' ' -f8 > /tmp/vmm_size.txt"); 15 | 16 | fp = fopen("/tmp/vmm_start.txt", "r"); 17 | if (fp == NULL){ 18 | return false; 19 | } 20 | 21 | line = malloc(20); 22 | memset(line, 0x0, 20); 23 | fread(line, 18, 1, fp); 24 | *start = strtoull(strtok(line, " "), NULL, 16); 25 | free(line); 26 | fclose(fp); 27 | 28 | fp = fopen("/tmp/vmm_size.txt", "r"); 29 | if (fp == NULL){ 30 | return false; 31 | } 32 | 33 | line = malloc(20); 34 | memset(line, 0x0, 20); 35 | fread(line, 18, 1, fp); 36 | uint64_t size = strtoull(strtok(line, " "), NULL, 16); 37 | free(line); 38 | fclose(fp); 39 | 40 | 41 | //printf("%s: %lx %lx (%lx) %lx\n", __func__, *start, *start+size, size, *start+(size + (0x1000-(size)&0xFFF))); 42 | 43 | *end = *start+(size + (0x1000-(size)&0xFFF)); //*start+size; 44 | return true; 45 | } 46 | 47 | int main(int argc, char** argv){ 48 | 49 | uint64_t start_vmm; 50 | uint64_t end_vmm; 51 | get_vmm_address(&start_vmm, &end_vmm); 52 | printf("vmm: %lx-%lx", start_vmm, end_vmm); 53 | 54 | /* lets use our autoconfiguration hypercall */ 55 | uint64_t* range = malloc(sizeof(uint64_t)*3); 56 | memset(range, 0x0, sizeof(uint64_t)*3); 57 | /* userspace */ 58 | range[0] = start_vmm; 59 | range[1] = end_vmm; 60 | range[2] = 0; /* range zero */ 61 | 62 | kAFL_hypercall(HYPERCALL_KAFL_RANGE_SUBMIT, (uintptr_t)range); 63 | } -------------------------------------------------------------------------------- /Targets/bhyve/config_template.ron: -------------------------------------------------------------------------------- 1 | ( 2 | runner: QemuSnapshot(( 3 | qemu_binary: "/home/kafl/release/QEMU-PT/qemu/x86_64-softmmu/qemu-system-x86_64", 4 | hda: "/home/kafl/release/Targets/bhyve/VM/bhyve.qcow2", 5 | sharedir: "/home/kafl/release/Targets/bhyve/sharedir/", 6 | presnapshot: "/home/kafl/release/Targets/bhyve/VM/pre_snapshot/", 7 | snapshot_path: DefaultPath, 8 | //snapshot_path: Reuse("/snapshot"), 9 | debug: false, 10 | )), 11 | fuzz: ( 12 | spec_path: "/home/kafl/release/Targets/bhyve/sharedir/spec.msgp", 13 | workdir_path: "/tmp/workdir_bhyve/", 14 | bitmap_size: 65536, 15 | mem_limit: 1024, 16 | time_limit: ( 17 | secs: 0, 18 | nanos: 800000000, 19 | ), 20 | target_binary: None, 21 | threads: 4, 22 | thread_id: 0, 23 | cpu_pin_start_at: 0, 24 | ), 25 | ) 26 | -------------------------------------------------------------------------------- /Targets/bhyve/sharedir/req_data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/bhyve/sharedir/req_data -------------------------------------------------------------------------------- /Targets/bhyve/sharedir/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | chmod +x req_data 3 | du -hs req_data 4 | 5 | kldload vmm 6 | 7 | ./req_data kafl_user.h kafl_user.h 8 | ./req_data hypertrash.iso hypertrash.iso 9 | ./req_data hypertrash_crash_detector.c hypertrash_crash_detector.c 10 | ./req_data set_vmm_ip_range set_vmm_ip_range 11 | ./req_data set_ip_range.c set_ip_range.c 12 | 13 | clang -I ./ -shared -O0 -m64 -Werror -fPIC ./hypertrash_crash_detector.c -o ./hypertrash_crash_detector -ldl 14 | clang -I ./ -O0 -m64 set_ip_range.c -o set_ip_range 15 | 16 | #./set_vmm_ip_range 17 | #./set_ip_range 0x1000 0x7ffffffff000 1 18 | ./set_ip_range 0x1000 0x100000000 0 19 | 20 | 21 | ifconfig tap0 create 22 | sysctl net.link.tap.up_on_open=1 23 | ifconfig bridge0 create 24 | ifconfig bridge0 addm lo addm tap0 25 | ifconfig bridge0 up 26 | 27 | dd if=/dev/zero of=disk.img bs=1024 count=64 28 | 29 | bhyvectl --vm=testvm --destroy; 30 | 31 | env MALLOC_PERTURB_=255 MALLOC_MMAP_PERTURB_=255 MALLOC_CHECK_=3 LD_PRELOAD=./hypertrash_crash_detector /usr/sbin/bhyve -w -H -s 0:0,hostbridge -s 1:0,lpc -s 2:0,ahci-cd,hypertrash.iso -l com1,stdio -s 3,fbuf,tcp=0.0.0.0:5900,w=800,h=600 -s 4:0,ahci-hd,hd:disk.img -c 1 -m 320M -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CSM.fd testvm 32 | 33 | -------------------------------------------------------------------------------- /Targets/bhyve/sharedir/set_ip_range.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "kafl_user.h" 8 | #include 9 | 10 | int main(int argc, char** argv){ 11 | 12 | if(argc == 4){ 13 | uint64_t start = 0; 14 | uint64_t end = 0; 15 | uint64_t range_num = 0; 16 | 17 | start = strtoul(argv[1], NULL, 16); 18 | end = strtoul(argv[2], NULL, 16); 19 | range_num = strtoul(argv[3], NULL, 16); 20 | 21 | printf("RANGE: %lx - %lx\n", start, end), 22 | 23 | assert(range_num <= 3); 24 | assert(start != end && start < end); 25 | 26 | /* lets use our autoconfiguration hypercall */ 27 | uint64_t* range = malloc(sizeof(uint64_t)*3); 28 | memset(range, 0x0, sizeof(uint64_t)*3); 29 | /* userspace */ 30 | range[0] = start; 31 | range[1] = end; 32 | range[2] = range_num; /* range one */ 33 | kAFL_hypercall(HYPERCALL_KAFL_RANGE_SUBMIT, (uintptr_t)range); 34 | 35 | } 36 | else{ 37 | printf("USAGE: IP_A IP_B RANGE\n"); 38 | } 39 | return 1; 40 | } -------------------------------------------------------------------------------- /Targets/qemu/.gitignore: -------------------------------------------------------------------------------- 1 | agent/bin/hypertrash_crash_detector 2 | agent/bin/hypertrash_crash_detector_asan 3 | agent/bin/loader 4 | agent/bin/req_data 5 | agent/bin/set_ip_range 6 | agent/bin/set_kvm_ip_range 7 | 8 | 9 | sharedir/hypertrash_crash_detector 10 | sharedir/hypertrash_crash_detector_asan 11 | sharedir/req_data 12 | sharedir/run.sh 13 | sharedir/set_ip_range 14 | sharedir/set_kvm_ip_range 15 | sharedir_asan/hypertrash_crash_detector 16 | sharedir_asan/hypertrash_crash_detector_asan 17 | sharedir_asan/req_data 18 | sharedir_asan/run.sh 19 | sharedir_asan/set_ip_range 20 | sharedir_asan/set_kvm_ip_range 21 | 22 | VM/*.iso 23 | VM/*.iso.1 24 | VM/qemu.qcow2 25 | 26 | sharedir/hypertrash.iso 27 | sharedir/spec.msgp 28 | sharedir_asan/hypertrash.iso 29 | sharedir_asan/spec.msgp 30 | 31 | config.ron 32 | -------------------------------------------------------------------------------- /Targets/qemu/VM/.gitignore: -------------------------------------------------------------------------------- 1 | pre_snapshot/fast_snapshot.mem_meta 2 | pre_snapshot/global.state 3 | pre_snapshot/fs_drv_qemu.qcow2.pcow 4 | pre_snapshot/ready.lock 5 | pre_snapshot/fast_snapshot.mem_dump 6 | pre_snapshot/fs_drv_qemu.qcow2.khash 7 | pre_snapshot/INFO.txt 8 | pre_snapshot/fast_snapshot.qemu_state 9 | pre_snapshot/fs_cache.meta 10 | -------------------------------------------------------------------------------- /Targets/qemu/VM/copy_install_files.sh: -------------------------------------------------------------------------------- 1 | 2 | cd ../agent 3 | sh compile.sh 4 | cd - 5 | scp -P 2223 ../agent/bin/loader ../misc/grub.cfg ../misc/install.sh ../misc/sources.list user@localhost:/home/user/ 6 | 7 | 8 | -------------------------------------------------------------------------------- /Targets/qemu/VM/create_pre_snapshot.sh: -------------------------------------------------------------------------------- 1 | mkdir -p pre_snapshot 2 | ../../../QEMU-PT/qemu/x86_64-softmmu/qemu-system-x86_64 -hda qemu.qcow2 -serial mon:stdio -enable-kvm -net none -k de -m 1024 -machine kAFL64-v1 -cpu kAFL64-Hypervisor-v1 -vnc :0 -fast_vm_reload pre_path=pre_snapshot/,load=off 3 | -------------------------------------------------------------------------------- /Targets/qemu/VM/prepare.sh: -------------------------------------------------------------------------------- 1 | wget http://old-releases.ubuntu.com/releases/18.04.4/ubuntu-18.04.4-live-server-amd64.iso 2 | 3 | qemu-img create -f qcow2 qemu.qcow2 20G 4 | 5 | sudo modprobe kvm 6 | sudo modprobe kvm-intel 7 | 8 | sudo chmod 777 /dev/kvm 9 | 10 | qemu-system-x86_64 --enable-kvm -m 1024 -cdrom ubuntu-18.04.4-live-server-amd64.iso -k de -hda qemu.qcow2 -nic user,hostfwd=tcp::2223-:22 -vnc :0 11 | 12 | -------------------------------------------------------------------------------- /Targets/qemu/agent/bin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/qemu/agent/bin/.keep -------------------------------------------------------------------------------- /Targets/qemu/agent/build_sharedir.sh: -------------------------------------------------------------------------------- 1 | mkdir ../sharedir 2 | mkdir ../sharedir_asan 3 | 4 | bash compile.sh 5 | cp bin/req_data ../sharedir/req_data 6 | cp bin/hypertrash_crash_detector ../sharedir/hypertrash_crash_detector 7 | cp bin/hypertrash_crash_detector_asan ../sharedir/hypertrash_crash_detector_asan 8 | cp bin/set_ip_range ../sharedir/set_ip_range 9 | cp bin/set_kvm_ip_range ../sharedir/set_kvm_ip_range 10 | cp src/run.sh ../sharedir/run.sh 11 | cp bin/req_data ../sharedir/req_data 12 | 13 | cp bin/req_data ../sharedir_asan/req_data 14 | cp bin/hypertrash_crash_detector ../sharedir_asan/hypertrash_crash_detector 15 | cp bin/hypertrash_crash_detector_asan ../sharedir_asan/hypertrash_crash_detector_asan 16 | cp bin/set_ip_range ../sharedir_asan/set_ip_range 17 | cp bin/set_kvm_ip_range ../sharedir_asan/set_kvm_ip_range 18 | cp src/run_asan.sh ../sharedir_asan/run.sh 19 | cp bin/req_data ../sharedir_asan/req_data 20 | 21 | -------------------------------------------------------------------------------- /Targets/qemu/agent/compile.sh: -------------------------------------------------------------------------------- 1 | mkdir bin/ 2> /dev/null 2 | 3 | printf "\tCompiling QEMU/KVM loader...\n" 4 | gcc src/loader.c -I ./ -o bin/loader 5 | 6 | printf "\tCompiling req_data tool...\n" 7 | gcc src/req_data.c -I ./ -o bin/req_data 8 | 9 | printf "\tCompiling set_ip_range tool...\n" 10 | gcc src/set_ip_range.c -I ./ -o bin/set_ip_range 11 | 12 | printf "\tCompiling set_kvm_ip_range tool...\n" 13 | gcc src/set_kvm_ip_range.c -I ./ -o bin/set_kvm_ip_range 14 | 15 | printf "\tCompiling hypertrash_crash_detector...\n" 16 | gcc -I./ -shared -O0 -m64 -Werror -fPIC src/hypertrash_crash_detector.c -o bin/hypertrash_crash_detector -ldl 17 | 18 | printf "\tCompiling hypertrash_crash_detector_asan...\n" 19 | gcc -I./ -shared -O0 -m64 -Werror -fPIC src/hypertrash_crash_detector_asan.c -o bin/hypertrash_crash_detector_asan -ldl 20 | -------------------------------------------------------------------------------- /Targets/qemu/agent/src/req_data.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "kafl_user.h" 5 | #include 6 | 7 | int main(int argc, char** argv){ 8 | 9 | if(argc == 3){ 10 | void* stream_data = mmap((void*)NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 11 | 12 | FILE* f = NULL; 13 | 14 | 15 | uint64_t bytes = 0; 16 | uint64_t total = 0; 17 | 18 | do{ 19 | strcpy(stream_data, argv[1]); 20 | bytes = kAFL_hypercall(HYPERCALL_KAFL_REQ_STREAM_DATA, (uint64_t)stream_data); 21 | 22 | if(bytes == 0xFFFFFFFFFFFFFFFFUL){ 23 | printf("HYPERVISOR: ERROR\n"); 24 | break; 25 | } 26 | 27 | if(f == NULL){ 28 | f = fopen(argv[2], "w+"); 29 | } 30 | 31 | //printf("REQUESTING \"hypertrash.iso\" from hypervisor: %lx\n", bytes); 32 | fwrite(stream_data, 1, bytes, f); 33 | 34 | total += bytes; 35 | 36 | } while(bytes); 37 | 38 | printf("%ld bytes received from hypervisor! (%s)\n", total, argv[1]); 39 | 40 | if(f){ 41 | fclose(f); 42 | return 0; 43 | } 44 | return -1; 45 | 46 | } 47 | printf("Usage: \n"); 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Targets/qemu/agent/src/run.sh: -------------------------------------------------------------------------------- 1 | chmod +x req_data 2 | du -hs req_data 3 | sha1sum req_data 4 | 5 | ./req_data hypertrash.iso hypertrash.iso 6 | ./req_data hypertrash_crash_detector hypertrash_crash_detector 7 | ./req_data hypertrash_crash_detector_asan hypertrash_crash_detector_asan 8 | ./req_data set_kvm_ip_range set_kvm_ip_range 9 | ./req_data set_ip_range set_ip_range 10 | 11 | chmod +x hypertrash_crash_detector 12 | chmod +x hypertrash_crash_detector_asan 13 | chmod +x set_kvm_ip_range 14 | chmod +x set_ip_range 15 | 16 | #./set_kvm_ip_range 17 | #./set_ip_range 0x1000 0x7ffffffff000 1 18 | 19 | # disable ASLR 20 | echo 0 > /proc/sys/kernel/randomize_va_space 21 | 22 | ./set_ip_range 0x1000 0x7ffffffff000 0 23 | 24 | echo 0 > /proc/sys/kernel/printk 25 | 26 | clear 27 | 28 | LD_PRELOAD=./hypertrash_crash_detector qemu-system-x86_64 -nographic -cdrom hypertrash.iso -m 100 -enable-kvm -device virtio-gpu-pci -device nec-usb-xhci -nographic 29 | 30 | -------------------------------------------------------------------------------- /Targets/qemu/agent/src/run_asan.sh: -------------------------------------------------------------------------------- 1 | chmod +x req_data 2 | du -hs req_data 3 | sha1sum req_data 4 | 5 | ./req_data hypertrash.iso hypertrash.iso 6 | ./req_data hypertrash_crash_detector hypertrash_crash_detector 7 | ./req_data hypertrash_crash_detector_asan hypertrash_crash_detector_asan 8 | ./req_data set_kvm_ip_range set_kvm_ip_range 9 | ./req_data set_ip_range set_ip_range 10 | 11 | chmod +x hypertrash_crash_detector 12 | chmod +x hypertrash_crash_detector_asan 13 | chmod +x set_kvm_ip_range 14 | chmod +x set_ip_range 15 | 16 | #./set_kvm_ip_range 17 | #./set_ip_range 0x1000 0x7ffffffff000 1 18 | 19 | # disable ASLR 20 | echo 0 > /proc/sys/kernel/randomize_va_space 21 | 22 | ./set_ip_range 0x1000 0x6ffffffff000 0 23 | 24 | echo 0 > /proc/sys/kernel/printk 25 | 26 | 27 | clear 28 | 29 | LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.4:./hypertrash_crash_detector ASAN_OPTIONS=abort_on_error=true:detect_leaks=false /home/user/qemu-4.2.0/x86_64-softmmu/qemu-system-x86_64 -cdrom hypertrash.iso -enable-kvm -net none -nographic -device nec-usb-xhci 2> /tmp/data.log -------------------------------------------------------------------------------- /Targets/qemu/agent/src/set_ip_range.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "kafl_user.h" 8 | #include 9 | 10 | int main(int argc, char** argv){ 11 | 12 | if(argc == 4){ 13 | uint64_t start = 0; 14 | uint64_t end = 0; 15 | uint64_t range_num = 0; 16 | 17 | start = strtoul(argv[1], NULL, 16); 18 | end = strtoul(argv[2], NULL, 16); 19 | range_num = strtoul(argv[3], NULL, 16); 20 | 21 | printf("RANGE: %lx - %lx\n", start, end), 22 | 23 | assert(range_num <= 3); 24 | assert(start != end && start < end); 25 | 26 | /* lets use our autoconfiguration hypercall */ 27 | uint64_t* range = malloc(sizeof(uint64_t)*3); 28 | memset(range, 0x0, sizeof(uint64_t)*3); 29 | /* userspace */ 30 | range[0] = start; 31 | range[1] = end; 32 | range[2] = range_num; /* range one */ 33 | kAFL_hypercall(HYPERCALL_KAFL_RANGE_SUBMIT, (uintptr_t)range); 34 | 35 | } 36 | else{ 37 | printf("USAGE: IP_A IP_B RANGE\n"); 38 | } 39 | return 1; 40 | } -------------------------------------------------------------------------------- /Targets/qemu/agent/src/set_kvm_ip_range.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "kafl_user.h" 6 | #include 7 | 8 | static inline bool get_kvm_address(uint64_t* start, uint64_t* end){ 9 | FILE * fp; 10 | char * line = NULL; 11 | uint64_t address = 0x0; 12 | 13 | uint64_t kvm_start = 0; 14 | uint64_t kvm_size = 0; 15 | uint64_t kvm_intel_start = 0; 16 | uint64_t kvm_intel_size = 0; 17 | 18 | system("cat /proc/modules | grep 'kvm ' | cut -d' ' -f6 > /tmp/kvm_start.txt"); 19 | system("cat /proc/modules | grep 'kvm ' | cut -d' ' -f2 > /tmp/kvm_size.txt"); 20 | 21 | system("cat /proc/modules | grep 'kvm_intel ' | cut -d' ' -f6 > /tmp/kvm_intel_start.txt"); 22 | system("cat /proc/modules | grep 'kvm_intel ' | cut -d' ' -f2 > /tmp/kvm_intel_size.txt"); 23 | 24 | 25 | fp = fopen("/tmp/kvm_start.txt", "r"); 26 | if (fp == NULL){ 27 | return false; 28 | } 29 | 30 | line = malloc(20); 31 | memset(line, 0x0, 20); 32 | fread(line, 18, 1, fp); 33 | kvm_start = strtoull(strtok(line, " "), NULL, 16); 34 | free(line); 35 | fclose(fp); 36 | 37 | fp = fopen("/tmp/kvm_size.txt", "r"); 38 | if (fp == NULL){ 39 | return false; 40 | } 41 | 42 | line = malloc(20); 43 | memset(line, 0x0, 20); 44 | fread(line, 18, 1, fp); 45 | kvm_size = strtoull(strtok(line, " "), NULL, 10); 46 | free(line); 47 | fclose(fp); 48 | 49 | 50 | fp = fopen("/tmp/kvm_intel_start.txt", "r"); 51 | if (fp == NULL){ 52 | return false; 53 | } 54 | 55 | line = malloc(20); 56 | memset(line, 0x0, 20); 57 | fread(line, 18, 1, fp); 58 | kvm_intel_start = strtoull(strtok(line, " "), NULL, 16); 59 | free(line); 60 | fclose(fp); 61 | 62 | fp = fopen("/tmp/kvm_intel_size.txt", "r"); 63 | if (fp == NULL){ 64 | return false; 65 | } 66 | 67 | line = malloc(20); 68 | memset(line, 0x0, 20); 69 | fread(line, 18, 1, fp); 70 | kvm_intel_size = strtoull(strtok(line, " "), NULL, 10); 71 | free(line); 72 | fclose(fp); 73 | 74 | printf("kvm: %lx - %lx\n", kvm_start, kvm_start+kvm_size); 75 | 76 | printf("kvm-intel: %lx - %lx\n", kvm_intel_start, kvm_intel_start+kvm_intel_size); 77 | 78 | if(kvm_start > kvm_intel_start){ 79 | *start = kvm_intel_start; 80 | *end = kvm_start+kvm_size; 81 | } 82 | else{ 83 | *start = kvm_start; 84 | *end = kvm_intel_start+kvm_intel_size; 85 | } 86 | 87 | printf("START: %lx\n", *start); 88 | printf("END: %lx\n", *end); 89 | 90 | return true; 91 | } 92 | 93 | int main(int argc, char** argv){ 94 | 95 | uint64_t start_vmm; 96 | uint64_t end_vmm; 97 | get_kvm_address(&start_vmm, &end_vmm); 98 | printf("kvm: %lx-%lx", start_vmm, end_vmm); 99 | 100 | /* lets use our autoconfiguration hypercall */ 101 | uint64_t* range = malloc(sizeof(uint64_t)*3); 102 | memset(range, 0x0, sizeof(uint64_t)*3); 103 | /* userspace */ 104 | range[0] = start_vmm; 105 | range[1] = end_vmm; 106 | range[2] = 0; /* range zero */ 107 | 108 | kAFL_hypercall(HYPERCALL_KAFL_RANGE_SUBMIT, (uintptr_t)range); 109 | } -------------------------------------------------------------------------------- /Targets/qemu/config_template.ron: -------------------------------------------------------------------------------- 1 | ( 2 | runner: QemuSnapshot(( 3 | qemu_binary: "/home/kafl/release/QEMU-PT/qemu/x86_64-softmmu/qemu-system-x86_64", 4 | hda: "/home/kafl/release/Targets/qemu/VM/qemu.qcow2", 5 | sharedir: "/home/kafl/release/Targets/qemu/sharedir_asan/", 6 | presnapshot: "/home/kafl/release/Targets/qemu/VM/pre_snapshot/", 7 | snapshot_path: DefaultPath, 8 | //snapshot_path: Reuse("/snapshot"), 9 | debug: false, 10 | )), 11 | fuzz: ( 12 | spec_path: "/home/kafl/release/Targets/qemu/sharedir_asan/spec.msgp", 13 | workdir_path: "/tmp/workdir_bhyve/", 14 | bitmap_size: 65536, 15 | mem_limit: 1024, 16 | time_limit: ( 17 | secs: 0, 18 | nanos: 800000000, 19 | ), 20 | target_binary: None, 21 | threads: 4, 22 | thread_id: 0, 23 | cpu_pin_start_at: 0, 24 | ), 25 | ) 26 | -------------------------------------------------------------------------------- /Targets/qemu/misc/grub.cfg: -------------------------------------------------------------------------------- 1 | GRUB_DEFAULT=0 2 | GRUB_TIMEOUT_STYLE=hidden 3 | GRUB_TIMEOUT=0 4 | GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` 5 | #GRUB_CMDLINE_LINUX_DEFAULT="maybe-ubiquity" 6 | GRUB_CMDLINE_LINUX_DEFAULT="nokaslr oops=panic nopti" 7 | GRUB_CMDLINE_LINUX="" 8 | -------------------------------------------------------------------------------- /Targets/qemu/misc/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ $EUID -ne 0 ]]; then 3 | echo "This script must be run as root" 4 | exit 1 5 | fi 6 | 7 | cp sources.list /etc/apt/sources.list 8 | 9 | apt-get update 10 | apt-get install qemu-system gcc -y 11 | apt-get build-dep qemu-system -y 12 | 13 | wget https://download.qemu.org/qemu-4.2.0.tar.xz 14 | 15 | tar xf qemu-4.2.0.tar.xz 16 | cd qemu-4.2.0 17 | 18 | ./configure --target-list=x86_64-softmmu --disable-werror --disable-capstone --enable-sanitizers 19 | make 20 | 21 | cd - 22 | 23 | modprobe kvm 24 | modprobe kvm-intel 25 | 26 | cp grub.cfg /etc/default/grub 27 | 28 | update-grub 29 | 30 | shutdown -h now 31 | -------------------------------------------------------------------------------- /Targets/qemu/misc/sources.list: -------------------------------------------------------------------------------- 1 | deb http://de.archive.ubuntu.com/ubuntu bionic main restricted 2 | deb-src http://de.archive.ubuntu.com/ubuntu bionic main restricted 3 | deb http://de.archive.ubuntu.com/ubuntu bionic-updates main restricted 4 | deb-src http://de.archive.ubuntu.com/ubuntu bionic-updates main restricted 5 | deb http://de.archive.ubuntu.com/ubuntu bionic universe 6 | deb-src http://de.archive.ubuntu.com/ubuntu bionic universe 7 | deb http://de.archive.ubuntu.com/ubuntu bionic-updates universe 8 | deb-src http://de.archive.ubuntu.com/ubuntu bionic-updates universe 9 | 10 | -------------------------------------------------------------------------------- /Targets/qemu/sharedir/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/qemu/sharedir/.keep -------------------------------------------------------------------------------- /Targets/qemu/sharedir_asan/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/Targets/qemu/sharedir_asan/.keep -------------------------------------------------------------------------------- /nyx_fuzzer/.gitignore: -------------------------------------------------------------------------------- 1 | hypertrash_spec/build/hypertrash_os/iso/hypertrash_os_bios.iso 2 | .vscode 3 | syzkaller_spec/__pycache__/ 4 | syzkaller_spec/build/cdrom_agent 5 | -------------------------------------------------------------------------------- /nyx_fuzzer/config/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /nyx_fuzzer/config/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "config" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "serde", 8 | "serde_derive", 9 | ] 10 | 11 | [[package]] 12 | name = "proc-macro2" 13 | version = "1.0.12" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" 16 | dependencies = [ 17 | "unicode-xid", 18 | ] 19 | 20 | [[package]] 21 | name = "quote" 22 | version = "1.0.4" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" 25 | dependencies = [ 26 | "proc-macro2", 27 | ] 28 | 29 | [[package]] 30 | name = "serde" 31 | version = "1.0.110" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" 34 | 35 | [[package]] 36 | name = "serde_derive" 37 | version = "1.0.110" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" 40 | dependencies = [ 41 | "proc-macro2", 42 | "quote", 43 | "syn", 44 | ] 45 | 46 | [[package]] 47 | name = "syn" 48 | version = "1.0.19" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "e8e5aa70697bb26ee62214ae3288465ecec0000f05182f039b477001f08f5ae7" 51 | dependencies = [ 52 | "proc-macro2", 53 | "quote", 54 | "unicode-xid", 55 | ] 56 | 57 | [[package]] 58 | name = "unicode-xid" 59 | version = "0.2.0" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 62 | -------------------------------------------------------------------------------- /nyx_fuzzer/config/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "config" 3 | version = "0.1.0" 4 | authors = ["coco "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde ="1.0.104" 11 | serde_derive ="1.0.104" -------------------------------------------------------------------------------- /nyx_fuzzer/config/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate serde; 2 | #[macro_use] 3 | extern crate serde_derive; 4 | 5 | use std::time::Duration; 6 | 7 | #[derive(Clone, Serialize, Deserialize)] 8 | pub struct QemuKernelConfig { 9 | pub qemu_binary: String, 10 | pub target_pack: String, 11 | pub kernel: String, 12 | pub ramfs: String, 13 | pub debug: bool, 14 | } 15 | 16 | #[derive(Clone, Serialize, Deserialize)] 17 | pub enum SnapshotPath { 18 | Reuse(String), 19 | Create(String), 20 | DefaultPath, 21 | } 22 | 23 | #[derive(Clone, Serialize, Deserialize)] 24 | pub struct QemuSnapshotConfig { 25 | pub qemu_binary: String, 26 | pub hda: String, 27 | pub sharedir: String, 28 | pub presnapshot: String, 29 | pub snapshot_path: SnapshotPath, 30 | pub debug: bool, 31 | } 32 | 33 | #[derive(Clone, Serialize, Deserialize)] 34 | pub struct ForkServerConfig { 35 | pub args: Vec, 36 | pub hide_output: bool, 37 | pub input_size: usize, 38 | pub env: Vec, 39 | } 40 | 41 | #[derive(Clone, Serialize, Deserialize)] 42 | pub enum FuzzRunnerConfig { 43 | QemuKernel(QemuKernelConfig), 44 | QemuSnapshot(QemuSnapshotConfig), 45 | ForkServer(ForkServerConfig), 46 | } 47 | 48 | #[derive(Clone, Serialize, Deserialize)] 49 | pub struct FuzzerConfig { 50 | pub spec_path: String, 51 | pub workdir_path: String, 52 | pub bitmap_size: usize, 53 | pub mem_limit: usize, 54 | pub time_limit: Duration, 55 | pub target_binary: Option, 56 | pub threads: usize, 57 | pub thread_id: usize, 58 | pub cpu_pin_start_at: usize, 59 | } 60 | 61 | #[derive(Clone, Serialize, Deserialize)] 62 | pub struct Config { 63 | pub runner: FuzzRunnerConfig, 64 | pub fuzz: FuzzerConfig, 65 | } 66 | -------------------------------------------------------------------------------- /nyx_fuzzer/fuzz_runner/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /nyx_fuzzer/fuzz_runner/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fuzz_runner" 3 | version = "0.1.0" 4 | authors = ["coco "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | nix = "0.17.0" 11 | time = "0.2.9" 12 | subprocess = "0.2.4" 13 | regex = "1.3.6" 14 | lazy_static = "1.4.0" 15 | libc = "0.2.68" 16 | quick-error = "*" 17 | tempfile = "3.1.0" 18 | rand = "0.7.3" 19 | serde_derive = "1.0" 20 | serde = "1.0" 21 | byteorder = "*" 22 | snafu = "0.6.3" 23 | timeout-readwrite = "0.3.1" 24 | glob="0.3.0" 25 | hex="0.4.2" 26 | config={path="../config"} -------------------------------------------------------------------------------- /nyx_fuzzer/fuzz_runner/src/exitreason.rs: -------------------------------------------------------------------------------- 1 | use nix::sys::wait::WaitStatus; 2 | 3 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] 4 | pub enum ExitReason { 5 | Normal(i32), 6 | Timeout, 7 | Signaled(i32), 8 | Crash(Vec), 9 | Asan, 10 | Stopped(i32), 11 | FuzzerError, 12 | InvalidWriteToPayload(Vec), 13 | } 14 | 15 | impl ExitReason { 16 | pub fn from_wait_status(status: WaitStatus) -> ExitReason { 17 | return match status { 18 | WaitStatus::Exited(_, return_value) => ExitReason::Normal(return_value), 19 | WaitStatus::Signaled(_, signal, _) => ExitReason::Signaled(signal as i32), 20 | WaitStatus::Stopped(_, signal) => ExitReason::Stopped(signal as i32), 21 | _ => panic!("Unknown WaitStatus: {:?}", status), 22 | }; 23 | } 24 | 25 | pub fn is_normal(&self) -> bool{ 26 | use ExitReason::*; 27 | match self { 28 | Normal(_) => return true, 29 | _ => return false, 30 | } 31 | } 32 | 33 | pub fn name(&self) -> &str{ 34 | use ExitReason::*; 35 | match self { 36 | Normal(_) => return "normal", 37 | Timeout => return "timeout", 38 | Signaled(_) => return "signal", 39 | Crash(_) => return "crash", 40 | Asan => return "asan", 41 | Stopped(_) => return "stop", 42 | InvalidWriteToPayload(_) => return "invalid_write_to_payload_buffer", 43 | FuzzerError => unreachable!(), 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nyx_fuzzer/fuzz_runner/src/forksrv/error.rs: -------------------------------------------------------------------------------- 1 | use nix; 2 | use std; 3 | 4 | quick_error! { 5 | #[derive(Debug, Clone)] 6 | pub enum SpawnError { 7 | Fork(err: nix::Error) { 8 | from() 9 | description("execve failed") 10 | display("execve error: {}", err) 11 | cause(err) 12 | } 13 | Path(desc: String){ 14 | description("Invalid Path") 15 | display("Problem with binary path: {}", desc) 16 | } 17 | 18 | Exec(desc: String){ 19 | description("Execution Failed") 20 | display("Execution failed: {}", desc) 21 | } 22 | 23 | FFINull(err: std::ffi::NulError) { 24 | from() 25 | description("argument/path contained Null byte") 26 | display("Null error: {}", err) 27 | cause(err) 28 | } 29 | DevNull(desc: String){ 30 | description("failed to open /dev/null") 31 | display("failed to open /dev/null: {}", desc) 32 | } 33 | } 34 | } 35 | 36 | pub fn path_err(desc: &str) -> Result { 37 | return Err(SpawnError::Path(desc.into())); 38 | } 39 | 40 | quick_error! { 41 | #[derive(Debug)] 42 | pub enum SubprocessError { 43 | Spawn(err: SpawnError) { 44 | from() 45 | description("spawning failed") 46 | display("spawning failed: {}", err) 47 | cause(err) 48 | } 49 | Unspecific(desc: String){ 50 | description("Subprocess Failed") 51 | display("Subprocess failed: {}", desc) 52 | } 53 | Io(err: std::io::Error){ 54 | from() 55 | cause(err) 56 | } 57 | Unix(err: nix::Error){ 58 | from() 59 | cause(err) 60 | } 61 | } 62 | } 63 | 64 | pub fn descr_err(desc: &str) -> Result { 65 | return Err(SubprocessError::Unspecific(desc.into())); 66 | } 67 | -------------------------------------------------------------------------------- /nyx_fuzzer/fuzz_runner/src/forksrv/newtypes.rs: -------------------------------------------------------------------------------- 1 | use snafu::{Backtrace, Snafu}; 2 | 3 | use std::path::PathBuf; 4 | 5 | #[derive(Debug, Snafu)] 6 | #[snafu(visibility = "pub")] 7 | pub enum SubprocessError { 8 | #[snafu(display("Could not handle qemu trace file to {} {}", path.display(), source))] 9 | ReadQemuTrace { 10 | path: PathBuf, 11 | source: std::io::Error, 12 | }, 13 | 14 | #[snafu(display("Could not parse integer in {} {}", line, source))] 15 | ParseIntQemuTrace { 16 | line: String, 17 | source: std::num::ParseIntError, 18 | }, 19 | 20 | #[snafu(display("Could not parse line {}", line))] 21 | ParseLineQemuTrace { line: String, backtrace: Backtrace }, 22 | 23 | #[snafu(display("Qemu did not produce any output"))] 24 | NoQemuOutput { backtrace: Backtrace }, 25 | 26 | #[snafu(display("Could not communicate with QemuForkServer {} {} ", task, source))] 27 | QemuRunNix { task: String, source: nix::Error }, 28 | 29 | #[snafu(display("Could not communicate with QemuForkServer {} {} ", task, source))] 30 | QemuRunIO { 31 | task: String, 32 | source: std::io::Error, 33 | }, 34 | 35 | #[snafu(display("Could not disassemble {}", task))] 36 | DisassemblyError { task: String, backtrace: Backtrace }, 37 | } 38 | -------------------------------------------------------------------------------- /nyx_fuzzer/fuzz_runner/src/nyx/mem_barrier.rs: -------------------------------------------------------------------------------- 1 | use std::sync::atomic::compiler_fence; 2 | use std::sync::atomic::Ordering; 3 | 4 | // we expect this to be a nop. 5 | // but in some extreme cases, this 6 | /* 7 | use std::sync::atomic::compiler_fence; 8 | use std::sync::atomic::Ordering; 9 | 10 | fn barrier() { 11 | compiler_fence(Ordering::SeqCst); 12 | } 13 | 14 | pub fn read2(data: &mut u32) -> u32{ 15 | let a = *data; 16 | barrier(); 17 | let b = *data; 18 | return a.wrapping_add(b); 19 | } 20 | */ 21 | 22 | //compiles to 23 | /* 24 | mov eax, dword ptr [rdi] 25 | add eax, dword ptr [rdi] 26 | ret 27 | */ 28 | //while the second access gets optimized out without the barrier. 29 | //To ensure that reads/writes to the shared memory buffer actually are executed, we use mem_barrier to lightweight synchronize the values. 30 | 31 | pub fn mem_barrier() { 32 | compiler_fence(Ordering::SeqCst); 33 | } 34 | -------------------------------------------------------------------------------- /nyx_fuzzer/helpers/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /nyx_fuzzer/helpers/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "helpers" 3 | version = "0.1.0" 4 | authors = ["coco "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | nix="0.17.0" 11 | -------------------------------------------------------------------------------- /nyx_fuzzer/helpers/src/hash_by_ref.rs: -------------------------------------------------------------------------------- 1 | use std::rc::Rc; 2 | use std::ptr; 3 | use std::hash::{Hash,Hasher}; 4 | 5 | #[derive(Clone,Debug)] 6 | pub struct HashAsRef(Rc); 7 | 8 | impl Hash for HashAsRef { 9 | fn hash(&self, state: &mut H) { 10 | let ptr: *const T = &*self.0; 11 | ptr::hash(ptr, state); 12 | } 13 | } 14 | 15 | impl PartialEq for HashAsRef { 16 | fn eq(&self, other: &Self) -> bool { 17 | Rc::ptr_eq(&self.0, &other.0) 18 | } 19 | } 20 | impl Eq for HashAsRef {} 21 | 22 | impl HashAsRef{ 23 | pub fn new(rc: Rc) -> Self{ 24 | return Self(rc); 25 | } 26 | pub fn into_rc(self) -> Rc{ 27 | self.0 28 | } 29 | pub fn as_usize(&self) -> usize{ 30 | let ptr: *const T = &*self.0; 31 | return ptr as usize; 32 | } 33 | } -------------------------------------------------------------------------------- /nyx_fuzzer/helpers/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate nix; 2 | 3 | use core::ffi::c_void; 4 | use nix::sys::mman::*; 5 | use std::fs::{File, OpenOptions}; 6 | use std::os::unix::io::IntoRawFd; 7 | 8 | mod hash_by_ref; 9 | pub use hash_by_ref::HashAsRef; 10 | 11 | pub fn make_shared_data_from_path(path: &str, size: usize) -> &'static mut[u8] { 12 | let data_shm_f = OpenOptions::new() 13 | .create(true) 14 | .read(true) 15 | .write(true) 16 | .open(path) 17 | .expect("couldn't open input file"); 18 | data_shm_f.set_len(size as u64).unwrap(); 19 | return make_shared_data_from_file(data_shm_f, size); 20 | } 21 | 22 | pub fn make_shared_data_from_file(file: File, size: usize) -> &'static mut [u8] { 23 | let prot = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE; 24 | let flags = MapFlags::MAP_SHARED; 25 | unsafe { 26 | let ptr = mmap(0 as *mut c_void, size, prot, flags, file.into_raw_fd(), 0).unwrap(); 27 | 28 | let data = std::slice::from_raw_parts_mut(ptr as *mut u8, size); 29 | return data; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/.gitignore: -------------------------------------------------------------------------------- 1 | *.msgp 2 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/.gitignore: -------------------------------------------------------------------------------- 1 | bytecode_spec.h 2 | bytecode_spec.template.h 3 | data_include.h 4 | interpreter.h 5 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/.gitignore: -------------------------------------------------------------------------------- 1 | src/*.o 2 | src/asm/*.o 3 | bin/hypertrash_os.bin 4 | bin/logo.o 5 | tesseract/*.o 6 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # HyperCube OS 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU Affero General Public License as 6 | # published by the Free Software Foundation, either version 3 of the 7 | # License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Affero General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Affero General Public License 15 | # along with this program. If not, see . 16 | # 17 | # 18 | 19 | 20 | AS=as --32 21 | CC=gcc-8 -m32 22 | 23 | CFLAGS=-c -std=gnu99 -ffreestanding -O1 -Wall -Wextra -static -DHYPERTRASH -DLOOP 24 | LDFLAGS=-T misc/linker.ld -ffreestanding -O1 -nostdlib -static 25 | LIBS= 26 | INCLUDE=-Iinclude -Itesseract 27 | 28 | AS_SOURCES= src/asm/boot.s src/asm/cpu_tables.s src/asm/ap_boot.s 29 | AS_OBJECTS=$(AS_SOURCES:.s=.o) 30 | 31 | SOURCES=src/kernel.c src/libk.c src/serial.c src/tty.c src/gdt.c src/idt.c src/isr.c src/pci.c src/panic.c src/msr.c src/acpi.c src/cpuid.c src/apic.c src/pic.c src/mboot.c src/efi.c src/mem.c src/smp.c src/fuzz.c src/isa.c tesseract/core.c tesseract/state.c tesseract/opcodes.c tesseract/decompiler.c tesseract/dict.c src/hypercube_opcodes.c 32 | OBJECTS=$(SOURCES:.c=.o) bin/logo.o 33 | 34 | .PHONY: all clean run 35 | 36 | all: clean misc/linker.ld $(AS_SOURCES) $(SOURCES) hypertrash_os.bin 37 | 38 | bin/logo.o: 39 | objcopy -I binary -O elf32-i386 -B i386 misc/logo.bmp bin/logo.o 40 | 41 | bin/payload.o: 42 | objcopy -I binary -O elf32-i386 -B i386 misc/crash.hexa bin/payload.o 43 | 44 | hypertrash_os_crash.bin: CFLAGS := $(CFLAGS) -DPAYLOAD 45 | hypertrash_os_crash.bin: $(AS_OBJECTS) $(OBJECTS) bin/payload.o 46 | $(CC) $(LDFLAGS) -o bin/hypertrash_os.bin $(AS_OBJECTS) $(OBJECTS) bin/payload.o $(LIBS) 47 | rm -rf isofiles/ 48 | mkdir isofiles 49 | mkdir isofiles/boot 50 | mkdir isofiles/boot/grub 51 | cp misc/grub.cfg isofiles/boot/grub/ 52 | cp bin/hypertrash_os.bin isofiles/boot/kernel.bin 53 | ./grub/bios/bin/grub-mkrescue --xorriso=./xorriso -d ./grub/bios/lib/grub/i386-pc/ -o iso/hypertrash_os_bios_crash.iso --install-modules='normal multiboot2' --locales= --themes=None --modules= --fonts= isofiles 54 | rm -r isofiles/ 55 | 56 | hypertrash_os.bin: $(AS_OBJECTS) $(OBJECTS) 57 | $(CC) $(LDFLAGS) -o bin/hypertrash_os.bin $(AS_OBJECTS) $(OBJECTS) $(LIBS) 58 | rm -rf isofiles/ 59 | mkdir isofiles 60 | mkdir isofiles/boot 61 | mkdir isofiles/boot/grub 62 | cp misc/grub.cfg isofiles/boot/grub/ 63 | cp bin/hypertrash_os.bin isofiles/boot/kernel.bin 64 | ./grub/bios/bin/grub-mkrescue --xorriso=./xorriso -d ./grub/bios/lib/grub/i386-pc/ -o iso/hypertrash_os_bios.iso --install-modules='normal multiboot2' --locales= --themes=None --modules= --fonts= isofiles 65 | rm -r isofiles/ 66 | 67 | .s.o: 68 | $(AS) $< -o $@ 69 | 70 | .c.o: 71 | $(CC) $(CFLAGS) $< -o $@ $(INCLUDE) 72 | 73 | clean: 74 | rm -rf isofiles/ 75 | rm -f $(AS_OBJECTS) 76 | rm -f $(OBJECTS) 77 | rm -f bin/hypertrash_os.bin 78 | rm -f iso/hypertrash_os_bios.iso 79 | rm -f iso/hypertrash_os_efi.iso 80 | rm -f iso/hypertrash_os_efi_app.iso 81 | rm -f serial.txt 82 | rm -f bin/payload.o 83 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/bin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/hypervisor_spec/build/hypertrash_os/bin/.keep -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/grub/.gitignore: -------------------------------------------------------------------------------- 1 | bios 2 | efi 3 | efi_app 4 | grub-2.02 5 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/grub/grub.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/hypervisor_spec/build/hypertrash_os/grub/grub.zip -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/grub/install.sh: -------------------------------------------------------------------------------- 1 | GRUB_VERSION="2.02" 2 | GRUB_URL="ftp://ftp.gnu.org//gnu/grub/grub-2.02.tar.gz" 3 | GRUB_MD5="1116d1f60c840e6dbd67abbc99acb45d" 4 | PWD_BIOS=$(pwd)/bios/ 5 | PWD_EFI=$(pwd)/efi/ 6 | PWD_EFI_APP=$(pwd)/efi_app/ 7 | 8 | echo "[*] Installing build dependencies for GRUB2 $GRUB_VERSION ..." 9 | sudo -Eu root apt-get build-dep grub2 -y > /dev/null 10 | 11 | echo "[*] Downloading GRUB2 $GRUB_VERSION ..." 12 | wget -O grub.tar.gz $GRUB_URL 2> /dev/null 13 | 14 | echo "[*] Checking signature of GRUB2 $GRUB_VERSION ..." 15 | CHKSUM=`md5sum grub.tar.gz| cut -d' ' -f1` 16 | 17 | if [ "$CHKSUM" != "$GRUB_MD5" ]; then 18 | echo "[-] Error: signature mismatch..." 19 | exit 1 20 | fi 21 | 22 | echo "[*] Unpacking GRUB2 $GRUB_VERSION ..." 23 | tar xf grub.tar.gz 24 | 25 | echo "[*] Compiling GRUB2 $GRUB_VERSION BIOS bootloader ..." 26 | cd grub-2.02/ 27 | CFLAGS=-Wno-error=unused-value ./autogen.sh 28 | CFLAGS=-Wno-error=unused-value ./configure --target=i386 --with-platform="pc" --prefix=$PWD_BIOS 29 | CFLAGS=-Wno-error=unused-value make -j 8 30 | make install 31 | make clean 32 | cd .. 33 | 34 | rm -rf ./grub-2.02/ 35 | rm -f grub.tar.gz 36 | echo "[*] Done ..." 37 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/grub/patches/kern_efi_mm.patch: -------------------------------------------------------------------------------- 1 | 154c154 2 | < grub_efi_boot_services_t *b; 3 | --- 4 | > //grub_efi_boot_services_t *b; 5 | 184a185 6 | > /* 7 | 187a189,190 8 | > */ 9 | > status = GRUB_EFI_SUCCESS; 10 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/grub/patches/loader_multiboot.patch: -------------------------------------------------------------------------------- 1 | 233c233 2 | < grub_puts_ (N_("WARNING: no console will be available to OS")); 3 | --- 4 | > //grub_puts_ (N_("WARNING: no console will be available to OS")); 5 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/grub/patches/video_video.patch: -------------------------------------------------------------------------------- 1 | 595,596c595,597 2 | < return grub_error (GRUB_ERR_BAD_ARGUMENT, 3 | < N_("no suitable video mode found")); 4 | --- 5 | > return GRUB_ERR_BAD_ARGUMENT; 6 | > //return grub_error (GRUB_ERR_BAD_ARGUMENT, 7 | > // N_("no suitable video mode found")); 8 | 759,760c760,762 9 | < return grub_error (GRUB_ERR_BAD_ARGUMENT, 10 | < N_("no suitable video mode found")); 11 | --- 12 | > return GRUB_ERR_BAD_ARGUMENT; 13 | > //return grub_error (GRUB_ERR_BAD_ARGUMENT, 14 | > // N_("no suitable video mode found")); 15 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/bmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "system.h" 22 | 23 | #pragma pack(push, 1) 24 | 25 | typedef struct tagBITMAPFILEHEADER 26 | { 27 | uint16_t bfType; 28 | uint32_t bfSize; 29 | uint16_t bfReserved1; 30 | uint16_t bfReserved2; 31 | uint32_t bOffBits; 32 | }BITMAPFILEHEADER; 33 | 34 | #pragma pack(pop) 35 | 36 | #pragma pack(push, 1) 37 | 38 | typedef struct tagBITMAPINFOHEADER 39 | { 40 | uint32_t biSize; 41 | int32_t biWidth; 42 | int32_t biHeight; 43 | uint16_t biPlanes; 44 | uint16_t biBitCount; 45 | uint32_t biCompression; 46 | uint32_t biSizeImage; 47 | int32_t biXPelsPerMeter; 48 | int32_t biYPelsPerMeter; 49 | uint32_t biClrUsed; 50 | uint32_t biClrImportant; 51 | }BITMAPINFOHEADER; 52 | 53 | #pragma pack(pop) -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #define ENABLE_TTY_SERIAL 22 | #define ENABLE_TTY_VGA 23 | #define EARLY_BOOT_PRINTF 24 | 25 | 26 | #define PANIC_AUTO_REBOOT 27 | 28 | //#define IO_FUZZING 29 | #define PCI_FUZZING 30 | //#define EXTENDED_PCI_FUZZING 31 | //#define APIC_FUZZING 32 | //#define HPET_FUZZING 33 | 34 | //#define SEED 0xf3cafc34 35 | 36 | //#define FILTER "PCI/PCI-Express Bridge" 37 | //#define FILTER "VGA" 38 | //#define FILTER "Ethernet" -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/efi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | 24 | //http://elixir.free-electrons.com/linux/v4.6/source/include/linux/efi.h#L117 25 | //http://elixir.free-electrons.com/linux/v4.6/source/arch/x86/platform/efi/efi.c 26 | 27 | #define EFI_PAGE_SHIFT 12 28 | #define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT) 29 | 30 | typedef struct { 31 | uint32_t type; 32 | uint32_t pad1; 33 | uint32_t phys_addr_a; 34 | uint32_t phys_addr_b; 35 | uint32_t virt_addr_a; 36 | uint32_t virt_addr_b; 37 | uint32_t num_pages_a; 38 | uint32_t num_pages_b; 39 | uint32_t attribute_a; 40 | uint32_t attribute_b; 41 | uint64_t pad2; 42 | } efi_memory_desc_t; 43 | 44 | 45 | struct efi_table_header{ 46 | uint32_t signature_low; 47 | uint32_t signature_high; 48 | uint32_t revision; 49 | uint32_t size; 50 | uint32_t crc32; 51 | uint32_t reserved; 52 | }; 53 | 54 | struct efi_system_table{ 55 | struct efi_table_header eth; 56 | uint8_t* firmware_vendor; 57 | uint32_t firmware_revision; 58 | uintptr_t console_stdin_handle; 59 | uintptr_t con_in; 60 | uintptr_t console_stdout_handle; 61 | uintptr_t con_out; 62 | uintptr_t console_stderr_handle; 63 | uintptr_t con_err; 64 | uintptr_t runtime_services; 65 | uintptr_t boot_services; 66 | uint64_t num_of_entries; 67 | uintptr_t efi_config_table; 68 | }; 69 | 70 | void efi_parse_est32(uintptr_t est_ptr); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/fuzz.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | // 21 | #include 22 | #include "state.h" 23 | 24 | //#include 25 | // 26 | typedef struct { 27 | state_t* hexa_state; 28 | uintptr_t address_page; 29 | volatile uintptr_t payload_buffer; 30 | }fuzzer_state_t; 31 | 32 | fuzzer_state_t* new_fuzzer(void); 33 | void destroy_fuzzer(fuzzer_state_t* self); 34 | void register_area(fuzzer_state_t* self, uintptr_t base_address, uint32_t size, bool mmio, char* description); 35 | //void start_fuzzing(volatile fuzzer_state_t* self); 36 | 37 | void init_hprintf(void); 38 | uint8_t* prepare_fuzzing(volatile fuzzer_state_t* self); 39 | void start_fuzzing(uint8_t* payload_buffer, size_t payload_size); 40 | void exec_hprintf_str(char* buffer); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #define outb(__value,__port) asm volatile ("outb %%al, %%dx"::"a"(__value),"d"(__port)) 22 | #define outw(__value,__port) asm volatile ("outw %%ax, %%dx"::"a"(__value),"d"(__port)) 23 | #define outl(__value,__port) asm volatile ("outl %%eax, %%dx"::"a"(__value),"d"(__port)) 24 | 25 | #define inb(__port) \ 26 | ({ \ 27 | uint8_t __data; \ 28 | asm volatile ("inb %%dx,%%al":"=a"(__data):"d"(__port)); \ 29 | __data; \ 30 | }) 31 | 32 | #define inw(__port) \ 33 | ({ \ 34 | uint16_t __data; \ 35 | asm volatile ("inw %%dx,%%ax":"=a"(__data):"d"(__port)); \ 36 | __data; \ 37 | }) 38 | 39 | #define inl(__port) \ 40 | ({ \ 41 | uint32_t __data; \ 42 | asm volatile ("inl %%dx,%%eax":"=a"(__data):"d"(__port)); \ 43 | __data; \ 44 | }) 45 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/isa.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "fuzz.h" 22 | void isa_state_enum(fuzzer_state_t* fuzzer); 23 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/libk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "system.h" 22 | #include "cpuid.h" 23 | 24 | //#define MEMCPY_DEBUG 25 | 26 | void microdelay(uint32_t us); 27 | 28 | typedef __builtin_va_list va_list; 29 | #ifndef va_start 30 | #define va_start(ap,last) __builtin_va_start(ap, last) 31 | #define va_end(ap) __builtin_va_end(ap) 32 | #define va_arg(ap,type) __builtin_va_arg(ap,type) 33 | #define va_copy(dest, src) __builtin_va_copy(dest,src) 34 | #endif 35 | 36 | size_t vasprintf(char * buf, const char *fmt, va_list args); 37 | int sprintf(char * buf, const char *fmt, ...); 38 | 39 | size_t strlen(const char* str); 40 | void memcpy(void* dst, void* src, size_t len); 41 | void* memset(void* dst, int c, size_t len); 42 | 43 | char* dump_cpuid(); 44 | int raise_gpf(); 45 | void abort(void); 46 | void assert(bool cond); 47 | void assert2(bool cond, const char* reason); 48 | 49 | void hexdump (char *desc, void *addr, int len); 50 | 51 | int strcmp(const char *str1, const char *str2); 52 | size_t vsnprintf(char * buf, size_t n, const char *fmt, va_list args); 53 | 54 | char* strncpy(char* dst, const char* src, size_t num); 55 | 56 | /* 57 | static inline uint64_t rdtsc() 58 | { 59 | uint64_t ret; 60 | asm volatile ( "rdtsc" : "=A"(ret) ); 61 | return ret; 62 | } 63 | */ 64 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/mbootv1.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "system.h" 5 | 6 | #define MULTIBOOT_MAGIC 0x1BADB002 7 | #define MULTIBOOT_EAX_MAGIC 0x2BADB002 8 | #define MULTIBOOT_FLAG_MEM 0x001 9 | #define MULTIBOOT_FLAG_DEVICE 0x002 10 | #define MULTIBOOT_FLAG_CMDLINE 0x004 11 | #define MULTIBOOT_FLAG_MODS 0x008 12 | #define MULTIBOOT_FLAG_AOUT 0x010 13 | #define MULTIBOOT_FLAG_ELF 0x020 14 | #define MULTIBOOT_FLAG_MMAP 0x040 15 | #define MULTIBOOT_FLAG_CONFIG 0x080 16 | #define MULTIBOOT_FLAG_LOADER 0x100 17 | #define MULTIBOOT_FLAG_APM 0x200 18 | #define MULTIBOOT_FLAG_VBE 0x400 19 | 20 | struct multiboot 21 | { 22 | uintptr_t flags; 23 | uintptr_t mem_lower; 24 | uintptr_t mem_upper; 25 | uintptr_t boot_device; 26 | uintptr_t cmdline; 27 | uintptr_t mods_count; 28 | uintptr_t mods_addr; 29 | uintptr_t num; 30 | uintptr_t size; 31 | uintptr_t addr; 32 | uintptr_t shndx; 33 | uintptr_t mmap_length; 34 | uintptr_t mmap_addr; 35 | uintptr_t drives_length; 36 | uintptr_t drives_addr; 37 | uintptr_t config_table; 38 | uintptr_t boot_loader_name; 39 | uintptr_t apm_table; 40 | uintptr_t vbe_control_info; 41 | uintptr_t vbe_mode_info; 42 | uintptr_t vbe_mode; 43 | uintptr_t vbe_interface_seg; 44 | uintptr_t vbe_interface_off; 45 | uintptr_t vbe_interface_len; 46 | } __attribute__ ((packed)); 47 | 48 | typedef struct { 49 | uint16_t attributes; 50 | uint8_t winA, winB; 51 | uint16_t granularity; 52 | uint16_t winsize; 53 | uint16_t segmentA, segmentB; 54 | uint32_t realFctPtr; 55 | uint16_t pitch; 56 | 57 | uint16_t Xres, Yres; 58 | uint8_t Wchar, Ychar, planes, bpp, banks; 59 | uint8_t memory_model, bank_size, image_pages; 60 | uint8_t reserved0; 61 | 62 | uint8_t red_mask, red_position; 63 | uint8_t green_mask, green_position; 64 | uint8_t blue_mask, blue_position; 65 | uint8_t rsv_mask, rsv_position; 66 | uint8_t directcolor_attributes; 67 | 68 | uint32_t physbase; 69 | uint32_t reserved1; 70 | uint16_t reserved2; 71 | } __attribute__ ((packed)) vbe_info_t; 72 | 73 | typedef struct { 74 | uintptr_t mod_start; 75 | uintptr_t mod_end; 76 | uintptr_t cmdline; 77 | uintptr_t reserved; 78 | } __attribute__ ((packed)) mboot_mod_t; 79 | 80 | typedef struct { 81 | uint32_t size; 82 | uint32_t base_addr_a; 83 | uint32_t base_addr_b; 84 | uint32_t length_a; 85 | uint32_t length_b; 86 | uint32_t type; 87 | } __attribute__ ((packed)) mboot_memmap_t; 88 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "system.h" 22 | 23 | typedef struct page { 24 | unsigned int present:1; 25 | unsigned int rw:1; 26 | unsigned int user:1; 27 | unsigned int writethrough:1; 28 | unsigned int cachedisable:1; 29 | unsigned int unused:7; 30 | unsigned int frame:20; 31 | } __attribute__((packed)) page_t; 32 | 33 | typedef struct page_table { 34 | page_t pages[1024]; 35 | } page_table_t; 36 | 37 | typedef struct page_directory { 38 | uintptr_t physical_tables[1024]; /* Physical addresses of the tables */ 39 | page_table_t *tables[1024]; /* 1024 pointers to page tables... */ 40 | uintptr_t physical_address; /* The physical address of physical_tables */ 41 | int32_t ref_count; 42 | } page_directory_t; 43 | 44 | void kfree(void* page); 45 | 46 | void* malloc(size_t size); 47 | 48 | void* kmalloc(size_t size); 49 | void* kvmalloc(size_t size); 50 | void* kmalloc_p(size_t size, uintptr_t* phys); 51 | void* kvmalloc_p(size_t size, uintptr_t* phys); 52 | 53 | void* pmalloc(size_t size); 54 | void* pvmalloc(size_t size); 55 | void* pmalloc_p(size_t size, uintptr_t* phys); 56 | void* pvmalloc_p(size_t size, uintptr_t* phys); 57 | 58 | 59 | void mem_set_low_high(uintptr_t mboot_low_mem, uintptr_t mboot_high_mem); 60 | void mem_set_e820_mmap(uintptr_t e820_mmap_ptr, uint32_t entries); 61 | void mem_set_efi_mmap(uintptr_t efi_mmap_ptr); 62 | 63 | uintptr_t mem_alloc_ap_stack(void); 64 | void mem_set_ap_cr3(void); 65 | bool mem_init(void); 66 | void* virtual_map(uintptr_t page, size_t size); 67 | 68 | void print_mem_stats(void); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/mmio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | static inline uint8_t mmio_read8(uint32_t __base, uint32_t __offset){ 22 | return *(volatile uint8_t *)(__base + __offset); 23 | } 24 | 25 | static inline uint16_t mmio_read16(uint32_t __base, uint32_t __offset){ 26 | return *(volatile uint16_t *)(__base + __offset); 27 | } 28 | 29 | static inline uint32_t mmio_read32(uint32_t __base, uint32_t __offset){ 30 | return *(volatile uint32_t *)(__base + __offset); 31 | } 32 | 33 | static inline uint64_t mmio_read64(uint32_t __base, uint32_t __offset){ 34 | return *(volatile uint64_t *)(__base + __offset); 35 | } 36 | 37 | static inline void mmio_write8(uint32_t __base, uint32_t __offset, uint8_t data){ 38 | *(volatile uint8_t *)(__base + __offset) = data; 39 | } 40 | 41 | static inline void mmio_write16(uint32_t __base, uint32_t __offset, uint16_t data){ 42 | *(volatile uint16_t *)(__base + __offset) = data; 43 | } 44 | 45 | static inline void mmio_write32(uint32_t __base, uint32_t __offset, uint32_t data){ 46 | *(volatile uint32_t *)(__base + __offset) = data; 47 | } 48 | 49 | static inline void mmio_write64(uint32_t __base, uint32_t __offset, uint64_t data){ 50 | *(volatile uint64_t *)(__base + __offset) = data; 51 | } 52 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/msr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #ifndef MSR_H 20 | #define MSR_H 21 | 22 | #include 23 | #include 24 | 25 | #define IA32_APIC_BASE 0x0000001b 26 | #define IA32_EFER 0xc0000080 27 | 28 | 29 | void rdmsr32(uint32_t msr, uint32_t *lo, uint32_t *hi); 30 | void wrmsr32(uint32_t msr, uint32_t lo, uint32_t hi); 31 | 32 | uint64_t rdmsr64(uint32_t msr); 33 | void wrmsr64(uint32_t msr, uint64_t value); 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/panic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #ifndef PANIC_H 20 | #define PANIC_H 21 | 22 | #include "system.h" 23 | 24 | void panic_isr(struct regs* r); 25 | void panic_handler(struct regs* r); 26 | 27 | #endif -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/pic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #define IRQ_BASE 0x20 25 | 26 | #define PIC1_CMD 0x0020 27 | #define PIC1_DATA 0x0021 28 | #define PIC2_CMD 0x00a0 29 | #define PIC2_DATA 0x00a1 30 | 31 | #define ICW1_ICW4 0x01 32 | #define ICW1_SINGLE 0x02 33 | #define ICW1_ADI 0x04 34 | #define ICW1_LTIM 0x08 35 | #define ICW1_INIT 0x10 36 | 37 | #define ICW4_8086 0x01 38 | #define ICW4_AUTO 0x02 39 | #define ICW4_BUF_SLAVE 0x04 40 | #define ICW4_BUF_MASTER 0x0C 41 | #define ICW4_SFNM 0x10 42 | 43 | #define PIC_EOI 0x20 44 | 45 | #define PIC_READ_IRR 0x0a 46 | #define PIC_READ_ISR 0x0b 47 | 48 | #define PIC_DISABLE 0xff 49 | 50 | void pic_eoi(uint8_t irq); 51 | bool pci_interrupt_pending(uint8_t irq); 52 | void pic_irq_ack(uint8_t irq); 53 | bool pic_spurious_irq(uint8_t irq); 54 | void pic_disable(void); 55 | void pic_init(void); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | /* credits: wiki.osdev.org, syssec.rub.de (angry_os) */ 20 | 21 | #pragma once 22 | 23 | #include "system.h" 24 | 25 | #define SERIAL_PORT_A 0x3F8 26 | #define SERIAL_PORT_B 0x2F8 27 | #define SERIAL_PORT_C 0x3E8 28 | #define SERIAL_PORT_D 0x2E8 29 | 30 | void serial_enable(int device); 31 | 32 | int serial_rcvd(int device); 33 | char serial_recv(int device); 34 | char serial_recv_async(int device); 35 | int serial_recv_string(int device, char* buf, int size); 36 | 37 | int serial_transmit_empty(int device); 38 | void serial_send(int device, char out); 39 | void serial_send_string(int device, char * out); 40 | int serial_printf(int device, const char* fmt, ...); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/smp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #define AP_INIT_ADDRESS 0x9000 24 | 25 | void smp_increase_aps(void); 26 | void smp_boot_ack(void); 27 | void smp_init(void); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/system.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | #define UNUSED(x) (void)(x) 27 | 28 | #define SYSCALL_VECTOR 0x7F 29 | 30 | struct regs { 31 | unsigned int gs, fs, es, ds; 32 | unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; 33 | unsigned int int_no, err_code; 34 | unsigned int eip, cs, eflags, useresp, ss; 35 | }; 36 | 37 | typedef struct regs regs_t; 38 | 39 | typedef void (*irq_handler_t) (struct regs *); 40 | 41 | #define PAUSE { asm volatile ("hlt"); } 42 | #define STOP while (1) { PAUSE; } 43 | 44 | /* GDT */ 45 | extern void gdt_install(void); 46 | extern void gdt_set_gate(uint8_t num, uint64_t base, uint64_t limit, uint8_t access, uint8_t gran); 47 | 48 | /* IDT */ 49 | extern void idt_install(void); 50 | extern void idt_set_gate(uint8_t num, void (*base)(void), uint16_t sel, uint8_t flags); 51 | 52 | /* ISRS */ 53 | extern void isrs_install(void); 54 | extern void isrs_install_handler(size_t isrs, irq_handler_t); 55 | extern void isrs_uninstall_handler(size_t isrs); 56 | 57 | extern void* kernel_end; -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #ifndef TEST_H 20 | #define TEST_H 21 | 22 | enum test_type { 23 | TEST_DIV_BY_ZERO, 24 | TEST_PAGE_FAULT, 25 | TEST_PCI_MMIO, 26 | TEST_PCI_IO, 27 | TEST_MSR, 28 | TEST_SMEP, 29 | TEST_CVE_2015_3456, 30 | TEST_CVE_2011_1751, 31 | TEST_IO 32 | }; 33 | 34 | void test(enum test_type id); 35 | 36 | #endif -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/tty.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "system.h" 22 | #include "vga.h" 23 | 24 | #ifdef SHARKOS 25 | #define DEFAULT_COLOR vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_WHITE) 26 | #else 27 | #define DEFAULT_COLOR vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_LIGHT_BLUE) 28 | #endif 29 | 30 | #define SUCCESS_COLOR vga_entry_color(VGA_COLOR_LIGHT_GREEN, VGA_COLOR_LIGHT_BLUE) 31 | #define FAIL_COLOR vga_entry_color(VGA_COLOR_LIGHT_RED, VGA_COLOR_LIGHT_BLUE) 32 | #define CRASH_COLOR vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_RED) 33 | 34 | #define printf(...) tty_printf(__VA_ARGS__); 35 | 36 | void tty_initialize(uint8_t default_terminal_color); 37 | 38 | void tty_setcolor(uint8_t color); 39 | void tty_setpos(size_t column, size_t row); 40 | 41 | void tty_writestring(const char* data); 42 | int tty_printf(const char* fmt, ...); 43 | 44 | void tty_drawbmp(uint8_t* data); 45 | void enable_printf(void); 46 | void disable_printf(void); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/include/vga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "system.h" 22 | 23 | enum vga_color { 24 | VGA_COLOR_BLACK = 0, 25 | VGA_COLOR_BLUE = 1, 26 | VGA_COLOR_GREEN = 2, 27 | VGA_COLOR_CYAN = 3, 28 | VGA_COLOR_RED = 4, 29 | VGA_COLOR_MAGENTA = 5, 30 | VGA_COLOR_BROWN = 6, 31 | VGA_COLOR_LIGHT_GREY = 7, 32 | VGA_COLOR_DARK_GREY = 8, 33 | VGA_COLOR_LIGHT_BLUE = 9, 34 | VGA_COLOR_LIGHT_GREEN = 10, 35 | VGA_COLOR_LIGHT_CYAN = 11, 36 | VGA_COLOR_LIGHT_RED = 12, 37 | VGA_COLOR_LIGHT_MAGENTA = 13, 38 | VGA_COLOR_LIGHT_BROWN = 14, 39 | VGA_COLOR_WHITE = 15, 40 | }; 41 | 42 | static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { 43 | return fg | bg << 4; 44 | } 45 | 46 | static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { 47 | return (uint16_t) uc | (uint16_t) color << 8; 48 | } 49 | 50 | static const size_t VGA_WIDTH = 80; 51 | static const size_t VGA_HEIGHT = 25; 52 | 53 | static uint16_t* const VGA_MEMORY = (uint16_t*)0xB8000; -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/iso/hypertrash_os_bios.iso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/hypervisor_spec/build/hypertrash_os/iso/hypertrash_os_bios.iso -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/misc/crash.hexa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/hypervisor_spec/build/hypertrash_os/misc/crash.hexa -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/misc/grub.cfg: -------------------------------------------------------------------------------- 1 | set gfxmode=1024x768 2 | set gfxpayload=1024x768 3 | set timeout=0 4 | 5 | set default=0 6 | 7 | menuentry "HyperCubeOS" { 8 | gfxpayload=1024x768 9 | multiboot2 /boot/kernel.bin 10 | } 11 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/misc/linker.ld: -------------------------------------------------------------------------------- 1 | /* credits: wiki.osdev.org, syssec.rub.de (angry_os) */ 2 | 3 | /* The bootloader will look at this image and start execution at the symbol 4 | designated as the entry point. */ 5 | ENTRY(_start) 6 | 7 | /* Tell where the various sections of the object files will be put in the final 8 | kernel image. */ 9 | SECTIONS 10 | { 11 | /* Begin putting sections at 1 MiB, a conventional place for kernels to be 12 | loaded at by the bootloader. */ 13 | . = 1M; 14 | 15 | /* First put the multiboot header, as it is required to be put very early 16 | early in the image or the bootloader won't recognize the file format. 17 | Next we'll put the .text section. */ 18 | .text BLOCK(4K) : ALIGN(4K) 19 | { 20 | *(.text) 21 | } 22 | 23 | /* Read-only data. */ 24 | .rodata BLOCK(4K) : ALIGN(4K) 25 | { 26 | *(.rodata) 27 | } 28 | 29 | /* Read-write data (initialized) */ 30 | .data BLOCK(4K) : ALIGN(4K) 31 | { 32 | *(.data) 33 | } 34 | 35 | /* Read-write data (uninitialized) and stack */ 36 | .bss BLOCK(4K) : ALIGN(4K) 37 | { 38 | *(COMMON) 39 | *(.bss) 40 | *(.stack) 41 | } 42 | 43 | /* Pointer to end of binary */ 44 | kernel_end=.; 45 | 46 | 47 | /* The compiler may produce other sections, by default it will put them in 48 | a segment with the same name. Simply add stuff here as needed. */ 49 | 50 | /DISCARD/ : 51 | { 52 | *(.comment) 53 | *(.eh_frame) 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/misc/logo.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/hypervisor_spec/build/hypertrash_os/misc/logo.bmp -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/asm/ap_boot.s: -------------------------------------------------------------------------------- 1 | .globl __ap_boot 2 | 3 | .align 4096 4 | .code16 5 | 6 | .extern ap_main 7 | .type ap_main, @function 8 | 9 | __ap_boot: 10 | cli /* welcome in real mode */ 11 | 12 | mov %cs, %ax 13 | mov %ax, %ds 14 | 15 | lgdtl __gdt_Ptr - __ap_boot + 2 16 | 17 | mov %cr0, %eax 18 | or $1, %eax 19 | mov %eax, %cr0 20 | 21 | ljmpl $0x8, $1f /* switch to protected mode */ 22 | 23 | .code32 24 | 25 | 1: 26 | mov $0x10, %eax 27 | mov %ax, %ds 28 | mov %ax, %es 29 | mov %ax, %fs 30 | mov %ax, %gs 31 | mov %ax, %ss 32 | 33 | mov ap_stack, %esp 34 | call ap_main 35 | 36 | __gdt_Ptr: 37 | .long 0xFFFF0000 38 | .long gdt /* reuse the BSP GDT */ -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/asm/boot.s: -------------------------------------------------------------------------------- 1 | /* credits: wiki.osdev.org, syssec.rub.de (angry_os) */ 2 | 3 | multiboot_header: 4 | .long 0xe85250d6 /* magic */ 5 | .long 0 /* ISA: i386 */ 6 | .long multiboot_header_end - multiboot_header /* Header length. */ 7 | .long -(0xe85250d6 + (multiboot_header_end - multiboot_header)) /* checksum */ 8 | .short 0 9 | .short 0 10 | .long 8 11 | multiboot_header_end: 12 | 13 | /* .stack resides in .bss */ 14 | .section .stack, "aw", @nobits 15 | stack_bottom: 16 | .skip 16384 /* 16KiB */ 17 | stack_top: 18 | 19 | .section .text 20 | 21 | .global _start 22 | .type _start, @function 23 | 24 | 25 | .extern kernel_main 26 | .type kernel_main, @function 27 | 28 | .extern printf 29 | .type tty_printf, @function 30 | 31 | _start: 32 | /* Setup our stack */ 33 | mov $stack_top, %esp 34 | 35 | /* Make sure our stack is 16-byte aligned */ 36 | and $-16, %esp 37 | 38 | pushl %esp 39 | pushl %eax /* Multiboot header magic */ 40 | pushl %ebx /* Multiboot header pointer */ 41 | 42 | cli 43 | call kernel_main 44 | 45 | cli 46 | pushl $halt_message 47 | call tty_printf 48 | hang: 49 | hlt 50 | jmp hang 51 | 52 | halt_message: 53 | .asciz "Halted." 54 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/asm/boot_v2.s: -------------------------------------------------------------------------------- 1 | 2 | multiboot_header: 3 | .long 0xe85250d6 /* magic */ 4 | .long 0 /* ISA: i386 */ 5 | .long multiboot_header_end - multiboot_header /* Header length. */ 6 | .long -(0xe85250d6 + (multiboot_header_end - multiboot_header)) /* checksum */ 7 | .short 0 8 | .short 0 9 | .long 8 10 | multiboot_header_end: 11 | 12 | /* .stack resides in .bss */ 13 | .section .stack, "aw", @nobits 14 | stack_bottom: 15 | .skip 16384 /* 16KiB */ 16 | stack_top: 17 | 18 | .section .text 19 | 20 | .global _start 21 | .type _start, @function 22 | 23 | 24 | .extern kernel_main 25 | .type kernel_main, @function 26 | 27 | .extern printf 28 | .type tty_printf, @function 29 | 30 | _start: 31 | /* Setup our stack */ 32 | mov $stack_top, %esp 33 | 34 | /* Make sure our stack is 16-byte aligned */ 35 | and $-16, %esp 36 | 37 | pushl %esp 38 | pushl %eax /* Multiboot header magic */ 39 | pushl %ebx /* Multiboot header pointer */ 40 | 41 | cli 42 | call kernel_main 43 | 44 | cli 45 | pushl $halt_message 46 | call tty_printf 47 | hang: 48 | hlt 49 | jmp hang 50 | 51 | halt_message: 52 | .asciz "Halted." 53 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/asm/bootv1.s: -------------------------------------------------------------------------------- 1 | /* credits: wiki.osdev.org, syssec.rub.de (angry_os) */ 2 | 3 | .set MB_MAGIC, 0x1BADB002 4 | .set MB_FLAG_PAGE_ALIGN, 1 << 0 5 | .set MB_FLAG_MEMORY_INFO, 1 << 1 6 | .set MB_FLAG_GRAPHICS, 1 << 2 7 | .set MB_FLAGS, 2 8 | .set MB_CHECKSUM, -(MB_MAGIC + MB_FLAGS) 9 | 10 | .section .multiboot 11 | .align 4 12 | 13 | /* Multiboot section */ 14 | .long MB_MAGIC 15 | .long MB_FLAGS 16 | .long MB_CHECKSUM 17 | .long 0x00000000 /* header_addr */ 18 | .long 0x00000000 /* load_addr */ 19 | .long 0x00000000 /* load_end_addr */ 20 | .long 0x00000000 /* bss_end_addr */ 21 | .long 0x00000000 /* entry_addr */ 22 | 23 | /* Request linear graphics mode */ 24 | .long 0x00000000 25 | .long 0 26 | .long 0 27 | .long 32 28 | 29 | /* .stack resides in .bss */ 30 | .section .stack, "aw", @nobits 31 | stack_bottom: 32 | .skip 16384 /* 16KiB */ 33 | stack_top: 34 | 35 | .section .text 36 | 37 | .global _start 38 | .type _start, @function 39 | 40 | .extern kernel_main 41 | .type kernel_main, @function 42 | 43 | _start: 44 | /* Setup our stack */ 45 | mov $stack_top, %esp 46 | 47 | /* Make sure our stack is 16-byte aligned */ 48 | and $-16, %esp 49 | 50 | pushl %esp 51 | pushl %eax /* Multiboot header magic */ 52 | pushl %ebx /* Multiboot header pointer */ 53 | 54 | /* Disable interrupts and call kernel proper */ 55 | cli 56 | call kernel_main 57 | 58 | /* Clear interrupts and hang if we return from kernel_main */ 59 | cli 60 | hang: 61 | hlt 62 | jmp hang 63 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/gdt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | /* credits: wiki.osdev.org, syssec.rub.de (angry_os) */ 20 | 21 | #include 22 | #include "tty.h" 23 | 24 | typedef struct { 25 | /* Limits */ 26 | uint16_t limit_low; 27 | /* Segment address */ 28 | uint16_t base_low; 29 | uint8_t base_middle; 30 | /* Access modes */ 31 | uint8_t access; 32 | uint8_t granularity; 33 | uint8_t base_high; 34 | } __attribute__((packed)) gdt_entry_t; 35 | 36 | typedef struct { 37 | uint16_t limit; 38 | uintptr_t base; 39 | } __attribute__((packed)) gdt_pointer_t; 40 | 41 | struct { 42 | gdt_entry_t entries[6]; 43 | gdt_pointer_t pointer; 44 | } gdt __attribute__((used)); 45 | 46 | extern void gdt_flush(uintptr_t); 47 | 48 | #define ENTRY(X) (gdt.entries[(X)]) 49 | 50 | void gdt_set_gate(uint8_t num, uint64_t base, uint64_t limit, uint8_t access, uint8_t gran) { 51 | /* Base Address */ 52 | ENTRY(num).base_low = (base & 0xFFFF); 53 | ENTRY(num).base_middle = (base >> 16) & 0xFF; 54 | ENTRY(num).base_high = (base >> 24) & 0xFF; 55 | /* Limits */ 56 | ENTRY(num).limit_low = (limit & 0xFFFF); 57 | ENTRY(num).granularity = (limit >> 16) & 0X0F; 58 | /* Granularity */ 59 | ENTRY(num).granularity |= (gran & 0xF0); 60 | /* Access flags */ 61 | ENTRY(num).access = access; 62 | } 63 | 64 | void gdt_install(void) { 65 | gdt_pointer_t *gdtp = &gdt.pointer; 66 | gdtp->limit = sizeof(gdt.entries)-1; 67 | gdtp->base = (uintptr_t)&ENTRY(0); 68 | 69 | gdt_set_gate(0, 0, 0, 0, 0); /* NULL segment */ 70 | gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* Code segment */ 71 | gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Data segment */ 72 | gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); /* User code */ 73 | gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); /* User data */ 74 | 75 | gdt_flush((uintptr_t)gdtp); 76 | } -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/idt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | /* credits: wiki.osdev.org, syssec.rub.de (angry_os) */ 20 | 21 | #include "system.h" 22 | #include "libk.h" 23 | #include "tty.h" 24 | 25 | typedef struct { 26 | uint16_t base_low; 27 | uint16_t sel; 28 | uint8_t zero; 29 | uint8_t flags; 30 | uint16_t base_high; 31 | } __attribute__((packed)) idt_entry_t; 32 | 33 | typedef struct { 34 | uint16_t limit; 35 | uintptr_t base; 36 | } __attribute__((packed)) idt_pointer_t; 37 | 38 | static struct { 39 | idt_entry_t entries[256]; 40 | idt_pointer_t pointer; 41 | } idt __attribute__((used)); 42 | 43 | #define ENTRY(X) (idt.entries[(X)]) 44 | 45 | typedef void (*idt_gate_t)(void); 46 | 47 | extern void idt_load(uintptr_t); 48 | 49 | void idt_set_gate(uint8_t num, idt_gate_t base, uint16_t sel, uint8_t flags) { 50 | ENTRY(num).base_low = ((uintptr_t)base & 0xFFFF); 51 | ENTRY(num).base_high = ((uintptr_t)base >> 16) & 0xFFFF; 52 | ENTRY(num).sel = sel; 53 | ENTRY(num).zero = 0; 54 | ENTRY(num).flags = flags | 0x60; 55 | } 56 | 57 | void idt_install(void) { 58 | idt_pointer_t * idtp = &idt.pointer; 59 | 60 | idtp->limit = sizeof(idt.entries)-1; 61 | idtp->base = (uintptr_t)&ENTRY(0); 62 | memset(&ENTRY(0), 0, sizeof(idt.entries)); 63 | 64 | idt_load((uintptr_t)idtp); 65 | } -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/msr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #include "msr.h" 20 | 21 | const uint32_t CPUID_FLAG_MSR = 1 << 5; 22 | 23 | void rdmsr32(uint32_t msr, uint32_t *lo, uint32_t *hi){ 24 | asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); 25 | } 26 | 27 | void wrmsr32(uint32_t msr, uint32_t lo, uint32_t hi){ 28 | asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); 29 | } 30 | 31 | uint64_t rdmsr64(uint32_t msr){ 32 | uint32_t lo, hi; 33 | uint64_t result; 34 | asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); 35 | result = hi; 36 | result = result << 32; 37 | result = result + lo; 38 | return result; 39 | } 40 | 41 | void wrmsr64(uint32_t msr, uint64_t value){ 42 | asm volatile("wrmsr" : : "a"((uint32_t)(value)), "d"((uint32_t)(value>>32)), "c"(msr)); 43 | } -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/pic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #include 20 | #include "pic.h" 21 | #include "io.h" 22 | #include "tty.h" 23 | 24 | #define STR_PREFIX " [PIC] " 25 | 26 | static bool enabled = false; 27 | 28 | static uint16_t pic_get_irq_reg(int ocw3){ 29 | outb(PIC1_CMD, ocw3); 30 | outb(PIC2_CMD, ocw3); 31 | return (inb(PIC2_CMD) << 8) | inb(PIC1_CMD); 32 | } 33 | 34 | static uint16_t pic_get_irr(void){ 35 | return pic_get_irq_reg(PIC_READ_IRR); 36 | } 37 | 38 | static inline void pic_irq_master_eoi(void){ 39 | outb(PIC_EOI, PIC1_CMD); 40 | } 41 | 42 | static inline void pic_irq_slave_eoi(void){ 43 | outb(PIC_EOI, PIC2_CMD); 44 | } 45 | 46 | void pic_irq_ack(uint8_t irq){ 47 | pic_irq_master_eoi(); 48 | if (irq >= 8) { 49 | pic_irq_slave_eoi(); 50 | } 51 | } 52 | 53 | bool pci_interrupt_pending(uint8_t irq){ 54 | return !!(pic_get_irr() & (1<. 16 | * 17 | */ 18 | 19 | /* credits: wiki.osdev.org, syssec.rub.de (angry_os) */ 20 | 21 | #include "system.h" 22 | #include "serial.h" 23 | #include "libk.h" 24 | #include "io.h" 25 | #include "config.h" 26 | 27 | bool serial_enabled = false; 28 | 29 | void serial_enable(int device) { 30 | outb(0x00, device + 1); 31 | outb(0x80, device + 3); /* Enable divisor mode */ 32 | outb(0x03, device + 0); /* Div Low: 03 Set the port to 38400 baud */ 33 | outb(0x00, device + 1); /* Div High: 00 */ 34 | outb(0x03, device + 3); /* 8 bits, no parity, one stop bit */ 35 | outb(0xC7, device + 2); 36 | outb(0x0B, device + 4); 37 | serial_enabled = true; 38 | } 39 | 40 | int serial_rcvd(int device) { 41 | return inb(device + 5) & 1; 42 | } 43 | 44 | char serial_recv(int device) { 45 | while (serial_rcvd(device) == 0) ; 46 | return inb(device); 47 | } 48 | 49 | int serial_recv_string(int device, char* buf, int size) { 50 | if(size == 0) 51 | return 0; 52 | 53 | int pos = 0; 54 | while(1) { 55 | char c = serial_recv(device); 56 | buf[pos] = c; 57 | pos++; 58 | 59 | if(c == 0 || c == '\n' || pos >= size) 60 | return pos; 61 | 62 | } 63 | } 64 | 65 | char serial_recv_async(int device) { 66 | return inb(device); 67 | } 68 | 69 | int serial_transmit_empty(int device) { 70 | return inb(device + 5) & 0x20; 71 | } 72 | 73 | void serial_send(int device, char out) { 74 | if(serial_enabled){ 75 | while (serial_transmit_empty(device) == 0); 76 | outb(out, device); 77 | } 78 | } 79 | 80 | void serial_send_string(int device, char * out) { 81 | #ifdef ENABLE_TTY_SERIAL 82 | for (uint32_t i = 0; i < strlen(out); ++i) { 83 | serial_send(device, out[i]); 84 | } 85 | #endif 86 | } 87 | 88 | int serial_printf(int device, const char* fmt, ...) { 89 | char buf[1024]; 90 | va_list args; 91 | va_start(args, fmt); 92 | int out = vasprintf(buf, fmt, args); 93 | va_end(args); 94 | serial_send_string(device, buf); 95 | return out; 96 | } 97 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/src/smp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #include "smp.h" 20 | #include "apic.h" 21 | #include "tty.h" 22 | #include "mmio.h" 23 | #include "libk.h" 24 | #include "mem.h" 25 | 26 | #define STR_PREFIX " [SMP] " 27 | 28 | uint32_t stack_offset = 0x1; 29 | 30 | volatile uintptr_t ap_stack; 31 | 32 | static volatile uint32_t ap_ready = 0; 33 | static uint32_t aps = 0; 34 | 35 | 36 | void smp_increase_aps(void){ 37 | aps++; 38 | } 39 | 40 | void smp_boot_ack(void){ 41 | ap_ready++; 42 | } 43 | 44 | void smp_init(void){ 45 | extern void __ap_boot(); 46 | memcpy((void*)AP_INIT_ADDRESS, __ap_boot, 0x1000); 47 | 48 | uint32_t base = apic_get_base(); 49 | printf(STR_PREFIX" Starting %d APs...\n", aps); 50 | 51 | uint32_t volatile tmp = 0; 52 | uint32_t volatile fetch = 0; 53 | 54 | tmp = ap_ready; 55 | for(uint32_t i = 1; i < aps; i++){ 56 | ap_stack = mem_alloc_ap_stack(); 57 | fetch = ap_ready; 58 | 59 | mmio_write32(base, LAPIC_ICRHI, i << ICR_DESTINATION_SHIFT); 60 | mmio_write32(base, LAPIC_ICRLO, ICR_ASSERT | ICR_INIT); 61 | 62 | microdelay(1000000); 63 | microdelay(1000000); 64 | mmio_write32(base, LAPIC_ICRHI, i << ICR_DESTINATION_SHIFT); 65 | mmio_write32(base, LAPIC_ICRLO, ICR_ASSERT | ICR_STARTUP | (AP_INIT_ADDRESS>>12)); 66 | 67 | microdelay(1000000); 68 | mmio_write32(base, LAPIC_ICRHI, i << ICR_DESTINATION_SHIFT); 69 | mmio_write32(base, LAPIC_ICRLO, ICR_ASSERT | ICR_STARTUP | (AP_INIT_ADDRESS>>12)); 70 | 71 | microdelay(1000000); 72 | 73 | if ((mmio_read32(base, LAPIC_ICRLO) & ICR_SEND_PENDING) != 0) { 74 | printf(STR_PREFIX" AP-WAKENING FAIL!\n"); 75 | } 76 | 77 | while(1){ 78 | fetch = ap_ready; 79 | if(fetch != tmp){ 80 | tmp = fetch; 81 | break; 82 | } 83 | } 84 | printf(STR_PREFIX" Processor %d ready...\n", ap_ready); 85 | } 86 | printf(STR_PREFIX" Processor 0 ready...\n"); 87 | } 88 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/tesseract/compile.sh: -------------------------------------------------------------------------------- 1 | # 2 | # HyperCube OS 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU Affero General Public License as 6 | # published by the Free Software Foundation, either version 3 of the 7 | # License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Affero General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Affero General Public License 15 | # along with this program. If not, see . 16 | # 17 | # 18 | 19 | 20 | mkdir bin/ 2> /dev/null 21 | mkdir asan/ 2> /dev/null 22 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -o bin/hexas_32 23 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -DDECOMPILER -o bin/hexas_32_decompiler 24 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -DDISASSEMBLER -o bin/hexas_32_disassembler 25 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -DDECOMPILER -DLOOP -o bin/hexas_32_decompiler_loop 26 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -DDISASSEMBLER -DLOOP -o bin/hexas_32_disassembler_loop 27 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -DHYBRID -o bin/hexas_32_hybrid_loop 28 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -DHYBRID -DLOOP -o bin/hexas_32_hybrid_loop 29 | 30 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -fsanitize=address -DDECOMPILER -o bin/hexas_32_decompiler_asan 31 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -fsanitize=address -DDECOMPILER -DLOOP -o bin/hexas_32_decompiler_loop_asan 32 | 33 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -fsanitize=address -DHYBRID -o bin/hexas_32_hybrid_asan 34 | gcc -m32 main.c state.c opcodes.c decompiler.c core.c dict.c -g -O3 -fsanitize=address -DHYBRID -DLOOP -o bin/hexas_32_hybrid_loop_asan 35 | 36 | gcc -m32 generate_config.c -o bin/generate_config 37 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/tesseract/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | #include 21 | #include "state.h" 22 | 23 | void run(hexa_op* instructions, uint32_t num, state_t* state_obj); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/tesseract/dict.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | extern uint32_t dict[]; 24 | extern uint32_t data_dict[]; 25 | 26 | uint32_t dict_size(void); 27 | uint32_t data_dict_size(void); -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/tesseract/io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #ifdef HYPERTRASH 24 | #define outb(__value,__port) asm volatile ("outb %%al, %%dx"::"a"(__value),"d"(__port)) 25 | #define outw(__value,__port) asm volatile ("outw %%ax, %%dx"::"a"(__value),"d"(__port)) 26 | #define outl(__value,__port) asm volatile ("outl %%eax, %%dx"::"a"(__value),"d"(__port)) 27 | 28 | #define inb(__port) \ 29 | ({ \ 30 | uint8_t __data; \ 31 | asm volatile ("inb %%dx,%%al":"=a"(__data):"d"(__port)); \ 32 | __data; \ 33 | }) 34 | 35 | #define inw(__port) \ 36 | ({ \ 37 | uint16_t __data; \ 38 | asm volatile ("inw %%dx,%%ax":"=a"(__data):"d"(__port)); \ 39 | __data; \ 40 | }) 41 | 42 | #define inl(__port) \ 43 | ({ \ 44 | uint32_t __data; \ 45 | asm volatile ("inl %%dx,%%eax":"=a"(__data):"d"(__port)); \ 46 | __data; \ 47 | }) 48 | 49 | #else 50 | #define outb(__value,__port) {} 51 | #define outw(__value,__port) {} 52 | #define outl(__value,__port) {} 53 | 54 | #define inb(__port) 0 55 | #define inw(__port) 0 56 | #define inl(__port) 0 57 | 58 | #endif 59 | 60 | 61 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/tesseract/mmio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #ifdef HYPERTRASH 24 | #include "tty.h" 25 | #endif 26 | 27 | 28 | #ifdef HYPERTRASH 29 | static inline uint8_t _mmio_read8(uint32_t __base, uint32_t __offset){ 30 | #ifdef INTERPRETER_BENCHMARK 31 | return 0; 32 | #endif 33 | return *(volatile uint8_t *)((uintptr_t)(__base + __offset)); 34 | } 35 | 36 | static inline uint16_t _mmio_read16(uint32_t __base, uint32_t __offset){ 37 | #ifdef INTERPRETER_BENCHMARK 38 | return 0; 39 | #endif 40 | return *(volatile uint16_t *)((uintptr_t)(__base + __offset)); 41 | } 42 | 43 | static inline uint32_t _mmio_read32(uint32_t __base, uint32_t __offset){ 44 | #ifdef INTERPRETER_BENCHMARK 45 | return 0; 46 | #endif 47 | return *(volatile uint32_t *)((uintptr_t)(__base + __offset)); 48 | } 49 | 50 | static inline uint64_t _mmio_read64(uint32_t __base, uint32_t __offset){ 51 | #ifdef INTERPRETER_BENCHMARK 52 | return 0; 53 | #endif 54 | return *(volatile uint64_t *)((uintptr_t)(__base + __offset)); 55 | } 56 | 57 | static inline void _mmio_write8(uint32_t __base, uint32_t __offset, uint8_t data){ 58 | #ifdef INTERPRETER_BENCHMARK 59 | return 0; 60 | #endif 61 | *(volatile uint8_t *)((uintptr_t)(__base + __offset)) = data; 62 | } 63 | 64 | static inline void _mmio_write16(uint32_t __base, uint32_t __offset, uint16_t data){ 65 | #ifdef INTERPRETER_BENCHMARK 66 | return 0; 67 | #endif 68 | *(volatile uint16_t *)((uintptr_t)(__base + __offset)) = data; 69 | } 70 | 71 | static inline void _mmio_write32(uint32_t __base, uint32_t __offset, uint32_t data){ 72 | #ifdef INTERPRETER_BENCHMARK 73 | return 0; 74 | #endif 75 | *(volatile uint32_t *)((uintptr_t)(__base + __offset)) = data; 76 | } 77 | 78 | static inline void _mmio_write64(uint32_t __base, uint32_t __offset, uint64_t data){ 79 | #ifdef INTERPRETER_BENCHMARK 80 | return 0; 81 | #endif 82 | *(volatile uint64_t *)((uintptr_t)(__base + __offset)) = data; 83 | } 84 | 85 | 86 | #else 87 | #define _mmio_read8(__base, __offset) 0 88 | #define _mmio_read16(__base, __offset) 0 89 | #define _mmio_read32(__base, __offset) 0 90 | #define _mmio_read64(__base, __offset) 0 91 | 92 | #define _mmio_write8(__base, __offset, __data) {} 93 | #define _mmio_write16(__base, __offset, __data) {} 94 | #define _mmio_write32(__base, __offset, __data) {} 95 | #define _mmio_write64(__base, __offset, __data) {} 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/tesseract/state.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HyperCube OS 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #define MAX_LOOP_COUNT 0x8 24 | #define MAX_LOOP_STEPS 0x8 25 | 26 | #define unlikely(expr) __builtin_expect(!!(expr), 0) 27 | #define likely(expr) __builtin_expect(!!(expr), 1) 28 | 29 | #define AREA_DESC_LEN 256 30 | #define MAGIC_NUMBER 0x41584548U 31 | #define NUM_OF_SCRATCH_AREAS 1 32 | #define SCRATCH_AREA_SIZE 0x2000 33 | 34 | typedef struct { 35 | uint8_t op_type; 36 | //uint8_t op_code; 37 | uint32_t arg; 38 | } __attribute__((packed)) hexa_op; 39 | 40 | typedef struct { 41 | uint32_t base; 42 | uint32_t size; 43 | uint32_t virtual_base; 44 | char desc[AREA_DESC_LEN]; 45 | }area_t_export; 46 | 47 | typedef struct { 48 | uint32_t base; 49 | uint32_t size; 50 | uint32_t virtual_base; 51 | char desc[AREA_DESC_LEN]; 52 | }area_t; 53 | 54 | typedef struct { 55 | uint32_t a[10]; 56 | uint8_t num_mmio_areas; 57 | uint8_t num_io_areas; 58 | uint8_t num_alloc_areas; 59 | uint8_t** alloc_areas; 60 | area_t** mmio_area; 61 | area_t** io_area; 62 | 63 | uint8_t loop_count; 64 | uint32_t ip; 65 | uint32_t loop_target; 66 | uint32_t last_loop_ip; 67 | }state_t; 68 | 69 | typedef struct { 70 | uint32_t magic; 71 | uint8_t num_mmio_areas; 72 | uint8_t num_io_areas; 73 | uint8_t num_alloc_areas; 74 | uint8_t padding; 75 | }config_t; 76 | 77 | state_t* new_state(void); 78 | void print_state(state_t* state); 79 | state_t* load_state(void* config_data, uint32_t config_len); 80 | void save_state(state_t* state_data, void** saved_data, uint32_t* saved_len); 81 | void destroy_state(state_t* state_obj); 82 | void reset_state(state_t* state_obj); 83 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/hypertrash_os/xorriso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/hypervisor_spec/build/hypertrash_os/xorriso -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/build/userspace_tester.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define hprintf printf 23 | #include "interpreter.h" 24 | 25 | char* data_mmap=0; 26 | size_t data_mmap_size=0; 27 | 28 | int run_vm() { 29 | uint64_t* offsets = (uint64_t*)data_mmap; 30 | hprintf("checksum: %lx, %lx\n",offsets[0], INTERPRETER_CHECKSUM); 31 | assert(offsets[0] == INTERPRETER_CHECKSUM); 32 | assert(offsets[1] < 0xffffff); 33 | assert(offsets[2] < 0xffffff); 34 | assert(offsets[3] < 0xffffff); 35 | assert(offsets[4] < 0xffffff); 36 | uint64_t graph_size = offsets[1]; 37 | uint64_t data_size = offsets[2]; 38 | printf("graph_size: %d\n", graph_size); 39 | printf("data_size: %d\n", graph_size); 40 | printf("graph_offset: %d\n", offsets[3]); 41 | printf("data_offset: %d\n", offsets[4]); 42 | uint16_t* graph_ptr = (uint16_t*)(data_mmap+offsets[3]); 43 | uint8_t* data_ptr = (uint8_t*)(data_mmap+offsets[4]); 44 | assert(offsets[3]+graph_size*sizeof(uint16_t) <= data_mmap_size); 45 | assert(offsets[4]+data_size <= data_mmap_size); 46 | interpreter_t* vm = new_interpreter(); 47 | init_interpreter(vm, graph_ptr, graph_size, data_ptr, data_size); 48 | interpreter_user_init(vm); 49 | run(vm); 50 | interpreter_user_shutdown(vm); 51 | } 52 | 53 | int main(int argc, char** argv) { 54 | char* file = getenv("STRUCT_INPUT_PATH"); 55 | if(!file){ 56 | printf("COULDN'T OPEN SPEC INPUT, SKIPING ENVIRONMENT SETUP\n"); 57 | exit(0); 58 | } else { 59 | int fd=open(file, O_RDWR); 60 | assert(fd >= 0); 61 | struct stat attr; 62 | assert(fstat(fd, &attr) >= 0); 63 | 64 | data_mmap=mmap(0, attr.st_size, PROT_READ, MAP_SHARED, fd, 0); 65 | data_mmap_size = (size_t)attr.st_size; 66 | hprintf("mmaped buffer size: %lx\n",data_mmap_size); 67 | } 68 | run_vm(); 69 | } -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/gen_spec.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(1, '../structured_fuzzer/interpreter/') 3 | 4 | from spec_lib.graph_spec import * 5 | from spec_lib.data_spec import * 6 | from spec_lib.graph_builder import * 7 | from spec_lib.generators import opts,flags,limits 8 | 9 | import jinja2 10 | 11 | from hexa_spec.legacy import make_legacy_pcnet, make_legacy_rtl8139, make_legacy_e1000, make_legacy_ee100pro, make_legacy_sdhci, make_legacy_intel_hda, make_legacy_ac97, make_legacy_ide_core, make_legacy_floppy, make_legacy_parallel, make_legacy_serial, make_legacy_cs4231a, make_legacy_xhci 12 | 13 | from hexa_spec.ahci import make_ahci 14 | 15 | from hexa_spec.xhci import make_xhci 16 | 17 | s = Spec() 18 | 19 | s.use_std_lib = False 20 | s.custom_defines=""+ \ 21 | "#define ASSERT(x) assert(x)\n"+\ 22 | "#define VM_MALLOC(x) kvmalloc(x)\n" 23 | 24 | s.includes.append("\"custom_includes.h\"") 25 | 26 | s.interpreter_user_data_type = "hypertrash_context_t*" 27 | 28 | if len(sys.argv) == 2: 29 | 30 | target = sys.argv[1] 31 | 32 | if target == "bhyve_ahci": 33 | make_ahci(s, 0x824000, 0, bhyve=True) 34 | elif target == "qemu_xhci": 35 | make_xhci(s, 0x1821000, 0x40, 30, 16, 0, 0x2000, 0x1000, 0x440, msix=True) 36 | elif target == "legacy_xhci": 37 | make_legacy_xhci(s) 38 | elif target == "legacy_pcnet": 39 | make_legacy_pcnet(s) 40 | elif target == "legacy_rtl8139": 41 | make_legacy_rtl8139(s) 42 | elif target == "legacy_e1000": 43 | make_legacy_e1000(s) 44 | elif target == "legacy_ee100pro": 45 | make_legacy_ee100pro(s) 46 | elif target == "legacy_sdhci": 47 | make_legacy_sdhci(s) 48 | elif target == "legacy_intel_hda": 49 | make_legacy_intel_hda(s) 50 | elif target == "legacy_ide_core": 51 | make_legacy_ide_core(s) 52 | elif target == "legacy_floppy": 53 | make_legacy_floppy(s) 54 | elif target == "legacy_parallel": 55 | make_legacy_parallel(s) 56 | elif target == "legacy_serial": 57 | make_legacy_serial(s) 58 | elif target == "legacy_cs4231a": 59 | make_legacy_cs4231a(s) 60 | elif target == "legacy_ac97": 61 | make_legacy_ac97(s) 62 | else: 63 | sys.exit(0) 64 | 65 | s.build_interpreter() 66 | 67 | import msgpack 68 | serialized_spec = s.build_msgpack() 69 | with open("spec.msgp","wb") as f: 70 | f.write(msgpack.packb(serialized_spec)) 71 | 72 | 73 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/hexa_spec/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/hexa_spec/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/hypervisor_spec/hexa_spec/__init__.py -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/make.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | cd build/hypertrash_os 3 | make clean 4 | cd - 5 | #python3 gen_spec.py legacy_xhci 6 | python3 gen_spec.py legacy_xhci 7 | cd build 8 | cp bytecode_spec.template.h bytecode_spec.h 9 | cd hypertrash_os 10 | make 11 | 12 | cd ../../ 13 | 14 | cp build/hypertrash_os/iso/hypertrash_os_bios.iso ../../Targets/bhyve/sharedir/hypertrash.iso 15 | cp build/hypertrash_os/iso/hypertrash_os_bios.iso ../../Targets/qemu/sharedir/hypertrash.iso 16 | cp build/hypertrash_os/iso/hypertrash_os_bios.iso ../../Targets/qemu/sharedir_asan/hypertrash.iso 17 | 18 | cp spec.msgp ../../Targets/bhyve/sharedir/spec.msgp 19 | cp spec.msgp ../../Targets/qemu/sharedir/spec.msgp 20 | cp spec.msgp ../../Targets/qemu/sharedir_asan/spec.msgp 21 | -------------------------------------------------------------------------------- /nyx_fuzzer/hypervisor_spec/make_sharedirs.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | cd build/hypertrash_os 3 | make clean 4 | cd - 5 | python3 gen_spec.py bhyve_ahci 6 | cd build 7 | cp bytecode_spec.template.h bytecode_spec.h 8 | cd hypertrash_os 9 | make 10 | 11 | cd ../../ 12 | 13 | cp build/hypertrash_os/iso/hypertrash_os_bios.iso ../../Targets/bhyve/sharedir/hypertrash.iso 14 | cp spec.msgp ../../Targets/bhyve/sharedir/spec.msgp 15 | 16 | cd build/hypertrash_os 17 | make clean 18 | cd - 19 | python3 gen_spec.py legacy_xhci 20 | cd build 21 | cp bytecode_spec.template.h bytecode_spec.h 22 | cd hypertrash_os 23 | make 24 | 25 | cd ../../ 26 | 27 | cp build/hypertrash_os/iso/hypertrash_os_bios.iso ../../Targets/qemu/sharedir_asan/hypertrash.iso 28 | cp spec.msgp ../../Targets/qemu/sharedir_asan/spec.msgp 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_fuzzer" 3 | version = "0.1.0" 4 | authors = ["coco "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | fuzz_runner={path="../fuzz_runner"} 11 | structured_fuzzer={path="../structured_fuzzer"} 12 | helpers={path="../helpers"} 13 | config={path="../config"} 14 | core_affinity="0.5.10" 15 | serde ="1.0.104" 16 | serde_derive ="1.0.104" 17 | rmp-serde ="0.14.3" 18 | ron = "0.5.1" 19 | clap="2.33.0" 20 | rand = "0.7.3" -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/config.ron: -------------------------------------------------------------------------------- 1 | ( 2 | runner: QemuSnapshot(( 3 | qemu_binary: "/home/kafl/QEMU-PT/x86_64-softmmu/qemu-system-x86_64", 4 | hda: "/home/kafl/VMs/freebsd_11_3_asan/freebsd_11_3_asan.qcow2", 5 | sharedir: "/home/kafl/VMs/freebsd_11_3_asan/freebsd_11_3_asan_sharedir/", 6 | presnapshot: "/home/kafl/VMs/freebsd_11_3_asan/freebsd_11_3_asan_pre_snapshot/", 7 | //snapshot_path: DefaultPath, 8 | snapshot_path: Reuse("/tmp/struct_snapshot"), 9 | debug: true, 10 | )), 11 | fuzz: ( 12 | spec_path: "../hypertrash_spec/hexaschrott_freebsd.msgp", 13 | workdir_path: "/tmp/fuzz_struct_test", 14 | bitmap_size: 65536, 15 | mem_limit: 1024, 16 | time_limit: ( 17 | secs: 0, 18 | nanos: 800000000, 19 | ), 20 | target_binary: None, 21 | threads: 3, 22 | thread_id: 0, 23 | cpu_pin_start_at: 0, 24 | ), 25 | ) 26 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/config_forkserver.ron: -------------------------------------------------------------------------------- 1 | ( 2 | runner: ForkServer(( 3 | args: [ 4 | "target", 5 | "--test_arg", 6 | ], 7 | hide_output: true, 8 | input_size: 262144, 9 | env: [], 10 | )), 11 | fuzz: ( 12 | spec_path: "../hypertrash_spec/hexaschrott_freebsd.msgp", 13 | workdir_path: "/tmp/fuzz_struct_test", 14 | bitmap_size: 65536, 15 | mem_limit: 1024, 16 | time_limit: ( 17 | secs: 0, 18 | nanos: 800000000, 19 | ), 20 | target_binary: None, 21 | threads: 3, 22 | thread_id: 0, 23 | ), 24 | ) -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/config_kernel.ron: -------------------------------------------------------------------------------- 1 | ( 2 | runner: QemuKernel(( 3 | qemu_binary: "/home/kafl/QEMU-PT/x86_64-softmmu/qemu-system-x86_64", 4 | target_pack: "/home/kafl/rust_dev/nyx/syzkaller_spec/build/agent_fuzz", 5 | kernel: "/home/kafl/Target-Components/linux_initramfs/bzImage-linux-4.15-rc7", 6 | ramfs: "/home/kafl/Target-Components/linux_initramfs/init.cpio.gz", 7 | debug: false, 8 | )), 9 | fuzz: ( 10 | spec_path: "../hypertrash_spec/hexaschrott_freebsd.msgp", 11 | workdir_path: "/tmp/fuzz_struct_test", 12 | bitmap_size: 65536, 13 | mem_limit: 1024, 14 | time_limit: ( 15 | secs: 0, 16 | nanos: 800000000, 17 | ), 18 | target_binary: None, 19 | threads: 3, 20 | thread_id: 0, 21 | ), 22 | ) -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/config_snapshot.ron: -------------------------------------------------------------------------------- 1 | ( 2 | runner: QemuSnapshot(( 3 | qemu_binary: "/home/kafl/QEMU-PT/x86_64-softmmu/qemu-system-x86_64", 4 | hda: "/home/kafl/VMs/freebsd_11_3_asan/freebsd_11_3_asan.qcow2", 5 | sharedir: "/home/kafl/VMs/freebsd_11_3_asan/freebsd_11_3_asan_sharedir/", 6 | presnapshot: "/home/kafl/VMs/freebsd_11_3_asan/freebsd_11_3_asan_pre_snapshot/", 7 | debug: true, 8 | )), 9 | fuzz: ( 10 | spec_path: "../hypertrash_spec/hexaschrott_freebsd.msgp", 11 | workdir_path: "/tmp/fuzz_struct_test", 12 | bitmap_size: 65536, 13 | mem_limit: 1024, 14 | time_limit: ( 15 | secs: 0, 16 | nanos: 800000000, 17 | ), 18 | target_binary: None, 19 | threads: 3, 20 | thread_id: 0, 21 | ), 22 | ) -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/config_snapshot_cluster_ubuntu.ron: -------------------------------------------------------------------------------- 1 | ( 2 | runner: QemuSnapshot(( 3 | qemu_binary: "/home/kafl/kafl/QEMU-PT/x86_64-softmmu/qemu-system-x86_64", 4 | hda: "/home/kafl/VMs/ubuntu_18_04_4_asan.qcow2", 5 | sharedir: "/home/kafl/VMs/ubuntu_18_04_4_asan/ubuntu_qemu_sharedir/", 6 | presnapshot: "/home/kafl/VMs/ubuntu_18_04_4_asan/ubuntu_snapshot_asan/", 7 | //snapshot_path: DefaultPath, 8 | snapshot_path: Reuse("/tmp/struct_snapshot"), 9 | debug: true, 10 | )), 11 | fuzz: ( 12 | spec_path: "../hypertrash_spec/hexaschrott_freebsd.msgp", 13 | workdir_path: "/tmp/fuzz_struct_test", 14 | bitmap_size: 65536, 15 | mem_limit: 1024, 16 | time_limit: ( 17 | secs: 0, 18 | nanos: 800000000, 19 | ), 20 | target_binary: None, 21 | threads: 3, 22 | thread_id: 0, 23 | cpu_pin_start_at: 0, 24 | ), 25 | ) 26 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/deploy.sh: -------------------------------------------------------------------------------- 1 | cargo build --release 2 | ssh kafl_02 'pkill -9 qemu' 3 | ssh kafl_02 'pkill -9 fuzz' 4 | scp target/release/rust_fuzzer kafl_02:/tmp/fuzz 5 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/spec.msgp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/rust_fuzzer/spec.msgp -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/src/bitmap.rs: -------------------------------------------------------------------------------- 1 | use crate::fuzz_runner::ExitReason; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, Hash)] 4 | pub struct StorageReason { 5 | pub index: usize, 6 | pub old: u8, 7 | pub new: u8, 8 | } 9 | 10 | pub struct BitmapHandler { 11 | normal: Bitmap, 12 | crash: Bitmap, 13 | timeout: Bitmap, 14 | invalid_write_to_payload: Bitmap, 15 | size: usize, 16 | } 17 | 18 | impl BitmapHandler { 19 | pub fn new(size: usize) -> Self { 20 | return Self { 21 | normal: Bitmap::new(size), 22 | crash: Bitmap::new(size), 23 | timeout: Bitmap::new(size), 24 | invalid_write_to_payload: Bitmap::new(size), 25 | size, 26 | }; 27 | } 28 | 29 | pub fn check_new_bytes( 30 | &mut self, 31 | run_bitmap: &[u8], 32 | etype: &ExitReason, 33 | ) -> Option> { 34 | match etype { 35 | ExitReason::Normal(_) => return self.normal.check_new_bytes(run_bitmap), 36 | ExitReason::Crash(_) => return self.crash.check_new_bytes(run_bitmap), 37 | ExitReason::Timeout => return self.timeout.check_new_bytes(run_bitmap), 38 | ExitReason::InvalidWriteToPayload(_) => { 39 | return self.invalid_write_to_payload.check_new_bytes(run_bitmap) 40 | } 41 | _ => return None, 42 | } 43 | } 44 | 45 | pub fn size(&self) -> usize { 46 | self.size 47 | } 48 | 49 | pub fn normal_bitmap(&self) -> &Bitmap{ 50 | return &self.normal 51 | } 52 | } 53 | 54 | #[derive(Clone)] 55 | pub struct Bitmap { 56 | bits: Vec, 57 | } 58 | 59 | impl Bitmap { 60 | pub fn new(size: usize) -> Self { 61 | return Self { 62 | bits: vec![0; size], 63 | }; 64 | } 65 | 66 | pub fn new_from_buffer(buff: &[u8]) -> Self { 67 | return Self { 68 | bits: buff.to_vec(), 69 | }; 70 | } 71 | 72 | pub fn check_new_bytes(&mut self, run_bitmap: &[u8]) -> Option> { 73 | assert_eq!(self.bits.len(), run_bitmap.len()); 74 | let mut res = None; 75 | for (i, (old, new)) in self.bits.iter_mut().zip(run_bitmap.iter()).enumerate() { 76 | if *new > *old { 77 | if res.is_none() { 78 | res = Some(vec![]); 79 | } 80 | res.as_mut().unwrap().push(StorageReason { 81 | index: i, 82 | old: *old, 83 | new: *new, 84 | }); 85 | *old = *new; 86 | } 87 | } 88 | return res; 89 | } 90 | 91 | pub fn bits(&self) -> &[u8] { 92 | return &self.bits; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/src/input.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | use std::sync::RwLock; 3 | use std::time::Duration; 4 | 5 | use crate::structured_fuzzer::custom_dict::CustomDict; 6 | use crate::bitmap::{Bitmap, StorageReason}; 7 | use crate::fuzz_runner::ExitReason; 8 | use crate::structured_fuzzer::graph_mutator::graph_storage::VecGraph; 9 | use crate::structured_fuzzer::mutator::MutationStrategy; 10 | 11 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] 12 | pub struct InputID(usize); 13 | 14 | impl InputID { 15 | pub fn new(a: usize) -> Self { 16 | Self(a) 17 | } 18 | pub fn invalid() -> Self { 19 | Self(std::usize::MAX) 20 | } 21 | pub fn as_usize(&self) -> usize { 22 | self.0 23 | } 24 | } 25 | 26 | #[derive(Clone)] 27 | pub enum InputState { 28 | Minimize, 29 | Havoc, 30 | } 31 | 32 | #[derive(Clone)] 33 | pub struct Input { 34 | pub id: InputID, 35 | pub data: Arc, 36 | pub bitmap: Bitmap, 37 | pub exit_reason: ExitReason, 38 | pub time: Duration, 39 | pub storage_reasons: Vec, 40 | pub found_by: MutationStrategy, 41 | pub state: InputState, 42 | pub custom_dict: CustomDict, 43 | } 44 | 45 | impl Input { 46 | pub fn new( 47 | data: VecGraph, 48 | found_by: MutationStrategy, 49 | storage_reasons: Vec, 50 | bitmap: Bitmap, 51 | exit_reason: ExitReason, 52 | time: Duration, 53 | ) -> Self { 54 | return Self { 55 | id: InputID::invalid(), 56 | data: Arc::new(data), 57 | bitmap, 58 | storage_reasons, 59 | exit_reason, 60 | time, 61 | state: InputState::Minimize, 62 | found_by, 63 | custom_dict: CustomDict::new(), 64 | }; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer/src/romu.rs: -------------------------------------------------------------------------------- 1 | pub struct RomuPrng { 2 | xstate: u64, 3 | ystate: u64, 4 | } 5 | 6 | impl RomuPrng { 7 | pub fn new(xstate: u64, ystate: u64) -> Self { 8 | return Self { xstate, ystate }; 9 | } 10 | 11 | pub fn range(&mut self, min: usize, max: usize) -> usize { 12 | return ((self.next_u64() as usize) % (max - min)) + min; 13 | } 14 | 15 | pub fn new_from_u64(seed: u64) -> Self { 16 | return Self::new(seed, seed ^ 0xec77152282650854); 17 | } 18 | 19 | pub fn next_u32(&mut self) -> u32 { 20 | self.next_u64() as u32 21 | } 22 | 23 | pub fn next_u64(&mut self) -> u64 { 24 | let xp = self.xstate; 25 | self.xstate = 15241094284759029579u64.wrapping_mul(self.ystate); 26 | self.ystate = self.ystate.wrapping_sub(xp); 27 | self.ystate = self.ystate.rotate_left(27); 28 | return xp; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer_debug/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_fuzzer_debug" 3 | version = "0.1.0" 4 | authors = ["Sergej Schumilo "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | fuzz_runner={path="../fuzz_runner"} 11 | structured_fuzzer={path="../structured_fuzzer"} 12 | helpers={path="../helpers"} 13 | config={path="../config"} 14 | core_affinity="0.5.10" -------------------------------------------------------------------------------- /nyx_fuzzer/rust_fuzzer_debug/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate config; 2 | extern crate fuzz_runner; 3 | extern crate helpers; 4 | extern crate structured_fuzzer; 5 | extern crate core_affinity; 6 | 7 | use std::time::Duration; 8 | 9 | use fuzz_runner::nyx::qemu_process_new_from_snapshot; 10 | 11 | use std::fs::File; 12 | use std::io::Read; 13 | use std::fs; 14 | 15 | use config::{ 16 | ForkServerConfig, FuzzRunnerConfig, FuzzerConfig, QemuKernelConfig, QemuSnapshotConfig, 17 | }; 18 | 19 | fn main() { 20 | println!("Hello, world!"); 21 | 22 | let snap_cfg = QemuSnapshotConfig { 23 | qemu_binary: "/home/sschumilo/kafl/QEMU-PT/x86_64-softmmu/qemu-system-x86_64".to_string(), 24 | //hda: "/home/sschumilo/VMs/ubuntu_18_04_4_asan.qcow2".to_string(), 25 | //presnapshot: "/home/sschumilo/VMs/ubuntu_18_04_4_asan/ubuntu_snapshot_asan".to_string(), 26 | //sharedir: "/home/sschumilo/VMs/ubuntu_18_04_4_asan/ubuntu_qemu_sharedir".to_string(), 27 | hda: "/home/sschumilo/VMs/freebsd_11_3_asan/freebsd_11_3_asan.qcow2".to_string(), 28 | presnapshot: "/home/sschumilo/VMs/freebsd_11_3_asan/freebsd_11_3_asan_pre_snapshot/".to_string(), 29 | sharedir: "/home/sschumilo/VMs/freebsd_11_3_asan/freebsd_11_3_asan_sharedir/".to_string(), 30 | //ram_size: 1024, 31 | debug: true, 32 | }; 33 | 34 | let config = FuzzerConfig { 35 | target_binary: None, 36 | bitmap_size: 1 << 16, 37 | time_limit: Duration::from_millis(10000), 38 | spec_path: "../hypertrash_spec/hexaschrott_freebsd.msgp".to_string(), 39 | workdir_path: "/tmp/fuzz_struct_test_debug".to_string(), 40 | mem_limit: 1024, //MB 41 | threads: 1, 42 | thread_id: 0, 43 | }; 44 | 45 | 46 | let runner_cfg = FuzzRunnerConfig::QemuSnapshot(snap_cfg); 47 | 48 | match runner_cfg.clone() { 49 | FuzzRunnerConfig::QemuSnapshot(cfg) => { 50 | let mut runner = qemu_process_new_from_snapshot(&cfg, &config); 51 | 52 | runner.aux.config.timeout_sec = 2; 53 | runner.aux.config.timeout_usec = 500_000; 54 | 55 | let paths = fs::read_dir("/tmp/fuzz_struct_test_bk2/corpus/timeout/").unwrap(); 56 | 57 | for path in paths { 58 | let final_path = path.unwrap().path(); 59 | let path_str = final_path.to_str().unwrap(); 60 | if path_str.ends_with("bin"){ 61 | println!("path: {:?}", final_path); 62 | let mut f = File::open(final_path).expect("no file found"); 63 | f.read(runner.payload).expect("buffer overflow"); 64 | 65 | runner.send_payload(); 66 | 67 | 68 | println!("AUX -> {:?}", runner.aux.result); 69 | if runner.aux.result.timeout_found == 1{ 70 | println!(" ---> TIMEOUT YO"); 71 | } 72 | } 73 | } 74 | 75 | 76 | 77 | 78 | 79 | 80 | //let input_path = "/dev/shm/input_data"; 81 | //let input_mmap = helpers::make_shared_data_from_path(input_path, runner.input_size); 82 | //let srv = ForkServer::new(&cfg, &fuzz_cfg); 83 | 84 | } 85 | _ => unreachable!(), 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | interpreter/.vscode 5 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "structured_fuzzer" 3 | version = "0.1.0" 4 | authors = ["coco "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | rand = "0.7.3" 11 | rand_core="0.5.1" 12 | serde ="1.0.104" 13 | serde_derive ="1.0.104" 14 | rmp-serde ="0.14.3" 15 | itertools="0.9.0" 16 | 17 | [dev-dependencies] 18 | clap="2.33.0" 19 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/examples/display.rs: -------------------------------------------------------------------------------- 1 | //extern crate structured_fuzzer; 2 | extern crate rand; 3 | 4 | use std::fs::File; 5 | 6 | use structured_fuzzer::graph_mutator::graph_storage::{VecGraph}; 7 | use structured_fuzzer::graph_mutator::spec_loader; 8 | use structured_fuzzer::GraphStorage; 9 | use clap::{App, Arg}; 10 | 11 | fn main() { 12 | 13 | let matches = App::new("generator") 14 | .about("Generate strings using a grammar. This can also be used to generate a corpus") 15 | .arg(Arg::with_name("spec_path") 16 | .short("s") 17 | .value_name("SPEC") 18 | .takes_value(true) 19 | .required(true) 20 | .help("Path to the spec.msgp")) 21 | .arg(Arg::with_name("input_path") 22 | .short("i") 23 | .value_name("IN_PATH") 24 | .takes_value(true) 25 | .help("Which .bin file to read")) 26 | .arg(Arg::with_name("output_path") 27 | .short("o") 28 | .value_name("OUT_PATH") 29 | .takes_value(true) 30 | .help("Where to store outputs")) 31 | .arg(Arg::with_name("svg") 32 | .value_name("SVG") 33 | .help("dump output as svg")) 34 | .get_matches(); 35 | 36 | let spec_path = matches 37 | .value_of("spec_path") 38 | .expect("spec_path is a required parameter") 39 | .to_string(); 40 | let input_path = matches.value_of("input_path").expect("input path is a reuqired parameter").to_string(); 41 | let output_path = matches.value_of("output_path").expect("output path is a reuqired parameter").to_string(); 42 | let svg = matches.is_present("svg"); 43 | 44 | let file = File::open(spec_path).unwrap(); 45 | let gs = spec_loader::load_spec_from_read(file); 46 | 47 | let graph = VecGraph::new_from_bin_file(&input_path, &gs); 48 | if svg { 49 | graph.to_svg(&output_path, &gs); 50 | } else { 51 | println!("{}", graph.to_script(&gs)); 52 | graph.write_to_script_file(&output_path, &gs); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/examples/gen.rs: -------------------------------------------------------------------------------- 1 | //extern crate structured_fuzzer; 2 | extern crate rand; 3 | 4 | use std::fs::File; 5 | use std::io::prelude::*; 6 | 7 | use structured_fuzzer::graph_mutator::graph_storage::{VecGraph}; 8 | use structured_fuzzer::graph_mutator::spec_loader; 9 | use structured_fuzzer::mutator::Mutator; 10 | use structured_fuzzer::GraphStorage; 11 | use structured_fuzzer::random::distributions::Distributions; 12 | use structured_fuzzer::custom_dict::CustomDict; 13 | 14 | use clap::{App, Arg, value_t}; 15 | 16 | fn main() { 17 | 18 | let matches = App::new("generator") 19 | .about("Generate strings using a grammar. This can also be used to generate a corpus") 20 | .arg(Arg::with_name("spec_path") 21 | .short("s") 22 | .value_name("SPEC") 23 | .takes_value(true) 24 | .required(true) 25 | .help("Path to the spec.msgp")) 26 | .arg(Arg::with_name("length") 27 | .short("n") 28 | .value_name("LENGTH") 29 | .takes_value(true) 30 | .help("Length of the generated scripts [default: 10]")) 31 | .arg(Arg::with_name("number_of_mutations") 32 | .short("m") 33 | .value_name("NUMBER") 34 | .takes_value(true) 35 | .help("Number of mutations to generate [default: 0]")) 36 | .arg(Arg::with_name("output_path") 37 | .short("o") 38 | .value_name("OUT_PATH") 39 | .takes_value(true) 40 | .help("Where to store outputs")) 41 | .get_matches(); 42 | 43 | let spec_path = matches 44 | .value_of("spec_path") 45 | .expect("spec_path is a required parameter") 46 | .to_string(); 47 | let length = value_t!(matches, "length", usize).unwrap_or(10); 48 | let number_of_mutations = value_t!(matches, "number_of_mutations", usize).unwrap_or(0); 49 | let out_path = matches.value_of("output_path").unwrap_or("./").to_string(); 50 | 51 | 52 | let file = File::open(spec_path).unwrap(); 53 | let gs = spec_loader::load_spec_from_read(file); 54 | //let ops = Box::leak(Box::new([0u16; 512])); 55 | //let data = Box::leak(Box::new([0u8; 512])); 56 | //let mut storage = RefGraph::new(ops, data, Box::leak(Box::new(0)), Box::leak(Box::new(0))); 57 | let mut storage = VecGraph::empty(); 58 | let mut mutator = Mutator::new(gs); 59 | let dist = Distributions::new(); 60 | mutator.generate(length, &mut storage, &dist); 61 | let graph = mutator.dump_graph(&storage); 62 | let mut file = File::create(&format!("{}/out.dot",out_path)).unwrap(); 63 | graph.to_svg(&format!("{}/out.svg",out_path), &mutator.spec); 64 | file.write_all(&graph.to_dot(&mutator.spec).as_bytes()).unwrap(); 65 | 66 | let queue = vec!(graph); 67 | let graph = &queue[0]; 68 | 69 | let cnt = number_of_mutations; 70 | for i in 0..cnt { 71 | if cnt > 100 && i % (cnt / 100) == 0 { 72 | println!("mutating {}%...", i / (cnt / 100)); 73 | } 74 | let strategy = mutator.mutate(graph, &CustomDict::new(), &queue, &mut storage, &dist); 75 | let g2 = mutator.dump_graph(&storage); 76 | let mut file = File::create(format!("{}/out_mut_{}_{}.dot", out_path, strategy.name(), i)).unwrap(); 77 | file.write_all(&g2.to_dot(&mutator.spec).as_bytes()).unwrap(); 78 | g2.to_svg(&format!("{}/out_mut_{}_{}.svg",out_path,strategy.name(), i), &mutator.spec); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/.gitignore: -------------------------------------------------------------------------------- 1 | input.bin 2 | interpreter 3 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/structured_fuzzer/interpreter/build/a.out -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/bytecode_spec.h: -------------------------------------------------------------------------------- 1 | //------------------------- 2 | // Move this file to bytecode_spec.h 3 | // and implemented in user spec part 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "data_include.h" 11 | 12 | /** 13 | 14 | typedef char* t_path; 15 | 16 | typedef int t_fd; 17 | 18 | typedef struct{ void* data; size_t size} t_mmap_buffer; 19 | 20 | **/ 21 | 22 | 23 | void handler_path(d_vec_path_string path_string, t_path* output_0){ 24 | printf("path: %.*s\n",path_string.count, path_string.vals); 25 | *output_0 = "/etc/passwd"; 26 | } 27 | 28 | void handler_open(t_path* borrow_0, t_fd* output_0){ 29 | *output_0 = open(*borrow_0, O_RDONLY); 30 | printf("open(%s) = %d\n",*borrow_0, *output_0); 31 | } 32 | 33 | void handler_fd_0(t_fd* output_0){ 34 | printf("fd:0\n"); 35 | *output_0 = 0; 36 | } 37 | 38 | void handler_dup2(t_fd* borrow_0, t_fd* borrow_1){ 39 | printf("dup2( %d, %d)\n", *borrow_0, *borrow_1); 40 | dup2(*borrow_0, *borrow_1); 41 | } 42 | 43 | void handler_mmap(d_flags flags, t_fd* borrow_0, t_mmap_buffer* output_0){ 44 | printf("nope no mmpa\n"); 45 | } 46 | 47 | void handler_close(t_fd* input_0){ 48 | printf("close(%d)\n", *input_0); 49 | close(*input_0); 50 | } 51 | 52 | void handler_read(t_fd* borrow_0){ 53 | printf("read from %d\n", *borrow_0); 54 | } 55 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/bytecode_spec.template.h: -------------------------------------------------------------------------------- 1 | //------------------------- 2 | // Move this file to bytecode_spec.h 3 | // and implemented in user spec part 4 | 5 | //includes 6 | 7 | 8 | /** 9 | 10 | **/ 11 | 12 | void interpreter_user_init(interpreter_t *vm){ 13 | } 14 | 15 | void interpreter_user_shutdown(interpreter_t *vm){ 16 | } 17 | 18 | 19 | void handler_data(d_vec_d_bytes *data_d_bytes){ 20 | } 21 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/data_include.h: -------------------------------------------------------------------------------- 1 | 2 | typedef uint8_t d_u8; 3 | typedef struct {size_t count; d_u8* vals; } d_vec_d_bytes; -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/interpreter.h: -------------------------------------------------------------------------------- 1 | //ALL OF THIS IS AUTO GENERATED, DO NOT CHANGE. CHANGE interpreter.jinja.h and regenerate! 2 | #ifndef __INTERPRETER__GEN__ 3 | #define __INTERPRETER__GEN__ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define ASSERT(x) assert(x) 11 | #define STATIC_ASSERT(cond, desc) _Static_assert(cond, desc) 12 | 13 | #define INTERPRETER_CHECKSUM 17206576842326037323ULL 14 | 15 | 16 | #define OP_DATA 0 17 | #define OP_DATA_SIZE 1 18 | 19 | 20 | #include "data_include.h" 21 | 22 | typedef struct { 23 | uint16_t* ops; 24 | size_t ops_len; 25 | size_t ops_i; 26 | 27 | uint8_t* data; 28 | size_t data_len; 29 | size_t data_i; 30 | 31 | 32 | 33 | } interpreter_t; 34 | 35 | 36 | #include "bytecode_spec.h" 37 | 38 | //========================= 39 | //atomic data type functions 40 | //========================= 41 | 42 | d_vec_d_bytes read_d_vec_d_bytes(interpreter_t* vm){ 43 | d_vec_d_bytes res = {0}; 44 | ASSERT(vm->data_i+2 <= vm->data_len); 45 | uint16_t byte_size = *((uint16_t*)&vm->data[vm->data_i]); 46 | vm->data_i+=2; 47 | ASSERT(vm->data_i+byte_size <= vm->data_len); 48 | res.count = ((size_t)byte_size)/sizeof(d_u8); 49 | res.vals = (d_u8*)&(vm->data[vm->data_i+2]); 50 | vm->data_i += byte_size; 51 | 52 | return res; 53 | } 54 | 55 | 56 | //========================= 57 | //edge type functions 58 | //========================= 59 | 60 | 61 | //========================= 62 | //interpreter functions 63 | //========================= 64 | 65 | interpreter_t* new_interpreter(){ 66 | interpreter_t* vm = malloc(sizeof(interpreter_t)); 67 | vm->ops = 0; 68 | vm->ops_len = 0; 69 | vm->data = 0; 70 | vm->data_len = 0; 71 | 72 | 73 | 74 | return vm; 75 | } 76 | 77 | void init_interpreter(interpreter_t* vm, uint16_t* ops, size_t ops_len, uint8_t* data, size_t data_len){ 78 | vm->ops=ops; 79 | vm->ops_len=ops_len; 80 | vm->ops_i = 0; 81 | vm->data = data; 82 | vm->data_i = 0; 83 | vm->data_len=data_len; 84 | } 85 | 86 | void run(interpreter_t* vm){ 87 | ASSERT(vm->ops && vm->data && vm->ops_i == 0 && vm->data_i == 0); //init_interpreter was called previously 88 | while(vm->ops_i < vm->ops_len) { 89 | uint16_t op = vm->ops[vm->ops_i]; 90 | switch(op){ 91 | 92 | case OP_DATA: 93 | ASSERT( vm->ops_len >= vm->ops_i + OP_DATA_SIZE ); 94 | handler_data(read_d_vec_d_bytes(vm)); 95 | vm->ops_i += OP_DATA_SIZE; 96 | 97 | break; 98 | default: 99 | ASSERT(0); 100 | } 101 | } 102 | } 103 | 104 | #endif -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/interpreter_main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "interpreter.h" 11 | 12 | uint8_t* mmap_file(const char* path, size_t* size){ 13 | uint8_t *memblock; 14 | 15 | int fd; 16 | struct stat sb; 17 | 18 | fd = open(path, O_RDWR); 19 | fstat(fd, &sb); 20 | //printf("Size: %lu\n", (uint64_t)sb.st_size); 21 | 22 | memblock = mmap(NULL, sb.st_size, PROT_WRITE, MAP_SHARED, fd, 0); 23 | if(memblock==(void*)-1){ 24 | perror("mmap failed"); 25 | exit(0); 26 | } 27 | 28 | *size = sb.st_size; 29 | return memblock; 30 | } 31 | 32 | void main(int argc, char** argv){ 33 | assert(argc >= 2); 34 | size_t size = 0; 35 | uint8_t* mem = mmap_file(argv[1], &size); 36 | uint64_t* offsets = (uint64_t*)mem; 37 | assert(size > sizeof(uint64_t)*5); 38 | assert(offsets[0] == INTERPRETER_CHECKSUM); 39 | assert(offsets[1] < 0xffffff); 40 | assert(offsets[2] < 0xffffff); 41 | assert(offsets[3] < 0xffffff); 42 | assert(offsets[4] < 0xffffff); 43 | uint64_t graph_size = offsets[1]; 44 | uint64_t data_size = offsets[2]; 45 | uint16_t* graph_ptr = (uint16_t*)(mem+offsets[3]); 46 | uint8_t* data_ptr = (uint8_t*)(mem+offsets[4]); 47 | assert(offsets[3]+graph_size*sizeof(uint16_t) <= size); 48 | assert(offsets[4]+data_size <= size); 49 | interpreter_t* vm = new_interpreter(); 50 | init_interpreter(vm, graph_ptr, graph_size, data_ptr, data_size); 51 | interpreter_user_init(vm); 52 | run(vm); 53 | interpreter_user_shutdown(vm); 54 | } 55 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/make.sh: -------------------------------------------------------------------------------- 1 | gcc interpreter_main.c -ggdb -o interpreter 2 | ./interpreter ./input.bin 3 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/build/spec.msgp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/structured_fuzzer/interpreter/build/spec.msgp -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/example_spec.msgp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/structured_fuzzer/interpreter/example_spec.msgp -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/example_spec.py: -------------------------------------------------------------------------------- 1 | from spec_lib.graph_spec import * 2 | from spec_lib.data_spec import * 3 | from spec_lib.graph_builder import * 4 | from spec_lib.generators import opts 5 | 6 | s = Spec() 7 | 8 | t_path = s.edge_type("path", c_type="char*"); 9 | t_fd = s.edge_type("fd", c_type="int"); 10 | t_mmap_buffer = s.edge_type("mmap_buffer", c_type="struct{ void* data; size_t size; }"); 11 | 12 | #d_string = s.data_type("string", size=(0,10) ); 13 | 14 | OPT_FOO = 1 15 | OPT_BAR = 42 16 | OPT_BAZ = 1337 17 | 18 | #d_flags = s.data_u32("flags") 19 | d_flags = s.data_u32("flags", [opts(OPT_FOO,OPT_BAR,OPT_BAZ)] ) 20 | d_char = s.data_u8("char") 21 | 22 | d_string = s.data_vec("path_string", d_char, (5,100)) 23 | 24 | d_foo = s.data_struct("foo") 25 | d_foo.u8("bla") 26 | d_foo.field("flags",d_flags) 27 | d_foo.u32("fuu") 28 | d_foo.finalize() 29 | 30 | n_path = s.node_type("path", outputs=[t_path], data=d_string) 31 | n_open = s.node_type("open", borrows=[t_path], outputs=[t_fd]) 32 | n_stdo = s.node_type("fd_0", outputs=[t_fd]) 33 | n_dup2 = s.node_type("dup2", borrows=[t_fd, t_fd]) 34 | n_mmap = s.node_type("mmap", borrows=[t_fd], outputs=[t_mmap_buffer], data=d_flags) 35 | n_close = s.node_type("close", inputs=[t_fd]) 36 | n_read = s.node_type("read", borrows=[t_fd]) 37 | 38 | s.build_interpreter() 39 | 40 | import msgpack 41 | serialized_spec = s.build_msgpack() 42 | with open("example_spec.msgp","wb") as f: 43 | f.write(msgpack.packb(serialized_spec)) 44 | 45 | b = Builder(s) 46 | 47 | p = b.path() 48 | fd1 = b.open(p) 49 | fd2 = b.fd_0() 50 | b.dup2(fd1,fd2) 51 | b.read(fd2) 52 | b.mmap(fd2) 53 | 54 | b.write_to_file("build/input.bin") 55 | print(repr(b.ops)) 56 | 57 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__ 3 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/__init__.py -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/data_spec.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | class StructDataType: 4 | def __init__(self, spec, name): 5 | self.spec = spec 6 | self.name = name 7 | self.emit_reader = False 8 | self.fixed_size = True 9 | self.size=0 10 | self.fields = [] 11 | self.c_type_name = "d_"+name 12 | self.c_type_def = self.get_c_type_def() 13 | 14 | def finalize(self): 15 | self.d_id = self.spec.finalize_struct(self) 16 | self.spec = None 17 | 18 | def get_c_type_def(self): 19 | template = self.spec.tmpl.get_template("templates/data_struct.jinja.h") 20 | return template.render(struct=self) 21 | 22 | def field(self, name, dtype): 23 | self.size += dtype.size 24 | self.fields.append((name, dtype)) 25 | self.c_type_def = self.get_c_type_def() 26 | return self 27 | 28 | def u64(self, name, generators=[]): 29 | field_type = self.spec.data_u64(self.name+"_"+name, generators) 30 | self.field(name, field_type) 31 | return field_type 32 | 33 | def u32(self, name, generators=[]): 34 | field_type = self.spec.data_u32(self.name+"_"+name, generators) 35 | self.field(name, field_type) 36 | return field_type 37 | 38 | def u16(self, name,generators=[]): 39 | field_type = self.spec.data_u16(self.name+"_"+name,generators) 40 | self.field(name, field_type) 41 | return field_type 42 | 43 | def u8(self, name,generators=[]): 44 | field_type = self.spec.data_u8(self.name+"_"+name,generators) 45 | self.field(name, field_type) 46 | return field_type 47 | 48 | def msgpack(self): 49 | return ["Struct", self.name, [[name,dtype.d_id] for (name,dtype) in self.fields]] 50 | 51 | 52 | class IntDataType: 53 | def __init__(self, d_id, name, size, generators=[]): 54 | assert(size in [1,2,4,8]) 55 | self.d_id = d_id 56 | self.name = name 57 | self.emit_reader = False 58 | self.fixed_size = True 59 | self.size = size 60 | self.generators = generators 61 | self.c_type_name = "d_"+self.name 62 | self.c_type_def = "typedef %s %s;"%("uint%d_t"%(size*8), self.c_type_name) 63 | 64 | def msgpack(self): 65 | print(repr((self.name,self.c_type_name,self.generators))) 66 | return ["Int", self.name, self.size,[g.msgpack() for g in self.generators]] 67 | 68 | 69 | class VecDataType: 70 | def __init__(self, d_id, name, dtype, size_range): 71 | assert(dtype.fixed_size); 72 | self.d_id = d_id 73 | self.name = name 74 | self.emit_reader = False 75 | self.fixed_size = False 76 | self.size_range = size_range 77 | self.dtype = dtype 78 | self.c_type_name = "d_vec_"+self.name 79 | self.c_type_def = "typedef struct {size_t count; %s* vals; } %s;"%(self.dtype.c_type_name, self.c_type_name) 80 | 81 | def msgpack(self): 82 | return ["Vec", self.name, [self.size_range[0], self.size_range[1]], self.dtype.d_id] 83 | 84 | class ArrayDataType: 85 | def __init__(self, d_id, name, dtype, count): 86 | assert(dtype.fixed_size); 87 | self.d_id = d_id 88 | self.name = name 89 | self.emit_reader = False 90 | self.fixed_size = True 91 | self.size = count*dtype.size 92 | self.dtype = dtype -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/generators.py: -------------------------------------------------------------------------------- 1 | class FixedOptionsGenerator: 2 | def __init__(self,*options): 3 | self.options=options 4 | 5 | def msgpack(self): 6 | return ["Options",self.options] 7 | 8 | def opts(*options): 9 | return FixedOptionsGenerator(*options) 10 | 11 | class FixedFlagsGenerator: 12 | def __init__(self,*options): 13 | self.flags=options 14 | 15 | def msgpack(self): 16 | return ["Flags",self.flags] 17 | 18 | def flags(*options): 19 | return FixedOptionsGenerator(*options) 20 | 21 | class LimitsGenerator: 22 | def __init__(self,min,max,align): 23 | self.min=min 24 | self.max=max 25 | self.align = align 26 | 27 | def msgpack(self): 28 | return ["Limits",(self.min,self.max),self.align] 29 | 30 | def limits(min,max,align=1): 31 | return LimitsGenerator(min,max,align) -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/graph_builder.py: -------------------------------------------------------------------------------- 1 | from spec_lib.graph_spec import * 2 | from spec_lib.data_spec import * 3 | 4 | import string 5 | 6 | class BuilderValue: 7 | def __init__(self, value_type, id): 8 | self.value_type = value_type 9 | self.id = id 10 | self.unused=True 11 | 12 | class Builder: 13 | def __init__(self, spec): 14 | self.spec = spec 15 | self.ops = [] 16 | self.data = b"" 17 | self.value_to_id = {} 18 | for n in spec.nodes: 19 | def build(node): 20 | return lambda *args: self.build_node(node.name, *args) 21 | setattr(self, n.name, build(n)) 22 | 23 | def build_node(self, name, *args): 24 | node = self.spec.name_to_node[name] 25 | assert(len(args) == len(node.inputs)+len(node.borrows)) 26 | self.ops.append(node.id) 27 | for (i,val) in enumerate(node.inputs): 28 | assert(args[i].value_type == val) 29 | assert(args[i].unused) 30 | self.ops.append(args[i].id) 31 | args[i].unused=False 32 | for(i, val) in enumerate(node.borrows): 33 | j = len(node.inputs)+i 34 | assert(args[j].value_type == val) 35 | assert(args[j].unused) 36 | self.ops.append(args[j].id) 37 | 38 | self.build_data(node.data) 39 | 40 | res = [] 41 | for val in node.outputs: 42 | b_val = self.build_value(val) 43 | res.append(b_val) 44 | self.ops.append(b_val.id) 45 | if len(res) == 1: 46 | return res[0] 47 | return res 48 | 49 | def build_data(self,dat): 50 | if not dat: 51 | return 52 | if not dat.fixed_size: 53 | assert(len(dat.size_range)==2) 54 | n = random.randrange(dat.size_range[0], dat.size_range[1]) 55 | self.data+=struct.pack("H",n) 56 | else: 57 | n = dat.size 58 | print("generate data: %d %s"%(n,repr(dat))) 59 | data = bytes(''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(n)), "ascii") 60 | self.data += data 61 | 62 | 63 | def build_value(self, val): 64 | if val not in self.value_to_id: 65 | self.value_to_id[val] = 0 66 | vid = self.value_to_id[val] 67 | self.value_to_id[val]+=1 68 | return BuilderValue(val, vid) 69 | 70 | def write_to_file(self, path): 71 | graph_size = len(self.ops) 72 | data_size = len(self.data) 73 | base = 5*8 74 | graph_offset = base 75 | data_offset = graph_offset+2*graph_size 76 | header = struct.pack(" 0 else "" -}} 27 | {%- endif -%} 28 | {%- if ntype.data -%} 29 | {{ntype.data.c_type_name}} *data_{{ntype.data.name}} 30 | {{-", " if ntype.args|length > 0 else "" -}} 31 | {% endif -%} 32 | {%- for (val,varname) in ntype.args -%} 33 | t_{{val.name}}* {{varname}} 34 | {{- ", " if not loop.last else ""-}} 35 | {%- endfor -%} 36 | ){ 37 | {{ ntype.handler_code -}} 38 | } 39 | {% endfor %} 40 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/templates/data_include.jinja.h: -------------------------------------------------------------------------------- 1 | {% for ttype in values %} 2 | typedef {{ttype.c_type}} t_{{ttype.name}}; 3 | {% endfor %} 4 | 5 | {%- for dtype in data_types %} 6 | {{dtype.c_type_def}} 7 | {%- endfor %} -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_lib/templates/data_struct.jinja.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma pack(1) 3 | typedef struct { 4 | {%- for (field_name, field_type) in struct.fields %} 5 | {{field_type.c_type_name}} {{field_name}}; 6 | {%- endfor %} 7 | } {{struct.c_type_name}}; -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_vec_u8.msgp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/structured_fuzzer/interpreter/spec_vec_u8.msgp -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/spec_vec_u8.py: -------------------------------------------------------------------------------- 1 | from spec_lib.graph_spec import * 2 | from spec_lib.data_spec import * 3 | from spec_lib.graph_builder import * 4 | 5 | 6 | s = Spec() 7 | 8 | d_bytes = s.data_vec("d_bytes", s.data_u8("u8"), size_range=(0,1<<4)) 9 | 10 | n_path = s.node_type("data", data=d_bytes) 11 | 12 | s.build_interpreter() 13 | 14 | import msgpack 15 | serialized_spec = s.build_msgpack() 16 | with open("spec_vec_u8.msgp","wb") as f: 17 | f.write(msgpack.packb(serialized_spec)) 18 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/test_spec.msgp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/nyx_fuzzer/structured_fuzzer/interpreter/test_spec.msgp -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/interpreter/test_spec.py: -------------------------------------------------------------------------------- 1 | from spec_lib.graph_spec import * 2 | from spec_lib.data_spec import * 3 | from spec_lib.graph_builder import * 4 | 5 | 6 | s = Spec() 7 | 8 | t_a = s.edge_type("a", c_type="int"); 9 | 10 | d_int = s.data_u32("a_data") 11 | 12 | n_path = s.node_type("start", outputs=[t_a], data=d_int) 13 | n_path = s.node_type("inc", borrows=[t_a]) 14 | n_open = s.node_type("stop", inputs=[t_a]) 15 | 16 | s.build_interpreter() 17 | 18 | import msgpack 19 | serialized_spec = s.build_msgpack() 20 | with open("test_spec.msgp","wb") as f: 21 | f.write(msgpack.packb(serialized_spec)) 22 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/custom_dict.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use crate::data_buff::DataBuff; 4 | use crate::random::distributions::Distributions; 5 | 6 | #[derive(Clone)] 7 | pub enum DictEntry{ 8 | Replace(Vec, Vec) 9 | } 10 | 11 | #[derive(Clone)] 12 | pub struct CustomDict{ 13 | groups: Vec>, 14 | lhs_to_groups: HashMap,Vec>>, 15 | } 16 | 17 | impl CustomDict{ 18 | pub fn new() -> Self{ 19 | return Self{groups: vec!(), lhs_to_groups: HashMap::new()} 20 | } 21 | 22 | pub fn new_from_groups(groups: Vec>) -> Self{ 23 | let mut lhs_to_groups = HashMap::new(); 24 | for group in groups.iter() { 25 | for entry in group.iter() { 26 | match entry { 27 | DictEntry::Replace(lhs, rhs) => { 28 | let entry = lhs_to_groups.entry(lhs.clone()).or_insert_with(|| vec!()); 29 | entry.push(rhs.clone()); 30 | } 31 | } 32 | } 33 | } 34 | return Self{groups, lhs_to_groups} 35 | } 36 | 37 | pub fn len(&self) -> usize { 38 | return self.groups.len(); 39 | } 40 | 41 | pub fn mutate(&self, buff: &mut DataBuff, dist: &Distributions) -> bool { 42 | if let Some(rhs) = self.sample_rhs(buff, dist) { 43 | if dist.gen(){ 44 | buff.copy_from(&rhs, 0); 45 | return dist.gen::(); 46 | } 47 | } 48 | if let Some(entry) = self.sample_entry(buff,dist){ 49 | match entry{ 50 | DictEntry::Replace(lhs, rhs) => { 51 | if let Some(pos) = self.find_pos(buff, &lhs, dist){ 52 | buff.copy_from(&rhs, pos); 53 | } 54 | return dist.gen::(); 55 | } 56 | } 57 | } 58 | return true; 59 | } 60 | 61 | pub fn sample_rhs(&self, buff: &DataBuff, dist: &Distributions) -> Option<&Vec> { 62 | if self.lhs_to_groups.contains_key(buff.as_slice()) { 63 | let opts = &self.lhs_to_groups[buff.as_slice()]; 64 | assert!(opts.len() > 0); 65 | return Some(&opts[dist.gen_range(0, opts.len())]); 66 | } 67 | return None 68 | } 69 | 70 | pub fn sample_entry(&self, buff: &DataBuff, dist: &Distributions) -> Option<&DictEntry> { 71 | if self.groups.len() == 0 {return None} 72 | let group = &self.groups[dist.gen_range(0,self.groups.len())]; 73 | return Some(&group[dist.gen_range(0,group.len())]); 74 | } 75 | 76 | pub fn find_pos(&self, buff: &DataBuff, lhs: &[u8], dist: &Distributions) -> Option{ 77 | let mut offsets = vec!(); 78 | for (i,win) in buff.as_slice().windows(lhs.len()).enumerate() { 79 | if win == lhs { 80 | offsets.push(i); 81 | } 82 | } 83 | if offsets.len() > 0 { 84 | return Some(offsets[dist.gen_range(0,offsets.len())]); 85 | } 86 | if buff.len() >= lhs.len(){ 87 | return Some(dist.gen_range(0,buff.len()-lhs.len()+1)); 88 | } 89 | return None 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/graph_mutator/generators.rs: -------------------------------------------------------------------------------- 1 | use crate::random::distributions::Distributions; 2 | 3 | #[derive(Debug, PartialEq, Deserialize, Serialize, Clone)] 4 | #[serde(tag = "type")] 5 | pub enum IntGenerator{ 6 | Options{opts: Vec}, 7 | Flags{opts: Vec}, 8 | Limits{range:(u64, u64), align: u64}, 9 | } 10 | 11 | impl IntGenerator{ 12 | pub fn generate(&self, dist: &Distributions) -> (u64,bool){ 13 | use IntGenerator::*; 14 | match self { 15 | Options{opts} => (opts[dist.gen_range(0,opts.len())],false), 16 | Flags{opts} => (opts[dist.gen_range(0,opts.len())],false), 17 | Limits{range,align} => { 18 | let mut val = dist.gen_range(range.0,range.1); 19 | val = val-(val%align); 20 | if val < range.0 {val+=align} 21 | if val > range.1 {val-=align} 22 | (val,false) 23 | }, 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/graph_mutator/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod atomic_data; 2 | pub mod graph_builder; 3 | pub mod graph_iter; 4 | pub mod graph_storage; 5 | pub mod newtypes; 6 | pub mod spec; 7 | pub mod spec_loader; 8 | pub mod generators; -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/graph_mutator/newtypes.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 2 | #[repr(transparent)] 3 | pub struct PortID(u16); 4 | impl PortID { 5 | pub fn new(x: u16) -> Self { 6 | Self(x) 7 | } 8 | pub fn next(self) -> Self { 9 | Self(self.0 + 1) 10 | } 11 | pub fn as_u16(self) -> u16 { 12 | self.0 13 | } 14 | pub fn as_usize(self) -> usize { 15 | self.0 as usize 16 | } 17 | } 18 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 19 | #[repr(transparent)] 20 | pub struct OpIndex(usize); 21 | impl OpIndex { 22 | pub fn new(x: usize) -> Self { 23 | Self(x) 24 | } 25 | pub fn as_usize(self) -> usize { 26 | return self.0; 27 | } 28 | } 29 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 30 | #[repr(transparent)] 31 | pub struct NodeTypeID(u16); 32 | impl NodeTypeID { 33 | pub fn new(x: u16) -> Self { 34 | Self(x) 35 | } 36 | pub fn as_u16(self) -> u16 { 37 | return self.0; 38 | } 39 | pub fn as_usize(self) -> usize { 40 | return self.0 as usize; 41 | } 42 | } 43 | 44 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 45 | #[repr(transparent)] 46 | pub struct AtomicTypeID(usize); 47 | impl AtomicTypeID { 48 | pub fn new(x: usize) -> Self { 49 | Self(x) 50 | } 51 | pub fn as_usize(self) -> usize { 52 | return self.0; 53 | } 54 | } 55 | 56 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 57 | #[repr(transparent)] 58 | pub struct ValueTypeID(u16); 59 | impl ValueTypeID { 60 | pub fn new(x: u16) -> Self { 61 | Self(x) 62 | } 63 | pub fn as_usize(self) -> usize { 64 | return self.0 as usize; 65 | } 66 | } 67 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 68 | #[repr(transparent)] 69 | pub struct ConnectorID(u16); 70 | impl ConnectorID { 71 | pub fn new(x: u16) -> Self { 72 | Self(x) 73 | } 74 | pub fn next(self) -> Self { 75 | Self(self.0 + 1) 76 | } 77 | pub fn as_u16(self) -> u16 { 78 | return self.0; 79 | } 80 | } 81 | 82 | #[derive(Debug)] 83 | pub enum GraphError { 84 | UnknownNodeType(NodeTypeID), 85 | UnknownValueType(ValueTypeID), 86 | UnknownDataType(AtomicTypeID), 87 | UnknownID(ConnectorID), 88 | MissingInput(), 89 | InvalidSpecs, 90 | } 91 | 92 | #[derive(Eq, PartialEq, Debug, Clone)] 93 | pub struct SrcVal { 94 | pub id: OpIndex, 95 | pub port: PortID, 96 | } 97 | impl SrcVal { 98 | pub fn new(id: OpIndex, port: PortID) -> Self { 99 | Self { id, port } 100 | } 101 | } 102 | #[derive(Eq, PartialEq, Debug, Clone)] 103 | pub struct DstVal { 104 | pub id: OpIndex, 105 | pub port: PortID, 106 | } 107 | impl DstVal { 108 | pub fn new(id: OpIndex, port: PortID) -> Self { 109 | Self { id, port } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/primitive_mutator/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/primitive_mutator/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod inplace_mutation; 2 | pub mod mutator; 3 | pub mod size_changing_mutation; 4 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/primitive_mutator/mutations.txt: -------------------------------------------------------------------------------- 1 | Text based mutations 2 | 3 | 4 | size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize); 5 | /// Mutates data by invoking user-provided crossover. 6 | size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize); 7 | /// Mutates data by shuffling bytes. 8 | size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize); 9 | /// Mutates data by erasing bytes. 10 | size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize); 11 | /// Mutates data by inserting a byte. 12 | size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize); 13 | /// Mutates data by inserting several repeated bytes. 14 | size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize); 15 | /// Mutates data by chanding one byte. 16 | size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize); 17 | /// Mutates data by chanding one bit. 18 | size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize); 19 | /// Mutates data by copying/inserting a part of data into a different place. 20 | size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize); -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/primitive_mutator/size_changing_mutation.rs: -------------------------------------------------------------------------------- 1 | use crate::data_buff::DataBuff; 2 | use std::ops::Range; 3 | 4 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 5 | pub enum SizeChangingMutationType { 6 | DeleteT, 7 | InsertChunkT, 8 | InsertFixedT, 9 | InsertRandomT, 10 | } 11 | 12 | impl SizeChangingMutationType { 13 | pub fn min_size(&self) -> usize { 14 | use SizeChangingMutationType::*; 15 | match self { 16 | DeleteT => return 8, 17 | InsertChunkT | InsertFixedT | InsertRandomT => return 1, 18 | } 19 | } 20 | pub fn min_available(&self) -> usize { 21 | use SizeChangingMutationType::*; 22 | match self { 23 | DeleteT => return 0, 24 | InsertChunkT | InsertFixedT | InsertRandomT => return 16, 25 | } 26 | } 27 | } 28 | 29 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] 30 | pub enum SizeChangingMutation { 31 | Delete { block: Range }, 32 | InsertChunk { src: Range, dst: usize }, 33 | InsertFixed { amount: usize, val: u8, dst: usize }, 34 | InsertRandom { data: Vec, dst: usize }, 35 | } 36 | 37 | impl SizeChangingMutation { 38 | pub fn apply(&self, buff: &mut DataBuff) { 39 | use SizeChangingMutation::*; 40 | match self { 41 | Delete { block } => buff.drop(block), 42 | InsertChunk { src, dst } => { 43 | buff.shift_every_after(*dst, src.end - src.start); 44 | buff.copy_within(&src, *dst); 45 | } 46 | InsertFixed { dst, amount, val } => { 47 | buff.shift_every_after(*dst, *amount); 48 | buff.memset(&(*dst..dst + amount), *val); 49 | } 50 | InsertRandom { data, dst } => { 51 | buff.shift_every_after(*dst, data.len()); 52 | buff.copy_from(data, *dst); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/random/choices.rs: -------------------------------------------------------------------------------- 1 | use rand::distributions::weighted::alias_method::WeightedIndex; 2 | use rand::prelude::*; 3 | 4 | pub struct Choices { 5 | weights: WeightedIndex, 6 | options: Vec, 7 | } 8 | 9 | impl Choices { 10 | pub fn new(weights: Vec, options: Vec) -> Self { 11 | let weights = WeightedIndex::new(weights).unwrap(); 12 | return Self { weights, options }; 13 | } 14 | 15 | pub fn sample<'a, R: Rng>(&'a self, rng: &mut R) -> &'a T { 16 | let i = self.weights.sample(rng); 17 | return &self.options[i]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/random/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod choices; 2 | pub mod distributions; 3 | pub mod romu; 4 | -------------------------------------------------------------------------------- /nyx_fuzzer/structured_fuzzer/src/random/romu.rs: -------------------------------------------------------------------------------- 1 | use rand::SeedableRng; 2 | use rand_core::{impls, Error, RngCore}; 3 | 4 | pub struct RomuPrng { 5 | xstate: u64, 6 | ystate: u64, 7 | } 8 | 9 | impl RomuPrng { 10 | pub fn new(xstate: u64, ystate: u64) -> Self { 11 | return Self { xstate, ystate }; 12 | } 13 | } 14 | 15 | impl SeedableRng for RomuPrng { 16 | type Seed = [u8; 16]; 17 | 18 | fn from_seed(seed: [u8; 16]) -> RomuPrng { 19 | if seed == [0; 16] { 20 | return RomuPrng::new(0x0DDB1A5E5BAD5EEDu64, 0x519fb20ce6a199bbu64); 21 | } 22 | let x = u64::from_le_bytes([ 23 | seed[0], seed[1], seed[2], seed[3], seed[4], seed[5], seed[6], seed[7], 24 | ]); 25 | let y = u64::from_le_bytes([ 26 | seed[8], seed[9], seed[10], seed[11], seed[12], seed[13], seed[14], seed[15], 27 | ]); 28 | return RomuPrng::new(x, y); 29 | } 30 | } 31 | 32 | impl RngCore for RomuPrng { 33 | fn next_u32(&mut self) -> u32 { 34 | self.next_u64() as u32 35 | } 36 | 37 | fn next_u64(&mut self) -> u64 { 38 | let xp = self.xstate; 39 | self.xstate = 15241094284759029579u64.wrapping_mul(self.ystate); 40 | self.ystate = self.ystate.wrapping_sub(xp); 41 | self.ystate = self.ystate.rotate_left(27); 42 | return xp; 43 | } 44 | 45 | fn fill_bytes(&mut self, dest: &mut [u8]) { 46 | impls::fill_bytes_via_next(self, dest) 47 | } 48 | 49 | fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { 50 | Ok(self.fill_bytes(dest)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RUB-SysSec/Nyx/e3bb1bac3625ac1b8cecdd157ea61cb03430543e/paper.png --------------------------------------------------------------------------------