kernel-alloc 0.2.3

Minimalistic Windows Kernel Allocator
![Rust](https://github.com/not-matthias/kernel-alloc-rs/workflows/Rust/badge.svg)
[![crates.io](https://img.shields.io/crates/v/kernel-alloc.svg)](https://crates.io/crates/kernel-alloc)
[![docs.rs](https://docs.rs/kernel-alloc/badge.svg)](https://docs.rs/kernel-alloc)

# kernel-alloc-rs

A custom memory allocator tailored for the Windows kernel space.

## Why?

Rust has many useful abstractions and utils that require heap allocations, such as `String`, `Vec`, and `Box`. To be able to use them in the Windows kernel space, we need to allocate memory at runtime, which requires a custom allocator. This crate provides such allocators tailored for the Windows kernel.

For more information on custom allocators in Rust, refer to the [alloc::GlobalAllocator](https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html) and [alloc::Allocator](https://doc.rust-lang.org/std/alloc/trait.Allocator.html) documentation. Additionally, the Rust book provides details on [global_allocator](https://doc.rust-lang.org/1.26.2/unstable-book/language-features/global-allocator.html) and [allocator_api](https://doc.rust-lang.org/1.26.2/unstable-book/library-features/allocator-api.html).

## Example

To use `KernelAlloc` or `PhysicalAllocator` as your global allocator, add the appropriate code to your kernel module:

For `KernelAlloc`:

```rust
use kernel_alloc::KernelAlloc;

#[global_allocator]
static GLOBAL: KernelAlloc = KernelAlloc;
```

For `PhysicalAllocator`:

```rust
use kernel_alloc::PhysicalAllocator;

#[global_allocator]
static GLOBAL: PhysicalAllocator = PhysicalAllocator;
```

## Using with `Box`

Once you've set up `KernelAlloc` or `PhysicalAllocator` as your global allocator, you can use `Box` and other heap-allocated types just like you would in a standard Rust environment.

Here's an example demonstrating how to use both `KernelAlloc` and `PhysicalAllocator` with `Box` to allocate memory for different structs in the Windows kernel:

```rust
use kernel_alloc::{KernelAlloc, PhysicalAllocator};
use core::mem;

pub const PAGE_SIZE: usize = 0x1000;
pub const KERNEL_STACK_SIZE: usize = 0x6000;
pub const STACK_CONTENTS_SIZE: usize = KERNEL_STACK_SIZE - (mem::size_of::<*mut u64>() * 2);

#[repr(C, align(4096))]
pub struct Vmxon {
    pub revision_id: u32,
    pub data: [u8; PAGE_SIZE - 4],
}

#[repr(C, align(4096))]
pub struct HostStackLayout {
    pub stack_contents: [u8; STACK_CONTENTS_SIZE],
    pub padding_1: u64,
    pub reserved_1: u64,
}

pub struct Vmx {
    pub vmxon_region: Box<Vmxon, PhysicalAllocator>,
    pub host_rsp: Box<HostStackLayout, KernelAlloc>,
}

impl Vmx {
    pub fn new() -> Result<Self, AllocError> {
        let vmxon_region = unsafe { Box::try_new_zeroed_in(PhysicalAllocator)?.assume_init() };
        let host_rsp = unsafe { Box::try_new_zeroed_in(KernelAlloc)?.assume_init() };

        Ok(Self {
            vmxon_region: vmxon_region,
            host_rsp: host_rsp,
        })
    }
}
```

## Credits / References

- [Vergilius Project]https://www.vergiliusproject.com/
- [@not-matthias]https://github.com/not-matthias/
- @jessiep_
- [@memN0ps]https://github.com/memN0ps/