WinDbg extension written in Rust to dump the CPU / memory state of a running VM

Overview

snapshot

A Rust WinDbg extension that takes a snapshot of a running VM.

snapshot is a WinDbg extension written in Rust that dumps both the state of a CPU (GPRs, relevant MSRs, FPU state, segments, etc.) and the physical memory of a running VM (via a crash-dump). This snapshot is meant to be used by snapshot-based fuzzers and more particularly by wtf.

This code base is also meant to show case how to write a WinDbg extension in Rust 🦀.

Building

You can build the extension with the below:

c:\>git clone https://github.com/0vercl0k/snapshot.git
c:\>cd snapshot
c:\snapshot>cargo build --release

If you would rather grab a pre-built extension, grab one on the releases page.

Grabbing a snapshot

Once you have the extension downloaded / compiled, you can load it in WinDbg with the below:

kd> .load \path\to\snapshot\target\release\snapshot.dll

kd> !snapshot -h
[snapshot] Usage: snapshot [OPTIONS] [STATE_PATH]

Arguments:
  [STATE_PATH]  The path to save the snapshot to

Options:
  -k, --kind <KIND>  The kind of snapshot to take [default: full] [possible values: active-kernel, full]
  -h, --help         Print help

Generate a full-kernel snapshot in the c:\foo directory with the below:

kd> !snapshot c:\foo
[snapshot] Dumping the CPU state into c:\foo\state.19041.1.amd64fre.vb_release.191206-1406.20240205_173527\regs.json..
[snapshot] Dumping the memory state into c:\foo\state.19041.1.amd64fre.vb_release.191206-1406.20240205_173527\mem.dmp..
Creating c:\\foo\\state.19041.1.amd64fre.vb_release.191206-1406.20240205_173527\\mem.dmp - Full memory range dump
0% written.
5% written. 1 min 12 sec remaining.
10% written. 1 min 4 sec remaining.
[...]
90% written. 6 sec remaining.
95% written. 3 sec remaining.
Wrote 4.0 GB in 1 min 11 sec.
The average transfer rate was 57.7 MB/s.
Dump successfully written
[snapshot] Done!

There is also !snapshot_active_kernel if you would prefer to grab an active kernel crash-dump.

You might also like...
A library for generating fake data in Rust.

Fake A Rust library for generating fake data. Installation Default (rand is required): [dependencies] fake = "2.4" rand = "0.8" If you want to use #[d

Benchmarks for rust serialization frameworks

Rust serialization benchmark The goal of these benchmarks is to provide thorough and complete benchmarks for various rust serialization frameworks. Th

Playwright is a rust library to automate Chromium, Firefox and WebKit built on top of Node.js library.

🎭 Playwright for Rust Playwright is a rust library to automate Chromium, Firefox and WebKit built on top of Node.js library. Installation [dependenci

 ArchTest is a rule based architecture testing tool for rust
ArchTest is a rule based architecture testing tool for rust

ArchTest is a rule based architecture testing tool. It applies static analyses on the specified rust project to extract use relationships.

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

LibAFL, the fuzzer library. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. LibAFL is written and main

Structure-aware, in-process, coverage-guided, evolutionary fuzzing engine for Rust functions.

fuzzcheck Fuzzcheck is a structure-aware, in-process, coverage-guided, evolutionary fuzzing engine for Rust functions. Given a function test: (T) - b

A fuzzer framework built in Rust

lain This crate provides functionality one may find useful while developing a fuzzer. A recent nightly Rust build is required for the specialization f

A fast Rust-based safe and thead-friendly grammar-based fuzz generator

Intro fzero is a grammar-based fuzzer that generates a Rust application inspired by the paper "Building Fast Fuzzers" by Rahul Gopinath and Andreas Ze

How-to: Sanitize your Rust code!

rust-san How-to: Sanitize your Rust code! Intro How to use the sanitizers? Examples AddressSanitizer Out of bounds access Use after free LeakSanitizer

Comments
  • Errors while creating the snapshot: ValidateSequenceNumber

    Errors while creating the snapshot: ValidateSequenceNumber

    First, let me thank you for the awesome tools!

    I tried to use snapshot to create a full memory dump for wtf. I always ran into this error:

    kd> p
    toto_exe!main+0x292:
    0033:00007ff6`3c1c94c2 ff15386b0900    call    qword ptr [toto_exe!_imp_DeviceIoControl (00007ff6`3c260000)]
    kd> .load C:\Users\testq\Downloads\snapshot\snapshot.dll
    kd> !snapshot c:\foo
    [snapshot] Dumping the CPU state into c:\foo\state.22621.1.amd64fre.ni_release.220506-1250.20240320_1426\regs.json..
    [snapshot] Dumping the memory state into c:\foo\state.22621.1.amd64fre.ni_release.220506-1250.20240320_1426\mem.dmp..
    Creating c:\\foo\\state.22621.1.amd64fre.ni_release.220506-1250.20240320_1426\\mem.dmp - 
    
    Press ctrl-c (cdb, kd, ntsd) or ctrl-break (windbg) to abort symbol loads that take too long.
    Run !sym noisy before .reload to track down problems loading symbols.
    
    Full memory range dump
    0% written.
    ValidateSequenceNumber: Sequence number too far ahead for validation.
    Wrote 62.8 MB in 38 sec.
    The average transfer rate was 1.7 MB/s.
    Dump successfully written
    [snapshot] Done!
    

    However the dump is not valid (only 62.8MB written) and is not accepted by wtf:

     ..\wtf.exe fuzz --backend=bochscpu --name blah --limit 10000000
    Initializing the debugger instance.. (this takes a bit of time)
    OpenDumpFile(state\mem.dmp) failed with hr=-0x7ff8ffa9 # error code 87?
    

    I have tried several times, and I sometimes get different errors:

    kd> !snapshot c:\foo
    [snapshot] Dumping the CPU state into c:\foo\state.22621.1.amd64fre.ni_release.220506-1250.20240320_1431\regs.json..
    [snapshot] Dumping the memory state into c:\foo\state.22621.1.amd64fre.ni_release.220506-1250.20240320_1431\mem.dmp..
    Creating c:\\foo\\state.22621.1.amd64fre.ni_release.220506-1250.20240320_1431\\mem.dmp - Full memory range dump
    0% written.
    ValidateKdPacket: Invalid packet leader. Expected 0x30303030, received 0x69696969.
    ValidateKdPacket: Invalid packet leader. Expected 0x30303030, received 0x69696969.
    ValidateKdPacket: Invalid packet leader. Expected 0x30303030, received 0x69696969.
    ValidateKdPacket: Invalid packet leader. Expected 0x30303030, received 0x69696969.
    ValidateKdPacket: Invalid packet leader. Expected 0x30303030, received 0x69696969.
    Wrote 512.0 KB in 2 sec.
    The average transfer rate was 256.1 KB/s.
    Dump successfully written
    [snapshot] Done!
    

    I don't think those are bugs in snapshot but my setup must be wrong. Could you find errors in my setup or give more details about yours?

    1. Userland app with system("PAUSE"); and then __debugbreak(); just before DeviceIoControl
    2. I open toto.exe inside the guest
    3. Windbg attached to the guest's kernel, I switch to toto.exe's context with .process /p /r <EPROCESS>
    4. On the guest, I press ente to unpause toto.exe, this trigger __debugbreak();
    5. In Windbg I step until the call to DeviceIoControl
    6. Load snapshot.dll
    7. Try to snapshot, fail, repeat.

    My setup:

    • Host and guest: Windows 11 23h2

    • Guest runs inside VMWare.

    • Windbg 1.2402.24001.0

    Network debugging for kd

    bcdedit /debug on
    bcdedit /dbgsettings net hostip:172.16.9.13 port:50420 nodhcp
    

    I also tried over Serial but it takes too long (2h for 16MB).

    opened by plowsec 4
  • Use clap to parse command arguments

    Use clap to parse command arguments

    Makes for a nicer end-user experience :)

    kd> !snapshot --help
    [snapshot] Usage: snapshot <KIND> [STATE_PATH]
    
    Arguments:
      <KIND>        The kind of snapshot to take [possible values: active-kernel, full]
      [STATE_PATH]  The path to save the snapshot to
    
    Options:
      -h, --help  Print help
    
    opened by DrChat 4
  • Better UX for path management

    Better UX for path management

    Those are the cases considered:

    • If a path is given and it doesn't exist. In that case, we do not generate a folder name, the user must have provided the directory where they want us to dump the files.
    • If a path is given and it does exist. In that case, we will generate a folder name for the user.
    • No path is given in which case the resulting files will be created in the temp folder, in a directory we will create.
    opened by 0vercl0k 0
Releases(v0.2.0)
  • v0.2.0(Feb 10, 2024)

    What's Changed

    • Use clap to parse command arguments by @DrChat in https://github.com/0vercl0k/snapshot/pull/2

    New Contributors

    • @DrChat made their first contribution in https://github.com/0vercl0k/snapshot/pull/2

    Full Changelog: https://github.com/0vercl0k/snapshot/compare/v0.1.0...v0.2.0

    Source code(tar.gz)
    Source code(zip)
    snapshot.zip(1.19 MB)
  • v0.1.0(Feb 7, 2024)

    What's Changed

    • v0.1 by @0vercl0k in https://github.com/0vercl0k/snapshot/pull/1

    New Contributors

    • @0vercl0k made their first contribution in https://github.com/0vercl0k/snapshot/pull/1

    Full Changelog: https://github.com/0vercl0k/snapshot/commits/v0.1.0

    Source code(tar.gz)
    Source code(zip)
    snapshot.zip(1013.81 KB)
Owner
Axel Souchet
Axel Souchet
Custom memory allocator that helps discover reads from uninitialized memory

libdiffuzz: security-oriented alternative to Memory Sanitizer This is a drop-in replacement for OS memory allocator that can be used to detect uses of

Sergey 155 Dec 3, 2022
atttribute macro for running a flaky test multiple times

flaky_test This attribute macro will register and run a test 3 times, erroring only if all three times fail. Useful for situations when a test is flak

Deno Land 23 Mar 23, 2022
It's implemented by laying out the elements in memory contiguously like alloc::vec::Vec

A Vec<T: ?Sized> It's implemented by laying out the elements in memory contiguously like alloc::vec::Vec Layout A Vechonk is 4 usize long. It owns a s

nils 4 Sep 15, 2022
Drill is an HTTP load testing application written in Rust inspired by Ansible syntax

Drill is an HTTP load testing application written in Rust inspired by Ansible syntax

Ferran Basora 1.5k Jan 1, 2023
Verdun is a HTTP stress-test/benchmark tool written in Rust.

Verdun is a HTTP stress-test/benchmark tool written in Rust. ?? It supports testing a single URL, loading multiples URLs from a file or automatically navigating a website (auto discovery)

Alex Hortopan 2 Feb 23, 2022
Handle some lichess.org/tournament load with Rust, while learning Rust

lila-http Take some of the HTTP load away from lila. WIP! Arena tournaments Clients connected to a tournament page request new data about the tourname

Lichess 22 Jan 2, 2023
HTTP mocking library for Rust.

httpmock HTTP mocking library for Rust. Documentation · Crate · Report Bug · Request Feature · Changelog Features Simple, expressive, fluent API. Many

Alexander Liesenfeld 320 Dec 21, 2022
Testing Framework for Rust

Polish Polish is Test-Driven Development done right Getting Started Installing the Package The crates.io package is kept up-to-date with all the major

Fadi Hanna Al-Kass 49 Dec 18, 2022
🐇 Fuzzing Rust code with American Fuzzy Lop

afl.rs Fuzzing Rust code with AFLplusplus What is it? Fuzz testing is a software testing technique used to find security and stability issues by provi

Rust Fuzzing Authority 1.3k Jan 5, 2023
Travis CI and AppVeyor template to test your Rust crate on 5 architectures and publish binary releases of it for Linux, macOS and Windows

trust Travis CI and AppVeyor template to test your Rust crate on 5 architectures and publish binary releases of it for Linux, macOS and Windows Featur

Jorge Aparicio 1.2k Dec 30, 2022