wtf is a distributed, code-coverage guided, customizable, cross-platform snapshot-based fuzzer designed for attacking user and / or kernel-mode targets running on Microsoft Windows.

Overview

what the fuzz

Builds

Overview

what the fuzz or wtf is a distributed, code-coverage guided, customizable, cross-platform snapshot-based fuzzer designed for attacking user and or kernel-mode targets running on Microsoft Windows. Execution of the target can be done inside an emulator with bochscpu (slowest, most precise), inside a Windows VM with the Windows Hypervisor Platform APIs or inside a Linux VM with KVM APIs (fastest).

It uncovered memory corruption vulnerabilities in a wide range of softwares: IDA Pro, a popular AAA game, the Windows kernel, HEVD secure mode, etc.

Compiled binaries are available from the CI artifacts for both Windows & Linux or from the Release section.

Special thanks to @yrp604 for providing valuable inputs throughout the project and @masthoon for suggesting to write a demo targeting HEVD secure mode.

Usage

The best way to try the features out is to work the the fuzzer_hevd example module. You can grab the target-hevd.7z archive and extract it into the targets/ directory. The archive contains the directory tree that is expected for every targets:

  • inputs is the folder where your input test-cases go into,
  • outputs is the folder where the current minset files are saved into,
  • coverage is the folder where the .cov files are expected to be in,
  • crashes is where the crashes gets saved in,
  • state is where the memory dump (mem.dmp) as well as the CPU state (regs.json) and the symbol store are stored in (symbol-store.json). The symbol store is a simple JSON file that is used on Linux systems to know where to put breakpoints as there is no support for symbols / dbgeng on those platforms. wtf generates this file at runtime everytime you run your target on Windows.

Starting a server node

The server is basically the brain and keeps track of all the state: the aggregated code-coverage, the corpus, it generates and distributes the test-cases to client.

This is how you might choose to launch a server node:

(base) c:\work\codes\wtf\targets\hevd>..\..\src\build\wtf.exe master --max_len=1028 --runs=10000000 --target . --address tcp://192.168.2.41/

The max_len option is used to limit the size of the generated test-case, runs is the number of test-cases it will generate, address specify where wtf needs to be listening on and target is a directory with the directory tree we described above (the user can also choose to override those directories with --input / --output / --crashes).

Fuzzing nodes

The client nodes run a test-case that has been generated and distributed by the server and communicates the result back to the server (code-coverage, result, etc.).

This is how you would start a client node that uses the bochscpu backend:

..\..\src\build\wtf.exe fuzz --backend=bochscpu --name hevd --max_len 1028 --limit 10000000

The fuzz subcommand is used with the name option to specify which fuzzer module needs to be used, backend specifies the execution backend and limit the maximum number of instruction to execute per testcase (depending on the backend, this option has different meaning).

Running a test-case

If you would like to run a test-case (or a folder filled with test-cases), you can use the run subcommand.

This is how you would would run the crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0 test-case:

..\..\src\build\wtf.exe run --name hevd --state state --backend=bochscpu  --limit 10000000 --input crashes\crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0

Minseting a corpus

To minset a corpus, you need to use a server node and as many client nodes as you need like you would for a fuzzing job. You can simply set the runs optins to 0.

This is how you would minset the corpus in outputs into the minset directory (also highlights how you can override the inputs and outputs directories):

..\..\src\build\wtf.exe master --max_len=1028 --runs=0 --target . --inputs=outputs --outputs=minset

Generating execution traces

The main mechanism available to instrospect in an execution backend is to generate an execution trace. bochscpu is the only backend that has the ability to generate a complete execution traces so it is best to use for debugging purposes. The other backends only generate execution traces used to measure code-coverage (address of the first instruction in a basic block).

This is how you would generate an execution trace for the crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0 test-case:

..\..\src\build\wtf.exe run --name hevd --state state --backend=bochscpu  --limit 10000000 --input crashes\crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0 --trace-path=. --trace-type=rip

The execution traces aren't symbolized because Linux systems wouldn't be able to do that and that is why I wrote symbolizer.

This is how you would symbolize the crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.trace execution trace generated above:

symbolizer.exe --input crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.trace --crash-dump state\mem.dmp

Generating code-coverage traces

To generate code-coverage traces you can simply use the run subcommand with the --trace-type=cov option.

This is how you would generate code-coverage traces for all the files inside the minset folder and store them in the coverage-traces folder:

..\..\src\build\wtf.exe run --name hevd --state state --backend=whv --input minset --trace-path=coverage-traces --trace-type=cov

Those traces aren't directly loadable into lighthouse because they aren't symbolized.

This is how you would symbolize all the files inside the coverage-traces folder and write the results into coverage-traces-symbolized:

symbolizer.exe --input coverage-traces --crash-dump state\mem.dmp -o coverage-traces-symbolized --style modoff

And finally, you can load those up in lighthouse:

How it works

wtf runs user & kernel mode through an execution backend and relies on the user to insert test-cases in the target. Unlike other classical fuzzer tools, wtf doesn't do much of the heavy lifting; the user does. The user needs to know the harnessed target very well and onboarding a target is an iterative process that will take time. It has a lot of flexibility to offer if you are ready to get hacking though :)

The usual workflow to harness a target is as follows:

  1. Get your target running into a Hyper-V VM running Windows with one virtual CPU and 4GB of RAM,

  2. Put your target into the desired state using KD. For example, to target HEVD's IOCTL handler, I chose to stop the target in user-mode right before the client invokes DeviceIoControl. This will vary depending on your targets but you probably want it to be close to the code you want to fuzz.

    kd> r
    rax=000000dfd98ff3d0 rbx=0000000000000088 rcx=0000000000000088
    rdx=00000000deadbeef rsi=0000000000000000 rdi=0000000000000000
    rip=00007ff6f5bb111e rsp=000000dfd98ff380 rbp=0000000000000000
    r8=000000dfd98ff3d0  r9=0000000000000400 r10=000002263e823055
    r11=00007ff6f5bcb54d r12=0000000000000000 r13=0000000000000000
    r14=0000000000000000 r15=0000000000000000
    iopl=0         nv up ei pl nz na po nc
    cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
    hevd_client!main+0xae:
    00007ff6`f5bb111e ff15dc1e0100    call    qword ptr [hevd_client!_imp_DeviceIoControl (00007ff6`f5bc3000)] ds:002b:00007ff6`f5bc3000={KERNEL32!DeviceIoControlImplementation (00007ff8`3e2e6360)}
    
  3. Use bdump.js to generate the kernel crash-dump as well as the regs.json file that contains the CPU state. I recommend to dump those file in a state directory under your target directory (targets/hevd/state for example):

    !bdump_active_kernel "c:\\work\\codes\\wtf\\targets\\hevd\\state" [bdump] creating dir... [bdump] saving regs... [bdump] register fixups... [bdump] don't know how to get mxcsr_mask or fpop, setting to zero... [bdump] [bdump] don't know how to get avx registers, skipping... [bdump] [bdump] tr.base is not cannonical... [bdump] old tr.base: 0x7375c000 [bdump] new tr.base: 0xfffff8047375c000 [bdump] [bdump] setting flag 0x2000 on cs.attr... [bdump] old cs.attr: 0x2fb [bdump] new cs.attr: 0x22fb [bdump] [bdump] rip and gs don't match kernel/user, swapping... [bdump] rip: 0x7ff6f5bb111e [bdump] new gs.base: 0xdfd9621000 [bdump] new kernel_gs_base: 0xfffff8046b6f3000 [bdump] [bdump] non-zero IRQL in usermode, resetting to zero... [bdump] saving mem, get a coffee or have a smoke, this will probably take around 10-15 minutes... [bdump] Creating c:\work\codes\wtf\targets\hevd\state\mem.dmp - Active kernel and user memory bitmap dump [bdump] Collecting pages to write to the dump. This may take a while. [bdump] 0% written. [...] [bdump] 95% written. 1 sec remaining. [bdump] Wrote 1.5 GB in 23 sec. [bdump] The average transfer rate was 64.7 MB/s. [bdump] Dump successfully written [bdump] done! @$bdump_active_kernel("c:\\work\\codes\\wtf\\targets\\hevd\\state") ">
    kd> .scriptload c:\\work\\codes\\bdump\\bdump.js
    [bdump] Usage: !bdump "C:\\path\\to\\dump"
    [bdump] Usage: !bdump_full "C:\\path\\to\\dump"
    [bdump] Usage: !bdump_active_kernel "C:\\path\\to\\dump"
    [bdump] This will create a dump directory and fill it with a memory and register files
    [bdump] NOTE: you must include the quotes and escape the backslashes!
    JavaScript script successfully loaded from 'c:\work\codes\bdump\bdump.js'
    
    kd> !bdump_active_kernel "c:\\work\\codes\\wtf\\targets\\hevd\\state"
    [bdump] creating dir...
    [bdump] saving regs...
    [bdump] register fixups...
    [bdump] don't know how to get mxcsr_mask or fpop, setting to zero...
    [bdump]
    [bdump] don't know how to get avx registers, skipping...
    [bdump]
    [bdump] tr.base is not cannonical...
    [bdump] old tr.base: 0x7375c000
    [bdump] new tr.base: 0xfffff8047375c000
    [bdump]
    [bdump] setting flag 0x2000 on cs.attr...
    [bdump] old cs.attr: 0x2fb
    [bdump] new cs.attr: 0x22fb
    [bdump]
    [bdump] rip and gs don't match kernel/user, swapping...
    [bdump] rip: 0x7ff6f5bb111e
    [bdump] new gs.base: 0xdfd9621000
    [bdump] new kernel_gs_base: 0xfffff8046b6f3000
    [bdump]
    [bdump] non-zero IRQL in usermode, resetting to zero...
    [bdump] saving mem, get a coffee or have a smoke, this will probably take around 10-15 minutes...
    [bdump] Creating c:\work\codes\wtf\targets\hevd\state\mem.dmp - Active kernel and user memory bitmap dump
    [bdump] Collecting pages to write to the dump. This may take a while.
    [bdump] 0% written.
    [...]
    [bdump] 95% written. 1 sec remaining.
    [bdump] Wrote 1.5 GB in 23 sec.
    [bdump] The average transfer rate was 64.7 MB/s.
    [bdump] Dump successfully written
    [bdump] done!
    @$bdump_active_kernel("c:\\work\\codes\\wtf\\targets\\hevd\\state")
    
  4. Create a fuzzer module, write the code that inserts a test-case into your target and define the various conditions to detect crashes or the end of a test-case.

At this point you should start to iterate and verify that the fuzzer module works as expected. The execution backends are a blackbox so you should generate execution traces to make sure it goes through the right paths, does the right things. During this phase I mainly use the bochscpu backend as it is fully deterministic, starts fast, generating execution traces is possible, code-coverage comes for free, etc. Overall, it's a nicer environment to develop and prototype in.

Once you are satisfied with the module, you can start to look at making it work with the winhv / kvm backends if you need it to run under those. One major difference between the bochscpu backend & the others, is that the others use software breakpoints to provide code-coverage information. As a result, you'll need to load the modules you want coverage for under IDA and use the gen_coveragefile_ida.py script to generate a simple JSON file that gets loaded by wtf. You are free to generate this JSON file yourself using whatever tool you would like: it basically is a list of basic-blocks virtual addresses.

Execution backends

In this section I briefly mention various differences between the execution backends.

bochscpu

  • Full system code-coverage,
  • Demand-paging,
  • Timeout is the number of instructions which is very precise,
  • Full execution traces are supported,
  • Fully deterministic,
  • Speed seems to be good for short executions but not for long executions (~100x slower than KVM when I was fuzzing IDA).

whv

  • Code-coverage via software breakpoints,
  • Demand-paging so start-up is slow (as it needs to load the full crash-dump in memory),
  • Timeout is implemented with a timer,
  • Only code-coverage traces are supported,
  • Deterministic if handling source of non determinism manually (for example, patching nt!ExGenRamdom that uses rdrand),
  • Speed seems to be ok for long executions (lots of bottleneck in whv though; ~10x slower than WHV when I was fuzzing IDA).

KVM

  • Code-coverage via software breakpoints,
  • Demand-paging is supported via UFDD,
  • Timeout is implemented with a timer. If the hardware supports PMU virtualization, it is used to generate a PMI after X retired instructions (MSR_IA32_FIXED_CTR0),
  • Only code-coverage traces are supported,
  • Deterministic if handling source of non determinism manually (for example, patching nt!ExGenRamdom that uses rdrand),
  • Fastest for long executions (~500m - 1.5 billion instructions; ~100x faster than bochscpu, ~10x faster than whv when I was fuzzing IDA).

Build

The CI builds wtf on Ubuntu 20.04 using clang++-11 / g++-11 and on Windows using Microsoft's Visual Studio 2019.

To build it yourself you need to start a Visual Studio Developper Command Prompt and either run build-release.bat which uses the Ninja generator or build-release-msvc.bat to generate a Visual Studio solution file:

(base) wtf\src\build>build-release.bat
[...]
[2/2] Linking CXX executable wtf.exe

(base) wtf\src\build_msvc>..\build\build-release-msvc.bat
[...]
  Finished generating code
  wtf.vcxproj -> wtf\src\build_msvc\RelWithDebInfo\wtf.exe
  Building Custom Rule wtf/src/CMakeLists.txt

Authors

Comments
  • Harnessing w/ file-system hooks

    Harnessing w/ file-system hooks

    After solving the 0vercl0k/wtf#101, I made a harness and tried fuzzing.

    However, in each test case, it did not reach the address I intended.

    Test Environment

    • Host: VMware
      • Windows 10 Pro 21H2 (OS build 19044.1706)
      • Memory 8GB, Processors 4
    • Guest: Hyper-V in VMware
      • Windows 10 Pro 21H2 (OS build 19044.1288)
      • Hyper-V generation 1
      • Memory 4GB, Processors 1
      • Disabled KVA shadow via disable-kva.cmd
      • Disabled paging file via sysdm.cpl
    • WinDbg (X64)
      • KDNET
    • Targeting 32bit binary

    Attachment

    • Target dll file, and exe file which loads it (+some other files): target.zip
    • mem.dmp & regs.json: dump
    • inputs: inputs.zip

    Issue

    These are commands I used for wtf.

    # Starting a server node
    ..\..\src\build\wtf.exe master --name abc --max_len=80000 --runs=10000000 --target .
    # Fuzzing nodes
    ..\..\src\build\wtf.exe fuzz --name abc --backend=bochscpu --limit 10000000
    # Running a test-case
    ..\..\src\build\wtf.exe run --name abc --state state --backend=bochscpu --limit 10000000 --input wtf_input.xlsx
    

    Below steps were used to generate the dump.

    kd> !gflag +ksl
    kd> sxe ld YYY.dll
    kd> g
    

    Make XXX.exe loads YYY.dll through user interaction. (=double click wtf_input.xlsx)

    kd> bp YYY+12aec2
    kd> g
    32.kd:x86> .scriptload C:\Users\user\Desktop\tools\bdump\bdump.js
    32.kd:x86> !wow64exts.sw
    32.kd> !bdump_full "C:\\Users\\user\\Downloads\\dump"
    

    And this is the harness.

    #include "backend.h"
    #include "crash_detection_umode.h"
    #include "fshandle_table.h"
    #include "fshooks.h"
    #include "targets.h"
    #include <fmt/format.h>
    
    namespace Abc {
    
    constexpr bool LoggingOn = true;
    
    template <typename... Args_t>
    void DebugPrint(const char *Format, const Args_t &...args) {
      if constexpr (LoggingOn) {
        fmt::print("Abc: ");
        fmt::print(fmt::runtime(Format), args...);
      }
    }
    
    bool InsertTestcase(const uint8_t *Buffer, const size_t BufferSize) {
      g_FsHandleTable.MapExistingGuestFile(
          uR"(\??\C:\Users\user\Desktop\wtf_input.xlsx)", Buffer, BufferSize);
    
      return true;
    }
    
    bool Init(const Options_t &Opts, const CpuState_t &State) {
      //
      // Stop the test-case once we return back from the call [sub_100B1010]
      //
      // ...
      // .text:1012AEBF                 lea     ecx, [ebp+var_1C]
      // .text:1012AEC2                 call    sub_100B1010
      // .text:1012AEC7                 mov     edi, eax
      // ...
      //
    
      const Gva_t Rip = Gva_t(g_Backend->Rip());
      const Gva_t AfterCall = Rip + Gva_t(5);
      if (!g_Backend->SetBreakpoint(AfterCall, [](Backend_t *Backend) {
            DebugPrint("Back from sub_100B1010!\n");
            Backend->Stop(Ok_t());
          })) {
        fmt::print("Failed to SetBreakpoint AfterCall\n");
        return false;
      }
    
      if (!SetupFilesystemHooks()) {
        fmt::print("Failed to SetupFilesystemHooks\n");
        return false;
      }
    
      if (!SetupUsermodeCrashDetectionHooks()) {
        fmt::print("Failed to SetupUsermodeCrashDetectionHooks\n");
        return false;
      }
    
      return true;
    }
    
    Target_t Abc("abc", Init, InsertTestcase);
    
    }
    

    1st Try

    > ..\..\src\build\wtf.exe run --name abc --state state --backend=bochscpu --limit 10000000 --input wtf_input.xlsx
    Initializing the debugger instance.. (this takes a bit of time)
    Setting debug register status to zero.
    Setting debug register status to zero.
    Could not set a breakpoint at hal!HalpPerfInterrupt.
    Failed to set breakpoint on HalpPerfInterrupt, but ignoring..
    Running wtf_input.xlsx
    fs: Mapping already existing guest file \??\C:\Users\user\Desktop\wtf_input.xlsx with filestream(8576)
    fs: ntdll!NtCreateFile(FileHandle=0x466e380, DesiredAccess=0x80100080, ObjectAttributes=0x466ec50 (\??\C:\Users\user\Desktop\wtf_input.xlsx), IoStatusBlock=0x466e398, AllocationSize=0x0, FileAttributes=0x80, ShareAccess=0x1 (FILE_SHARE_READ), CreateDisposition=0x1 (FILE_OPEN), CreateOptions=0x60 (FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT), EaBuffer=0x0, EaLength=0x0)
    fs: Opening 0x7ffffffffffffffe for \??\C:\Users\user\Desktop\wtf_input.xlsx
    fs: ntdll!NtQueryInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x466ec60, Length=0x18, FileInformationClass=0x5)
    fs: Unrecognized file handle.
    fs: ntdll!NtSetInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x466e3a8, Length=0x8, FileInformationClass=0xe)
    fs: Unrecognized file handle.
    fs: ntdll!NtQueryInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x9a7d2f8, Length=0x18, FileInformationClass=0x5)
    fs: Unrecognized file handle.
    fs: ntdll!NtCreateFile(FileHandle=0x466e380, DesiredAccess=0x80100080, ObjectAttributes=0x466ec50 (\??\C:\Users\user\Desktop\wtf_input.xlsx), IoStatusBlock=0x466e398, AllocationSize=0x0, FileAttributes=0x80, ShareAccess=0x3 (FILE_SHARE_READ | FILE_SHARE_WRITE), CreateDisposition=0x1 (FILE_OPEN), CreateOptions=0x60 (FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT), EaBuffer=0x0, EaLength=0x0)
    fs: Opening 0x7ffffffffffffffd for \??\C:\Users\user\Desktop\wtf_input.xlsx
    fs: ntdll!NtQueryAttributesFile(ObjectAttributes=0x466ec50 (\??\C:\Users\user\AppData\Local\Temp\), FileInformation=0x466e3a8)
    fs: Unknown file.
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\user\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\user\AppData\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\user\AppData\Local\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    --------------------------------------------------
    Run stats:
    Instructions executed: 821563 (61510 unique)
              Dirty pages: 1482752 bytes (0 MB)
          Memory accesses: 2435116 bytes (0 MB)
    #1 cov: 61510 exec/s: 0.2 lastcov: 0.0s crash: 0 timeout: 0 cr3: 1 uptime: 4.0s
    

    It did not reach DebugPrint("Back from sub_100B1010!\n");.

    When I loaded aggregate.cov as a result of fuzzing through Lighthouse, I could see that the execution was stopped at SpreadsheetDocument::Open(wchar_t const *)(presumed to be related to file-system operations).

    try1_lighthouse

    2nd Try

    After reading the wtf code a little, I changed one line of code of handle_table.h as below.

    -  static const uint64_t LastGuestHandle = 0x7ffffffffffffffeULL;
    +  static const uint64_t LastGuestHandle = 0xfffffffffffffffeULL;
    
    > ..\..\src\build\wtf.exe run --name abc --state state --backend=bochscpu --limit 10000000 --input wtf_input.xlsx
    Initializing the debugger instance.. (this takes a bit of time)
    Setting debug register status to zero.
    Setting debug register status to zero.
    Could not set a breakpoint at hal!HalpPerfInterrupt.
    Failed to set breakpoint on HalpPerfInterrupt, but ignoring..
    Running wtf_input.xlsx
    fs: Mapping already existing guest file \??\C:\Users\user\Desktop\wtf_input.xlsx with filestream(8576)
    fs: ntdll!NtCreateFile(FileHandle=0x466e380, DesiredAccess=0x80100080, ObjectAttributes=0x466ec50 (\??\C:\Users\user\Desktop\wtf_input.xlsx), IoStatusBlock=0x466e398, AllocationSize=0x0, FileAttributes=0x80, ShareAccess=0x1 (FILE_SHARE_READ), CreateDisposition=0x1 (FILE_OPEN), CreateOptions=0x60 (FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT), EaBuffer=0x0, EaLength=0x0)
    fs: Opening 0xfffffffffffffffe for \??\C:\Users\user\Desktop\wtf_input.xlsx
    fs: ntdll!NtQueryInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x466ec60, Length=0x18, FileInformationClass=0x5)
    filestream: FileStandardInformation(AllocationSize=0x3000, EndOfFile=0x2180).
    fs: ntdll!NtSetInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x466e3a8, Length=0x8, FileInformationClass=0xe)
    filestream: FilePositionInformation.
    filestream: Moving cursor to offset 0x0.
    fs: ntdll!NtQueryInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x9a7d2f8, Length=0x18, FileInformationClass=0x5)
    filestream: FileStandardInformation(AllocationSize=0x3000, EndOfFile=0x2180).
    fs: ntdll!NtSetInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x466e3a8, Length=0x8, FileInformationClass=0xe)
    filestream: FilePositionInformation.
    filestream: Moving cursor to offset 0x180.
    fs: ntdll!NtSetInformationFile(FileHandle=0xfffffffffffffffe, IoStatusBlock=0x466e398, FileInformation=0x466e3a8, Length=0x8, FileInformationClass=0xe)
    filestream: FilePositionInformation.
    filestream: Moving cursor to offset 0x0.
    fs: ntdll!NtCreateFile(FileHandle=0x466e380, DesiredAccess=0x80100080, ObjectAttributes=0x466ec50 (\??\C:\Users\user\Desktop\wtf_input.xlsx), IoStatusBlock=0x466e398, AllocationSize=0x0, FileAttributes=0x80, ShareAccess=0x3 (FILE_SHARE_READ | FILE_SHARE_WRITE), CreateDisposition=0x1 (FILE_OPEN), CreateOptions=0x60 (FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT), EaBuffer=0x0, EaLength=0x0)
    fs: Opening 0xfffffffffffffffd for \??\C:\Users\user\Desktop\wtf_input.xlsx
    fs: ntdll!NtQueryAttributesFile(ObjectAttributes=0x466ec50 (\??\C:\Users\user\AppData\Local\Temp\), FileInformation=0x466e3a8)
    fs: Unknown file.
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\user\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\user\AppData\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    fs: ntdll!NtOpenFile(FileHandle=0x466e3f8, DesiredAccess=0x100001, ObjectAttributes=0x466ec50 (\??\C:\Users\user\AppData\Local\), IoStatusBlock=0x466e398, ShareAccess=0x7 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), OpenOptions=0x4021 (FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT))
    --------------------------------------------------
    Run stats:
    Instructions executed: 905056 (61554 unique)
              Dirty pages: 1486848 bytes (0 MB)
          Memory accesses: 2457468 bytes (0 MB)
    #1 cov: 61554 exec/s: 1.0 lastcov: 0.0s crash: 0 timeout: 0 cr3: 1 uptime: 1.0s
    

    Again, it did not reach DebugPrint("Back from sub_100B1010!\n");.

    And result of the Lighthouse haven't changed.

    try2_lighthouse

    opened by donghyunlee00 39
  • Specifying a directory for the `--input` option when generating traces

    Specifying a directory for the `--input` option when generating traces

    When I generate traces through wtf.exe run, if I specify a folder for the --input option, the trace results of all input files are the same. However, if I specify each file for the --input option, the trace results are all different.

    opened by donghyunlee00 16
  • Translation of GVA 0x8903aff578 failed

    Translation of GVA 0x8903aff578 failed

    hi, first of all, thank you for providing such a cool fuzzer bro :) but i got an error while trying hevd sample test files.

    server

    D:\wtf\targets\hevd>..\..\src\build\wtf.exe master --max_len=1028 --runs=10000000 --target .
    Seeded with 8037290960217419384
    Iterating through the corpus..
    Sorting through the 1 entries..
    Running server on tcp://localhost:31337..
    #0 cov: 0 (+0) corp: 0 (0.0b) exec/s: -nan (1 nodes) lastcov: 6.0s crash: 0 timeout: 0 cr3: 0 uptime: 6.0s
    Could not receive size (0)
    Receive failed
    

    client

    D:\wtf\targets\hevd>..\..\src\build\wtf.exe fuzz --backend=bochscpu --name hevd --max_len 1028 --limit 10000000
    Initializing the debugger instance.. (this takes a bit of time)
    Setting debug register status to zero.
    Setting debug register status to zero.
    Dialing to tcp://localhost:31337/..
    Translation of GVA 0x8903aff578 failed
    

    and this is target dumps & wtf that i made based on README.md https://drive.google.com/file/d/1-18rDU_TY8uLHYimMhXO9169iFUVB6o8/view?usp=sharing

    thanx...

    opened by fish3rman 14
  • Unable to fuzz with WHV backend

    Unable to fuzz with WHV backend

    When I run server and one fuzzing node with whv backend, I got an error:

    Server:

    D:\wtf_fuzzing\targets>..\wtf.exe master --name ioctl --max_len=1028 --runs=10000000 --target .
    Seeded with 1892113798163204355
    Iterating through the corpus..
    Sorting through the 127 entries..
    Running server on tcp://localhost:31337..
    #0 cov: 0 (+0) corp: 0 (0.0b) exec/s: -nan (1 nodes) lastcov: 6.0s crash: 0 timeout: 0 cr3: 0 uptime: 6.0s                                                                   The corpus is empty, exiting
    

    Fuzzing node:

    D:\wtf_fuzzing\targets>..\wtf.exe fuzz --backend=whv --name ioctl --limit 10000000
    Initializing the debugger instance.. (this takes a bit of time)
    Setting debug register status to zero.
    Setting debug register status to zero.
    Resolved breakpoint 0x7ffec31e3ff4 at GPA 0xffbaff4 aka HVA 0x19c4618dff4
    Resolved breakpoint 0xfffff8012755c6e0 at GPA 0x10055c6e0 aka HVA 0x19c4617f6e0
    Resolved breakpoint 0xfffff801274a1e63 at GPA 0x1004a1e63 aka HVA 0x19c4618fe63
    Resolved breakpoint 0xfffff80127762230 at GPA 0x100762230 aka HVA 0x19c46181230
    Resolved breakpoint 0xfffff8012761fab0 at GPA 0x10061fab0 aka HVA 0x19c46189ab0
    Dialing to tcp://localhost:31337/..
    Could not receive size (-1)
    Receive failed
    #127 cov: 0 exec/s: 31.8 lastcov: 4.0s crash: 0 timeout: 0 cr3: 0 uptime: 4.0s
    

    Note: the state was dumped from VMWare and fuzzing performs normally with --backend=bochscpu

    opened by 1ndahous3 12
  • bochscpu

    bochscpu

    Hi,

    I read part of the code and got interested to play a bit with bochscpu, I went to https://github.com/yrp604/bochscpu-build but that seem to be different than what you used in this project!

    Like some functions like bochscpu_cpu_new() and many others that you used in this repository doesn't exist there!

        bochscpu_cpu_t Cpu_ = nullptr;
        Cpu_ = bochscpu_cpu_new(0);
    

    Can you please give me some clue on where I can start using bochscpu and what is the different between what is used in this project and the one in yrp604/bochscpu-build?

    Thanks, Nemo

    opened by djn3m0 12
  • Cannot reproduce the snapshot for HEVD fuzzer

    Cannot reproduce the snapshot for HEVD fuzzer

    Hello. I followed the instructions here and installed W10 inside Hyper-V VM, 4GB RAM, 1 CPU. I also disabled KVA and used lockmem.exe when doing the memory dump (!bdump).

    Still, when I run the fuzzer (I modified only ExGenRandom to reflect my Windows version), I am getting the following errors:

    • Master
    Seeded with 367867526817988208
    Iterating through the corpus..
    Sorting through the 1 entries..
    Running server on tcp://localhost:31337..
    #0 cov: 0 (+0) corp: 0 (0.0b) exec/s: -nan (1 nodes) lastcov: 2.0s crash: 0 timeout: 0 cr3: 0 uptime: 2.0s
    Could not receive size (-1)
    Receive failed
    #0 cov: 0 (+0) corp: 0 (0.0b) exec/s: -nan (0 nodes) lastcov: 3.0s crash: 0 timeout: 0 cr3: 0 uptime: 3.0s
    
    • Fuzzer node
    Initializing the debugger instance.. (this takes a bit of time)
    Setting debug register status to zero.
    Setting debug register status to zero.
    Dialing to tcp://localhost:31337/..
    VirtTranslate failed for GVA:0xfffff80711b78600
    

    Here is the dump of my image.

    I also did some sanity checks if the code was not swapped out, mentioned here https://github.com/0vercl0k/wtf/issues/41, so for instance KERNELBASE!DeviceIoControl disassembles correctly. How can I debug this issue? I tried to create images 10-15 times with more or less the same result. Also, no problem to run the fuzzer with the snapshot you provided. Thanks.

    opened by mkubx 10
  • Page faults on usermode target?

    Page faults on usermode target?

    Hello there and thank you for awesome project to play with!

    I'm trying to fuzz usermode program using bochscpu backend and only coverage I'm getting (in aggregate.cov) is related to page faults i.e. nt!KiPageFault, nt!MmAccessFault, nt!MiUserFault, ...

    My target is fairly simple, memory dump is taken on this first instruction:

    0033:00007ff8`5aaa2f20 83fa08         cmp     edx, 8
    0033:00007ff8`5aaa2f23 7233           jb      00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f25 803931         cmp     byte ptr [rcx], 31h
    0033:00007ff8`5aaa2f28 752e           jne     00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f2a 80790133       cmp     byte ptr [rcx+1], 33h
    0033:00007ff8`5aaa2f2e 7528           jne     00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f30 80790233       cmp     byte ptr [rcx+2], 33h
    0033:00007ff8`5aaa2f34 7522           jne     00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f36 80790337       cmp     byte ptr [rcx+3], 37h
    0033:00007ff8`5aaa2f3a 751c           jne     00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f3c 80790431       cmp     byte ptr [rcx+4], 31h
    0033:00007ff8`5aaa2f40 7516           jne     00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f42 80790533       cmp     byte ptr [rcx+5], 33h
    0033:00007ff8`5aaa2f46 7510           jne     00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f48 80790633       cmp     byte ptr [rcx+6], 33h
    0033:00007ff8`5aaa2f4c 750a           jne     00007ff8`5aaa2f58
    0033:00007ff8`5aaa2f4e 80790737       cmp     byte ptr [rcx+7], 37h
    0033:00007ff8`5aaa2f52 0f841fe2ffff   je      00007ff8`5aaa1177
    0033:00007ff8`5aaa2f58 c3             ret     
    

    Command lines, with some logs:

    >wtf.exe master --max_len=1028 --runs=10000000 --target .
    Seeded with 15448101250580876408
    Iterating through the corpus..
    Sorting through the 1 entries..
    Running server on tcp://localhost:31337..
    #0 cov: 0 (+0) corp: 0 (0.0b) exec/s: -nan (1 nodes) lastcov: 5.0s crash: 0 timeout: 0 cr3: 0 uptime: 5.0s
    #21754 cov: 830 (+830) corp: 1 (11.0b) exec/s: 2.2k (1 nodes) lastcov: 9.0s crash: 0 timeout: 0 cr3: 21754 uptime: 15.0s
    #41192 cov: 830 (+0) corp: 1 (11.0b) exec/s: 2.1k (1 nodes) lastcov: 19.0s crash: 0 timeout: 0 cr3: 41192 uptime: 25.0s
    #61699 cov: 830 (+0) corp: 1 (11.0b) exec/s: 2.1k (1 nodes) lastcov: 29.0s crash: 0 timeout: 0 cr3: 61699 uptime: 35.0s
    #82182 cov: 830 (+0) corp: 1 (11.0b) exec/s: 2.1k (1 nodes) lastcov: 39.0s crash: 0 timeout: 0 cr3: 82182 uptime: 45.0s
    #102441 cov: 830 (+0) corp: 1 (11.0b) exec/s: 2.0k (1 nodes) lastcov: 49.0s crash: 0 timeout: 0 cr3: 102441 uptime: 55.0s
    #123153 cov: 830 (+0) corp: 1 (11.0b) exec/s: 2.1k (1 nodes) lastcov: 60.0s crash: 0 timeout: 0 cr3: 123153 uptime: 1.1min
    #138078 cov: 830 (+0) corp: 1 (11.0b) exec/s: 2.0k (1 nodes) lastcov: 1.2min crash: 0 timeout: 0 cr3: 138078 uptime: 1.2min
    #152423 cov: 830 (+0) corp: 1 (11.0b) exec/s: 1.9k (1 nodes) lastcov: 1.3min crash: 0 timeout: 0 cr3: 152423 uptime: 1.4min
    #171748 cov: 830 (+0) corp: 1 (11.0b) exec/s: 1.9k (1 nodes) lastcov: 1.5min crash: 0 timeout: 0 cr3: 171748 uptime: 1.6min
    ...
    
    >wtf.exe fuzz --backend=bochscpu --name acctest1 --limit 10000000 --max_len=1028
    Initializing the debugger instance.. (this takes a bit of time)
    Setting debug register status to zero.
    Setting debug register status to zero.
    acctest1: rip = 7ff85aaa2f20, end = 7ff85aaa2f58
    Could not set a breakpoint at hal!HalpPerfInterrupt.
    Could not set a breakpoint on hal!HalpPerfInterrupt, but carrying on..
    Dialing to tcp://localhost:31337/..
    #19237 cov: 830 exec/s: 1.9k lastcov: 8.0s crash: 0 timeout: 0 cr3: 19237 uptime: 10.0s
    #38678 cov: 830 exec/s: 1.9k lastcov: 18.0s crash: 0 timeout: 0 cr3: 38678 uptime: 20.0s
    #59195 cov: 830 exec/s: 2.0k lastcov: 28.0s crash: 0 timeout: 0 cr3: 59195 uptime: 30.0s
    #79681 cov: 830 exec/s: 2.0k lastcov: 38.0s crash: 0 timeout: 0 cr3: 79681 uptime: 40.0s
    #99926 cov: 830 exec/s: 2.0k lastcov: 48.0s crash: 0 timeout: 0 cr3: 99926 uptime: 50.0s
    #120648 cov: 830 exec/s: 2.0k lastcov: 58.0s crash: 0 timeout: 0 cr3: 120648 uptime: 60.0s
    #136372 cov: 830 exec/s: 1.9k lastcov: 1.1min crash: 0 timeout: 0 cr3: 136372 uptime: 1.2min
    #150664 cov: 830 exec/s: 1.9k lastcov: 1.3min crash: 0 timeout: 0 cr3: 150664 uptime: 1.3min
    #169338 cov: 830 exec/s: 1.9k lastcov: 1.5min crash: 0 timeout: 0 cr3: 169338 uptime: 1.5min
    #184285 cov: 830 exec/s: 1.8k lastcov: 1.6min crash: 0 timeout: 0 cr3: 184285 uptime: 1.7min
    #200383 cov: 830 exec/s: 1.8k lastcov: 1.8min crash: 0 timeout: 0 cr3: 200383 uptime: 1.8min
    
    
    fuzzer_acctest1.cc
    #include "backend.h"
    #include "crash_detection_umode.h"
    #include "targets.h"
    #include <fmt/format.h>
    
    namespace fs = std::filesystem;
    
    namespace acctest1 {
    
    constexpr bool LoggingOn = true;
    
    template <typename... Args_t>
    void DebugPrint(const char *Format, const Args_t &...args) {
      if constexpr (LoggingOn) {
        fmt::print("acctest1: ");
        fmt::print(Format, args...);
      }
    }
    
    bool InsertTestcase(const uint8_t *Buffer, const size_t BufferSize) {
      if (BufferSize < sizeof(uint32_t)) {
        return true;
      }
    
      const auto tgt = Gva_t(g_Backend->Rcx());
      const auto size = g_Backend->Rdx();
      if (!g_Backend->VirtWriteDirty(tgt, Buffer, 
                  BufferSize > size ? size : BufferSize)){
        DebugPrint("Failed to write next testcase!");
        return false;
      }
      //DebugPrint("Testcase written\n");
      return true;
    
    }
    
    bool Init(const Options_t &Opts, const CpuState_t &) {
      //
      // Stop the test-case once we return back from the call [DeviceIoControl]
      //
    
      const Gva_t Rip = Gva_t(g_Backend->Rip());
      DebugPrint("rip = {:x}, end = {:x}\n", Rip, Rip + Gva_t(0x38));
      const Gva_t AfterCall = Rip + Gva_t(0x38); 
      if (!g_Backend->SetBreakpoint(AfterCall, [](Backend_t *Backend) {
            fmt::print("At the end of the function!\n");
            Backend->Stop(Ok_t());
          })) {
        DebugPrint("Failed to SetBreakpoint AfterCall\n");
        return false;
      }
      if (!g_Backend->SetBreakpoint(Rip + Gva_t(3), [](Backend_t *Backend) {
            fmt::print("At the beginnig of the function!\n");
          })) {
        DebugPrint("Failed to SetBreakpoint at the beginning\n");
        return false;
      }
    
      if (!SetupUsermodeCrashDetectionHooks()) {
        fmt::print("Failed to SetupUsermodeCrashDetectionHooks\n");
        return false;
      }
    
      return true;
    }
    
    bool Restore() { return true; }
    
    //
    // Register the target.
    //
    
    Target_t Acctest1("acctest1", Init, InsertTestcase, Restore);
    
    } // namespace acctest1
    

    We can see that:

    • Init() is called, RIP value is correct;
    • the setting of breakpoints does not lead to errors;
    • InsertTestcase() is called on each iteration as well

    However, non of the break points is really reached and there is no single userspace address in the aggregate.cov, only kernel code related to page faults.

    I tried without any luck:

    • regular dump and full dump;
    • g_Backend->VirtWrite, g_Backend->VirtWriteDirty and even empty InsertTestcase();

    Any ideas? My goal is at least to see any usermode addresses in the coverage. Thanks!

    PS: The dump is taken using kdnet -- could that cause the problems? (Pipe memory dump taking seems too slow). During the dump creating there was a line [bdump] rip and gs don't match kernel/user, swapping... but it looks in there README.md there is that like too. So, I would assume it's ok? Here is target directory archive, just in case someone wants to check the dump.

    opened by expend20 9
  • [Question] How to deal with 32bit binaries when doing a snapshot ?

    [Question] How to deal with 32bit binaries when doing a snapshot ?

    Hi, First of all this project looks amazing, thanks for all the documentation and everything :)

    I am trying to replicate the example shown in "Fuzzing Modern UDP Game Protocols With Snapshot-based Fuzzers", but I have a question.

    What if my target binary is a 32bit binary running on a 32bit Hyper-V virtual machine ? I saw that the bdump.js script is looking for some 64bits registers for the "regs.json" output, and the small paragraph about WOW64 in the README.md confuses me.

    Will I be able to run the fuzzer if a create a 32bit version of "bdump.js" ?

    For the context, I am trying to fuzz a 32bit library used by a 32bit binary. If I use a 32bit debuggee virtual machine and a 32bit version of WinDBG, everything is fine, I can break on the desired function and replicate "bdump.js"with my own script.

    But if I use a 64bit debuggee virtual machine with whatever version of WinDbg, I am not able to see my target DLL anymore, so I can't break on it nor take a process snapshot ... All I see are some wow64 related DLL when a switch into the context of the target process.

    I have tried to play with ".effmach" and "!wow64exts.sw" but my target DLL is never accessible that way when running on a 64bit platform.

    Unfortunately, I can't find a lot of resources online regarding this issue. I can't even figure out if this is something possible.

    The README of the project seems to imply that the snapshot must be done on a 64bit platform, but I'm not sure as this is not explicitly written ^^.

    I know that this question is not directly related to the project, and more about the "bdump.js" script usage / WinDbg usage, but since my goal is to fuzz this library using wtf, I take my chance here :)

    Thank you

    opened by GuillaumeOrlando 8
  • how to fix kvm_backend build error

    how to fix kvm_backend build error

    it has a build error on ubuntu 18.04,the output as follows.and i install the qemu-kvm by apt

    kvm_backend.cc:255:7: error: use of undeclared identifier 'KVM_SYNC_X86_REGS' KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS | KVM_SYNC_X86_EVENTS; ^ kvm_backend.cc:872:16: error: no member named 'sregs' in 'kvm_sync_regs' Run_->s.regs.sregs.cr8 = CpuState.Cr8;

    how do fix it? thanks.

    opened by fr0zenrain 8
  • broken emulation on specific circumstance

    broken emulation on specific circumstance

    Backend : bochscpu trace creation : bochscpu Dump VM environment: Hyper-V Gen1 VM, 1 CPU, 4GB RAM


    During when I tried to fuzzing some windows kernel component, I encounter some page fault.

    Animation ( 0xFFFFF8056CC05000 is nt!KiPageFault )

    nt!MmAccessFault's return value was 0x110( =STATUS_PAGE_FAULT_TRANSITION ). I don't know why transition fault was happened at there but I didn't care much about that because it executes normally after that transition fault.

    But the real problem happened when transition fault occured on conditional jump instruction. Animation2

    Transition fault occured on FFFFB1929ADE6483 but saved return address is FFFFB1929AE964E7. It is a next insturction after jz, so FFFFB1929AE964E7 will be executed after execution context restored from interrupt...and it was executed exactly as below.

    Animation3

    As you can see, emulator is broken and it execute as 2-byte aligned.

    0xfffff8056cc05638 <- end of nt!KiPageFault( iretq )
    0xffffb1929ae964e7 <- instruction of fuzzed kernel component...and 2 byte aligned execution for unknown reason
    0xffffb1929ae964e9
    0xffffb1929ae964eb
    0xffffb1929ae964ed
    0xffffb1929ae964ef
    0xffffb1929ae964f1
    0xffffb1929ae964f3
    0xffffb1929ae964f5
    0xffffb1929ae964f7
    0xffffb1929ae964f9
    0xffffb1929ae964fb
    0xffffb1929ae964fd
    0xffffb1929ae964ff
    

    I tried to catch that circumstance using SetBreakpoint on nt!KiPageFault but I couldn't find any method to get previous instruction address on breakpoint handler, so I will be very pleased if you let me know any good method for that.

    opened by y0ny0ns0n 8
  • Checking `g_Dbg.GetModuleBase( 0`">

    Checking `g_Dbg.GetModuleBase("verifier") > 0`

    Unlike other parts, I wonder why there is this line here.

    https://github.com/0vercl0k/wtf/blob/67beeb4ef0297253177397f8505265ac12cd55eb/src/wtf/crash_detection_umode.cc#L154

    opened by donghyunlee00 7
  • Measure the cost of per-instruction callback in bxcpu

    Measure the cost of per-instruction callback in bxcpu

    In #137, edge-coverage is implemented by using a set of hooks that executes on branches vs after every instruction. This means that potentially, we could stop using the per-instruction hook when fuzzing and potentially get a good performance win.

    This task is about trying to find out how much of a speed-up this would bring, and if it looks decent to make edge coverage default, use per-instruction hook when tracing and implement a breakpoint mechanism that doesn't rely on the per-instruction hook.

    enhancement 
    opened by 0vercl0k 0
  • Emulation of ExAllocatePoolWithTag

    Emulation of ExAllocatePoolWithTag

    I looked into fuzzing a driver. However, I'm running into issues when a call to ExAllocatePoolWithTagis executed during the fuzzing withs bochscpu or KVM. Sometimes it crashes directly inside the function and sometimes afterwards. Do you have an idea how to resolve/emulate this? I've attached an example trace file. The last call from the Target is nt!ExAllocatePoolWithTag

    Thanks for your help! efd332708da860ec4c82a347b65118e4.trace.txt

    opened by p0w1 1
  • KVM Windows Virtual Address Translation

    KVM Windows Virtual Address Translation

    Implement VAT to allow the KVM backend to set breakpoints on pages that are in the dump but still in transition.

    Might be useful as an alternative or a complement to memlock.

    PR based on our work on IceBox: https://thalium.github.io/blog/posts/windows-full-memory-introspection-with-icebox/

    opened by clslgrnc 1
  • Improve readme: talk about .cov files

    Improve readme: talk about .cov files

    In #112, I found out that .cov files are not documented in the README and that both cov traces and cov files w/ bp addresses have the same name so maybe fix that as well.

    opened by 0vercl0k 0
  • ELF Snapshotting and Fuzzing

    ELF Snapshotting and Fuzzing

    PR to add support for ELF files to WTF. For full usage instructions and a demo check out the README in the linux_mode directory.

    Added files:

    • raw2dmp
      • Program that converts the raw dump from qemu into a mem.dmp that can be read by WTF.
    • scripts
      • fuzzbkpt.py
        • Creates a class used to set the breakpoint in our executable file.
        • Sets up memory so that it can be dumped once the breakpoint is hit.
      • kernel.py
        • Allows us to access structures using gdb.
        • Lets us read from and write to memory.
      • qemu.py
        • Sets up the cpu command so that we can create the regs.json and symbol-store.json file after the dump is performed.
      • utils.py
        • Utility that lets us update the json files.
    • setup.sh
      • Sets up the environment for taking a snapshot of an elf file.
      • Installs dependencies for qemu and the python scripts.
      • Clones and builds the debug version of qemu for x86_64.
      • Makes the raw2dmp executable.
    • snapshot
      • bpkt.py
        • File used to set the breakpoint in our executable.
        • Needs to be updated with a file name and an address to break on.
      • gdb_client.sh
        • Connects to the remote gdb server and runs bpkt.py.
      • gdb_server.sh
        • Starts up the qemu image inside of gdb.
        • Can be used whenever you need to access the image.
      • move_to_fuzzer.sh
        • Converts the raw file to mem.dmp.
        • Creates a directory in targets and sets it up for fuzzing with required directories.
        • Moves mem.dmp, regs.json, and symbol-store.json into states.
        • Moves over the recompile_wtf script.
      • qemu_file_upload.sh
        • Moves a file from the local machine into the qemu image so that it can be used for snapshotting.
      • recompile_wtf.sh
        • Compiles the elf version of WTF and moves it into the target directory.
    • vars
      • Contains all of the variables needed by the other scripts.

    Modified Files:

    • utils.cc
      • Modified the file to check for a preprocessor definition to change between the normal WTF build and the elf WTF build.
      • Tested switching between the two builds. You will need to make clean and remove the cmake cache files but it will build the two versions with the same code base.
    opened by Kasimir123 1
Releases(v0.4)
  • v0.4(Dec 23, 2022)

    Fuzz all the things 🎅🏽❄️🎄!

    What's Changed

    • Update the scripts to build bochscpu-ffi on Windows and Linux by @0vercl0k in https://github.com/0vercl0k/wtf/pull/121
    • Warn users if no code coverage breakpoints are found by @0vercl0k in https://github.com/0vercl0k/wtf/pull/123
    • Update bxcpu-ffi to latest by @0vercl0k in https://github.com/0vercl0k/wtf/pull/124
    • Make sure to generate handles that actually fit in a 32-bit HANDLE. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/127
    • Generate coverage file with Ghidra by @huwwp in https://github.com/0vercl0k/wtf/pull/128
    • _1MB should be 1MB and not 16MB :facepalm: by @0vercl0k in https://github.com/0vercl0k/wtf/pull/133
    • Move the human functions in their own files / headers by @0vercl0k in https://github.com/0vercl0k/wtf/pull/147
    • Update CI to checkout & upload-artifact by @0vercl0k in https://github.com/0vercl0k/wtf/pull/148
    • Bochscpu: edge coverage by @clslgrnc in https://github.com/0vercl0k/wtf/pull/137
    • Fix memory performance issue related to aligned_alloc by @0vercl0k in https://github.com/0vercl0k/wtf/pull/149
    • Update README by @0vercl0k in https://github.com/0vercl0k/wtf/pull/150
    • Update gifs by @0vercl0k in https://github.com/0vercl0k/wtf/pull/151

    New Contributors

    • @huwwp made their first contribution in https://github.com/0vercl0k/wtf/pull/128
    • @clslgrnc made their first contribution in https://github.com/0vercl0k/wtf/pull/137

    Full Changelog: https://github.com/0vercl0k/wtf/compare/v0.3.2...v0.4

    Source code(tar.gz)
    Source code(zip)
    bin-lin64-clang.Release.zip(6.81 MB)
    bin-lin64-gcc.Release.zip(6.84 MB)
    bin-win64.RelWithDebInfo.zip(13.14 MB)
    target-hevd.7z(237.09 MB)
    target-tlv_server.7z(257.53 MB)
  • v0.3.2(Aug 8, 2022)

    Fuzz all the things 🛫🔥💥!

    What's Changed

    • Add 32bit function return simulate by @y0ny0ns0n in https://github.com/0vercl0k/wtf/pull/96
    • Move the fs hooks from ntdll to nt. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/108
    • Update the CI for clang15 and codeql-v2 by @0vercl0k in https://github.com/0vercl0k/wtf/pull/113
    • Improve README and fix #109 by @0vercl0k in https://github.com/0vercl0k/wtf/pull/110
    • Allow dumps larger than 4GB but warn the user that this is an unconventional configuration by @0vercl0k in https://github.com/0vercl0k/wtf/pull/114
    • Grab the bugcheck code as part of crash detection and fix rdrand opcode detection by @0vercl0k in https://github.com/0vercl0k/wtf/pull/115

    Full Changelog: https://github.com/0vercl0k/wtf/compare/v0.3.1...v0.3.2

    Source code(tar.gz)
    Source code(zip)
    bin-lin64-clang.Release.zip(6.65 MB)
    bin-lin64-gcc.Release.zip(6.67 MB)
    bin-win64.RelWithDebInfo.zip(12.34 MB)
    target-hevd.7z(237.09 MB)
    target-tlv_server.7z(257.53 MB)
  • v0.3.1(Feb 15, 2022)

  • v0.3(Feb 14, 2022)

    Fuzz all the things 🛫🔥💥!

    Highlights

    • Add custom mutate, post mutate, fuzzer_test_tlv_server by @y0ny0ns0n in https://github.com/0vercl0k/wtf/pull/67
    • Add a tlv_server to demonstrate a multi-packet target by @0vercl0k in https://github.com/0vercl0k/wtf/pull/71
    • Demonstrate multi-packets testcase delivery w/ fuzzer_tlv_server by @0vercl0k in https://github.com/0vercl0k/wtf/pull/76
    • Allow users to provide custom generators / mutators by @0vercl0k in https://github.com/0vercl0k/wtf/pull/78

    What's Changed

    • Client does not need TestcaseBufferMaxSize. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/66
    • Add custom mutate, post mutate, fuzzer_test_tlv_server by @y0ny0ns0n in https://github.com/0vercl0k/wtf/pull/67
    • Fix missing symbol format args when caching symbol name by @JohnPMerrill in https://github.com/0vercl0k/wtf/pull/70
    • Add a tlv_server to demonstrate a multi-packet target by @0vercl0k in https://github.com/0vercl0k/wtf/pull/71
    • Fix broken hyperlink by @y0ny0ns0n in https://github.com/0vercl0k/wtf/pull/72
    • Demonstrate multi-packets testcase delivery w/ fuzzer_tlv_server by @0vercl0k in https://github.com/0vercl0k/wtf/pull/76
    • Allow users to provide custom generators / mutators by @0vercl0k in https://github.com/0vercl0k/wtf/pull/78
    • Update README to prefer relative links by @0vercl0k in https://github.com/0vercl0k/wtf/pull/79
    • Adjust DebugPrint macro for fmt >= 8 by @0vercl0k in https://github.com/0vercl0k/wtf/pull/80
    • Check the size of the RAM to avoid underflow by @0vercl0k in https://github.com/0vercl0k/wtf/pull/81

    New Contributors

    • @y0ny0ns0n made their first contribution in https://github.com/0vercl0k/wtf/pull/67
    • @JohnPMerrill made their first contribution in https://github.com/0vercl0k/wtf/pull/70

    Full Changelog: https://github.com/0vercl0k/wtf/compare/v0.2...v0.3

    Source code(tar.gz)
    Source code(zip)
    bin-lin64-clang.Release.zip(5.77 MB)
    bin-lin64-gcc.Release.zip(6.67 MB)
    bin-win64.RelWithDebInfo.zip(12.28 MB)
    target-hevd.7z(237.09 MB)
    target-tlv_server.7z(257.53 MB)
  • v0.2(Dec 21, 2021)

    Happy holidays! 🎅🏽🤶🏽❄️🎄

    Highlights

    • Adds support for generating Tenet traces with bochs backend by @gaasedelen in https://github.com/0vercl0k/wtf/pull/12
    • sanity checking for segment registers, remove uneeded segment code in… by @wumb0 in https://github.com/0vercl0k/wtf/pull/29
    • Copy dbgeng/dbgcore.dll so that the distribution works on Win11 by @0vercl0k in https://github.com/0vercl0k/wtf/pull/33
    • Remove special casing related to @tr in WinHV backend by @0vercl0k in https://github.com/0vercl0k/wtf/pull/35
    • Update documentation for wow64 by @0vercl0k in https://github.com/0vercl0k/wtf/pull/37

    What's Changed

    • Fix broken links in README by @yuawn in https://github.com/0vercl0k/wtf/pull/3
    • Move off injectdll, add kva script. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/11
    • Stores bochscpu breakpoints in a dictionary. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/13
    • Fix hevd module by @0vercl0k in https://github.com/0vercl0k/wtf/pull/16
    • Adds support for generating Tenet traces with bochs backend by @gaasedelen in https://github.com/0vercl0k/wtf/pull/12
    • Add a hlt hook to prevent infinite-loop. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/23
    • Add ordlookup to be able to handle files that use ordinal imports. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/26
    • Add missing RBX register by @x9090 in https://github.com/0vercl0k/wtf/pull/27
    • sanity checking for segment registers, remove uneeded segment code in… by @wumb0 in https://github.com/0vercl0k/wtf/pull/29
    • Copy dbgeng/dbgcore.dll so that the distribution works on Win11 by @0vercl0k in https://github.com/0vercl0k/wtf/pull/33
    • Remove special casing related to @tr in WinHV backend by @0vercl0k in https://github.com/0vercl0k/wtf/pull/35
    • Update documentation for wow64 by @0vercl0k in https://github.com/0vercl0k/wtf/pull/37
    • Get rid of the macros used to turn on logging in subsystems. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/53
    • Update third party dependencies. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/54
    • Dump the aggregated code-coverage into a file. by @0vercl0k in https://github.com/0vercl0k/wtf/pull/55
    • Fix bug in client metrics by @0vercl0k in https://github.com/0vercl0k/wtf/pull/56
    • Ignore BX_INSERTED_OPCODE in BeforeExecutionHook by @0vercl0k in https://github.com/0vercl0k/wtf/pull/58
    • Make --trace-path defaults to the cwd if none is specified by @0vercl0k in https://github.com/0vercl0k/wtf/pull/59
    • Add documentation for Tenet by @0vercl0k in https://github.com/0vercl0k/wtf/pull/60

    New Contributors

    • @yuawn made their first contribution in https://github.com/0vercl0k/wtf/pull/3
    • @gaasedelen made their first contribution in https://github.com/0vercl0k/wtf/pull/12
    • @x9090 made their first contribution in https://github.com/0vercl0k/wtf/pull/27
    • @wumb0 made their first contribution in https://github.com/0vercl0k/wtf/pull/29

    Full Changelog: https://github.com/0vercl0k/wtf/compare/v0.1...v0.2

    Source code(tar.gz)
    Source code(zip)
    bin-lin64-clang.Release.zip(5.63 MB)
    bin-lin64-gcc.Release.zip(6.63 MB)
    bin-win64.RelWithDebInfo.zip(12.04 MB)
    targets-hevd.7z(237.08 MB)
Owner
Axel Souchet
Axel Souchet
Distributed, Encrypted, Fractured File System - A custom distributed file system written in C with FUSE

A custom FUSE-based filesystem that distributes encrypted shards of data across machines on a local network, allowing those files to be accessible from any machine.

Charles Averill 14 Nov 2, 2022
OSS-Sydr-Fuzz - OSS-Fuzz fork for hybrid fuzzing (fuzzer+DSE) open source software.

OSS-Sydr-Fuzz: Hybrid Fuzzing for Open Source Software This repository is a fork of OSS-Fuzz project. OSS-Sydr-Fuzz contains open source software targ

Ivannikov Institute for System Programming of the Russian Academy of Sciences 46 Dec 27, 2022
High-level build system for distributed, multi-platform C/C++ projects.

fips fips is a highlevel build system wrapper written in Python for C/C++ projects. (this project has nothing to do with the Federal Information Proce

Andre Weissflog 427 Dec 25, 2022
A high-performance distributed Bitcoin mining pool server.

Viabtc Mining Server ViaBTC Mining Server is a high-performance distributed Bitcoin mining pool server. We have made a lot of optimizations for Bitcoi

ViaBTC 96 Nov 22, 2022
Tink is a multi-language, cross-platform, open source library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

Tink A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse. Ubuntu

Google 12.9k Jan 9, 2023
XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight and AstroBWT unified CPU/GPU miner

XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight and AstroBWT unified CPU/GPU miner and RandomX benchmark. Official binaries are available for Windows, Linux, macOS and FreeBSD.

null 7.3k Jan 9, 2023
A Powerful, Easy-to-Use, Compact, Cross-Platform and Installation-Free Crypto Tool. 一个强大,易用,小巧,跨平台且免安装的加密解密签名工具。

GpgFrontend GpgFrontend is a Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free OpenPGP Crypto Tool. By using GpgFrontend, you can

Saturn&Eric 203 Jan 7, 2023
Nano is a digital payment protocol designed to be accessible and lightweight, with a focus on removing inefficiencies present in other cryptocurrencies.

Nano is a digital payment protocol designed to be accessible and lightweight, with a focus on removing inefficiencies present in other cryptocurrencies. With ultrafast transactions and zero fees on a secure, green and decentralized network, this makes Nano ideal for everyday transactions.

Nano 3.5k Jan 7, 2023
Nano is a digital payment protocol designed to be accessible and lightweight, with a focus on removing inefficiencies present in other cryptocurrencies.

Nano is a digital payment protocol designed to be accessible and lightweight, with a focus on removing inefficiencies present in other cryptocurrencies. With ultrafast transactions and zero fees on a secure, green and decentralized network, this makes Nano ideal for everyday transactions.

Nano 3.1k May 5, 2021
FCracker is a command line tool designed to brute force encrypted files like zip, 7z, rar, pdf etc.

FCrack is a command-line tool designed to brute force encrypted files like zip, 7z, rar, pdf, gpg etc.

null 23 Dec 21, 2022
BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.

Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.

Google 1.4k Dec 25, 2022
SHA256 Compute Shader (Kernel) Written in Rust

SHA256 Compute Shader (Kernel) Written in Rust ... with application to Validating the Bitcoin Blockchain Abstract The project consists of two primary

Daniel 38 Nov 10, 2022
Keystroke-level online anonymization kernel: obfuscates typing behavior at the device level.

Keystroke-level online anonymization kernel: obfuscates typing behavior at the device level.

Vinnie Monaco 362 Dec 25, 2022
A useful tool for identifying the architecture, platform type, compiler, and operating system specifications by preprocessor feature support.

Platform-Detector Cross-Platform Information Detector It is a useful tool for identifying the architecture, platform type, compiler, and operating sys

Kambiz Asadzadeh 10 Jul 27, 2022
This tool demonstrates the power of UAC bypasses and built-in features of Windows.

Auto-Elevate This tool demonstrates the power of UAC bypasses and built-in features of Windows. This utility auto-locates winlogon.exe, steals and imp

null 129 Dec 7, 2022
obfuscated any constant encryption in compile time on any platform

oxorany 带有混淆的编译时任意常量加密 English 介绍 我们综合了开源项目ollvm、xorstr一些实现思路,以及c++14标准中新加入的constexpr关键字和一些模板的知识,完成了编译时的任意常量的混淆(可选)和加密功能。

Chase 154 Dec 29, 2022
Windows Elevation

What's this This project is mainly used to collect the commonly used exp of Windows platform and give the relevant repair scheme. On the one hand, it

Al1ex 503 Dec 28, 2022
PrintNightmare - Windows Print Spooler RCE/LPE Vulnerability (CVE-2021-34527, CVE-2021-1675) proof of concept exploits

PrintNightmare - Windows Print Spooler RCE/LPE Vulnerability (CVE-2021-34527, CVE-2021-1675) Summary This is a remote code execution vulnerability tha

Jay K 72 Nov 18, 2022
How to exploit a vulnerable windows driver. Exploit for AsrDrv104.sys

Exploit and Proof of Concept (PoC) for CVE-2020-15368. Asrock repackaged rweverything driver for their RGB controller configuration tool and signed it. They "protect" it by encrypting their ioctls...lol. We found this CVE by accident last summer, and afaik the driver still isn't patched. The impact is of course arbitrary code execution in kernel, etc. So enjoy this "0day" lol.

Stephen Tong 354 Jan 2, 2023