Git Product home page Git Product logo

tandasat / hypervisor-101-in-rust Goto Github PK

View Code? Open in Web Editor NEW
966.0 14.0 64.0 16.02 MB

The materials of "Hypervisor 101 in Rust", a one-day long course, to quickly learn hardware-assisted virtualization technology and its application for high-performance fuzzing on Intel/AMD processors.

Home Page: https://tandasat.github.io/Hypervisor-101-in-Rust/

License: MIT License

Rust 92.73% Assembly 4.95% Python 2.14% NSIS 0.18%
fuzzing hypervisor rust uefi

hypervisor-101-in-rust's Introduction

Hypervisor 101 in Rust

The materials of the "Hypervisor 101 in Rust" class held at Global Cybersecurity Camp 2023 Singapore. This repository contains a fuzzing hypervisor for UEFI on Intel/AMD processors, lecture and hands-on exercise materials, and sample corpus and target files.

Read the course at https://tandasat.github.io/Hypervisor-101-in-Rust/

Directory structure

  • 📖course/ for the class materials
  • 🦀hypervisor/ for source code and a detailed description of the fuzzing hypervisor
  • ⚙️BUILDING.md for building and running the hypervisor with sample files under tests/

Course format

The class materials are designed for an interactive classroom setting and less effective for self-learning due to light explanations. We decided to publish this as it would still be useful to some, however. If you are interested in the interactive class with the author, please check out the schedule of the next public class at System Programming Lab.

Supported platforms

  • Host (class and development) environment
    • 📎Windows + WSL
    • 🍎macOS
    • 🐧Ubuntu
    • Apple Silicon-based macOS, ARM64-based Windows and Ubuntu are also supported. No x64 system required.
  • Test (target) environment
    • Hardware
      • Bochs
      • VMware Fusion or Workstation Pro (if a host has Intel or AMD processors)
      • Select bare metal models
    • with UEFI

Acknowledgements

  • Andrew Burkett (@drewkett) and Rich Seymour (@rseymour) for mentoring me about Rust
  • Karsten König (@gr4yf0x) and Amir Bazine for encouraging me looking into use of hypervisors for fuzzing
  • Brandon Falk (@gamozolabs) for his inspirational work, Falkvisor

hypervisor-101-in-rust's People

Contributors

0xhcf avatar hexhexd avatar tandasat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hypervisor-101-in-rust's Issues

Cannot run hypervisor

image
image
After executing cargo xtask bochs-amd the program is stuck. Am I doing something wrong?

Getting the coverage

I'd like to get the coverage of the .efi file like here:

I don't really understand how to do it. I ran the following command:

cargo xtask bochs-amd | tee coverage.log

Then i loaded the refind_x64_signed_at_0xDD15000.efi into the Ida 7.6 and fed it the script ida_highlight_coverage.py (file -> Script File...) and provided the coverage.log. I got the following error:

image

And the problem is, that it's trying to highlight the addreses starting with like 0xdd2....

While in Ida, my file is loaded at 0x00 adress. Maybe i need to rebase it, but how would i know to which adress?

I think we really need the more in-depth documentation about getting the coverage about getting the coverage. There are not many such materials in the internet and it would be really useful to have one documented.

Also don't forget to explain how can we prepare our own efi files for getting the coverage from them.

P.s Thanks for such a good material

Run bochs failed with Segmentation fault

I'm tring to follow the instruction of https://github.com/tandasat/Hypervisor-101-in-Rust/blob/main/BUILDING.md to build and run hypervisor on bochs. But failed,

probelm 1: compiling bochs with default parameters causes arg '-rc' was not understood.

I tried to add --enable-debugger into bochs compile parameters and fixed it.

problem 2: core dump for getting plugin with 0 count.

void bx_init_config_interface_list()
{
  Bit8u i, count = 0;

  count = PLUG_get_plugins_count(PLUGTYPE_CI);
  config_interface_list = (const char**) malloc((count + 1) * sizeof(char*));
  for (i = 0; i < count; i++) {
    config_interface_list[i] = PLUG_get_plugin_name(PLUGTYPE_CI, i);
  }
  config_interface_list[count] = NULL;
  // move default config_intergface to the top of the list
  if (strcmp(config_interface_list[0], BX_DEFAULT_CONFIG_INTERFACE)) {
    for (i = 1; i < count; i++) {

PLUG_get_plugins_count returns 0 and config_interface_list[0] is null causes core dump.

I tried to set bochs config to 'normal' instead of 'plugin' to fix it.

problem 3: bochs still cores.

spu@ubuntu:~/Hypervisor-101-in-Rust/tests$ gdb /home/spu/bochs_install/bin/bochs
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/spu/bochs_install/bin/bochs...
(gdb) run -q -unlock -rc ./bochs/dbg_command.txt -f ./bochs/linux_cpu_type.bxrc
Starting program: /home/spu/bochs_install/bin/bochs -q -unlock -rc ./bochs/dbg_command.txt -f ./bochs/linux_cpu_type.bxrc
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
========================================================================
                      Bochs x86 Emulator 2.7.svn
               Built from SVN snapshot after release 2.7
                  Compiled on Nov  3 2023 at 17:27:08
========================================================================
00000000000i[      ] debugger using rc file './bochs/dbg_command.txt'.
00000000000i[      ] BXSHARE not set. using compile time default '/home/spu/bochs_install/share/bochs'
00000000000i[      ] reading configuration from ./bochs/linux_cpu_type.bxrc
00000000000p[      ] >>PANIC<< reading from ./bochs/linux_cpu_type.bxrc failed
00000000000e[SIM   ] notify called, but no bxevent_callback function is registered
00000000000e[SIM   ] notify called, but no bxevent_callback function is registered
========================================================================
Bochs is exiting with the following message:
[      ] reading from ./bochs/linux_cpu_type.bxrc failed
========================================================================
00000000000i[CPU0  ] CPU is in real mode (active)
00000000000i[CPU0  ] CS.mode = 16 bit
00000000000i[CPU0  ] SS.mode = 16 bit
00000000000i[CPU0  ] EFER   = 0x00000000
00000000000i[CPU0  ] | EAX=00000000  EBX=00000000  ECX=00000000  EDX=00000000
00000000000i[CPU0  ] | ESP=00000000  EBP=00000000  ESI=00000000  EDI=00000000
00000000000i[CPU0  ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf ZF af PF cf
00000000000i[CPU0  ] | SEG sltr(index|ti|rpl)     base    limit G D
00000000000i[CPU0  ] |  CS:0000( 0000| 0|  0) 00000000 00000000 0 0
00000000000i[CPU0  ] |  DS:0000( 0000| 0|  0) 00000000 00000000 0 0
00000000000i[CPU0  ] |  SS:0000( 0000| 0|  0) 00000000 00000000 0 0
00000000000i[CPU0  ] |  ES:0000( 0000| 0|  0) 00000000 00000000 0 0
00000000000i[CPU0  ] |  FS:0000( 0000| 0|  0) 00000000 00000000 0 0
00000000000i[CPU0  ] |  GS:0000( 0000| 0|  0) 00000000 00000000 0 0
00000000000i[CPU0  ] | EIP=00000000 (00000000)
00000000000i[CPU0  ] | CR0=0x00000000 CR2=0x00000000
00000000000i[CPU0  ] | CR3=0x00000000 CR4=0x00000000

Program received signal SIGSEGV, Segmentation fault.
BX_MEM_C::dbg_fetch_mem (cpu=0x555555a1e7c0 <bx_cpu>, addr=0, len=16, buf=0x555557252de0 <bx_disasm_ibuf> "") at misc_mem.cc:617
617       memory_handler = BX_MEM_THIS memory_handlers[a20addr >> 20];
(gdb) bt
#0  BX_MEM_C::dbg_fetch_mem (cpu=0x555555a1e7c0 <bx_cpu>, addr=0, len=16, buf=0x555557252de0 <bx_disasm_ibuf> "") at misc_mem.cc:617
#1  0x00005555557d3d5e in bx_dbg_read_linear (which_cpu=0, laddr=0, len=16, buf=0x555557252de0 <bx_disasm_ibuf> "") at dbg_main.cc:1379
#2  0x00005555557d5d8d in bx_dbg_disassemble_current (which_cpu=0, print_time=1) at dbg_main.cc:2220
#3  0x0000555555857157 in BX_CPU_C::debug_disasm_instruction (offset=0) at debugstuff.cc:34
#4  0x0000555555857b48 in BX_CPU_C::debug (offset=0) at debugstuff.cc:251
#5  0x0000555555857fa3 in BX_CPU_C::atexit () at debugstuff.cc:374
#6  0x00005555557d1a1d in bx_dbg_exit (code=1) at dbg_main.cc:801
#7  0x000055555567bda7 in logfunctions::fatal (this=0x55555726ae00, level=3, prefix=0x55555726ae40 "[      ]", fmt=0x5555559048e7 "reading from %s failed", ap=0x7fffffffddf0, exit_status=1)
    at logio.cc:680
#8  0x000055555567b571 in logfunctions::panic (this=0x55555726ae00, fmt=0x5555559048e7 "reading from %s failed") at logio.cc:463
#9  0x0000555555687cee in bx_read_configuration (rcfile=0x7fffffffe38d "./bochs/linux_cpu_type.bxrc") at config.cc:1852
#10 0x000055555567d53e in bx_init_main (argc=7, argv=0x7fffffffe078) at main.cc:897
#11 0x000055555567c664 in bxmain () at main.cc:317
#12 0x000055555567c7a6 in main (argc=7, argv=0x7fffffffe078) at main.cc:551
if ((a20addr >= 0x000a0000 && a20addr < 0x000c0000) && BX_MEM_THIS smram_available)
  {
    // SMRAM memory space
    if (BX_MEM_THIS smram_enable || (cpu->smm_mode() && !BX_MEM_THIS smram_restricted))
      use_smram = true;
  }

  memory_handler = BX_MEM_THIS memory_handlers[a20addr >> 20];
  while (memory_handler) {
    if (memory_handler->begin <= a20addr && memory_handler->end >= a20addr)
    {
      if (!use_smram) {
        use_memory_handler = true;
        break;
      }
    }
    memory_handler = memory_handler->next;
  }

at 'memory_handler = BX_MEM_THIS memory_handlers[a20addr >> 20];'

I have no idea about it. Could you please help me with that?

On Windows, the provided VMware VM cannot be started when Hyper-V is enabled

On Windows, the provided VMware VM cannot be started when Hyper-V is enabled, which is almost always the case. This issue describes workaround for it.

The issue exists because the provided VMware VM requires nested virtualization to be enabled, which is not possible when Hyper-V is enabled on the host.

Here are two workaround:

  1. Disable Hyper-V when running VMware, and re-enable it when building the project.
  2. Disable Hyper-V indefinitely and work on WSL version 1 Ubuntu.

About (1)

It is good for trial.

Run this command in the administrator command prompt when you need to run the VM.

bcdedit /set hypervisorlaunchtype off
shutdown /r

This disables WSL if it is version 2, which is default, and prevents you from successfully running cargo xtask vmware. Whenever you need to rebuild the project, re-enable Hyper-V.

bcdedit /set hypervisorlaunchtype auto
shutdown /r

About (2)

This provides better workflow. After disabling Hyper-V in the same way as above, change the WSL version on the Administrator command prompt.

wsl --set-default-version 1

Then, create a Ubuntu WSL instance. This allows the VMware VM to start while all other instructions and workflow remain to work. If you need to test with VMware frequently, this setup is recommended. This is my Windows setup as well.

Problem starting with bochs - "connection refused"

I compiled bochs from the provided repo and got the following message:

Connection failed: Connection refused
telnet: Unable to connect to remote host: Connection refused
   0: Trying ::1...
   0: Trying 127.0.0.1...
00000000000i[      ] LTDL_LIBRARY_PATH not set. using compile time default '/usr/local/lib/bochs/plugins'
00000000000i[      ] debugger using rc file './bochs/dbg_command.txt'.
00000000000i[      ] BXSHARE not set. using compile time default '/usr/local/share/bochs'
00000000000e[SIM   ] get_param_bool(unmapped) could not find a parameter
Connection failed: Connection refused
telnet: Unable to connect to remote host: Connection refused
   0: Trying ::1...
   0: Trying 127.0.0.1...
Connection failed: Connection refused
telnet: Unable to connect to remote host: Connection refused
   0: Trying ::1...
   0: Trying 127.0.0.1...
Connection failed: Connection refused

This connection failure repeated forever until I killed the script.

Any idea what may be causing this?

Missed the dependency in BUILDING.md (mtools)

Newly installed Ubuntu from microsoft store doesnt have the mcopy command availible by default, so running the example from documentation is not possible, to fix this, i suggest adding this to BUILDING.md:

sudo apt install mtools

Need code and/or instruction to take a new snapshot of other UEFI code

Currently, the repo does not include code or instructions to take a new snapshot on your own. Add this so that users can get a better idea of how that code or workflow look like.

The reason behind not including that code or instructions is that this project's top focus is learning virtualization technologies and not using it for fuzzing (it is solely a mean), and our hypervisor is only capable of fuzzing UEFI code (due to missing paging handling), making it fairly useless as a fuzzer for many.

The format of a snapshot this project consumes is custom, so combining with limited usefulness of the project as a fuzzer, I do not have an impression that such code and instruction is going to be helpful for many. Let me know if you are interested. I can take time at some point as I see interest.

To make it somewhat more useful and interesting, it would be nice if the project can consume snapshots of existing hypervisor products such as VMware, but I do not think I am going to take time for that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.