Skip to content

Commit

Permalink
Add a KASAN demo sample (#1228)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnMcSandwich authored Nov 4, 2024
1 parent 55daf85 commit ea026ed
Show file tree
Hide file tree
Showing 10 changed files with 968 additions and 0 deletions.
46 changes: 46 additions & 0 deletions tools/kasan/samples/KasanDemo-WDM/KasanDemo.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{C4575BAC-8843-4B59-88F5-8D142A59F463}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sys", "Sys", "{52CD4CBC-6018-4367-BE2B-EA5A2864E7BE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kasanagent", "exe\kasanagent.vcxproj", "{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kasantrigger", "sys\kasantrigger.vcxproj", "{29BD96E0-B6C5-42A0-B683-FD9740810699}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Release|ARM64 = Release|ARM64
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Debug|ARM64.ActiveCfg = Debug|ARM64
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Debug|ARM64.Build.0 = Debug|ARM64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Debug|ARM64.ActiveCfg = Debug|ARM64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Debug|ARM64.Build.0 = Debug|ARM64
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Release|ARM64.ActiveCfg = Release|ARM64
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Release|ARM64.Build.0 = Release|ARM64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Release|ARM64.ActiveCfg = Release|ARM64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Release|ARM64.Build.0 = Release|ARM64
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Debug|x64.ActiveCfg = Debug|x64
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Debug|x64.Build.0 = Debug|x64
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Release|x64.ActiveCfg = Release|x64
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}.Release|x64.Build.0 = Release|x64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Debug|x64.ActiveCfg = Debug|x64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Debug|x64.Build.0 = Debug|x64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Release|x64.ActiveCfg = Release|x64
{29BD96E0-B6C5-42A0-B683-FD9740810699}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{61899E58-10C2-4EB1-9508-58AE7DC3B3A9} = {C4575BAC-8843-4B59-88F5-8D142A59F463}
{29BD96E0-B6C5-42A0-B683-FD9740810699} = {52CD4CBC-6018-4367-BE2B-EA5A2864E7BE}
EndGlobalSection
EndGlobal
25 changes: 25 additions & 0 deletions tools/kasan/samples/KasanDemo-WDM/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
page_type: sample
description: "Demonstrates KASAN."
languages:
- cpp
products:
- windows
- windows-wdk
---

# KasanDemo

This sample demonstrates how KASAN detects illegal memory accesses.

The sample consists of a legacy device driver that contains intentionally incorrect code that performs illegal memory accesses, and a Win32 console agent that interacts with the driver to trigger different types of illegal memory accesses that KASAN successfully detects.

> [!CAUTION]
> This driver contains INTENTIONALLY INCORRECT code. Neither this driver nor its sample programs are intended for use in a production environment. Instead, they are intended for educational purposes.
> [!CAUTION]
> This driver will cause KASAN to bugcheck your system.
## Run the sample

To run this sample, enable KASAN in your system, load the `kasantrigger.sys` driver, and then run the `kasanagent.exe` application.
157 changes: 157 additions & 0 deletions tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*++
Copyright (c) 2024 Microsoft Corporation All Rights Reserved
Module Name:
agent.c
Abstract:
Usermode agent that interacts with the kasantrigger.sys driver to
demonstrate how KASAN detects illegal memory accesses.
Environment:
Win32 console multi-threaded application.
--*/

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strsafe.h>
#include <sys\kasantrigger.h>

VOID __cdecl
main(
_In_ ULONG argc,
_In_reads_(argc) PCHAR argv[]
)
{
ULONG bytesReturned;
INT choice;
HANDLE hDevice;
ULONG index;
DWORD ioctlCode;
BOOLEAN isKasanEnabledOnDriver;
BOOL success;
UCHAR value;

UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);

printf(
" _ __ ______ \n"
"| | / / | _ \\ \n"
"| |/ / __ _ ___ __ _ _ __ | | | |___ _ __ ___ ___ \n"
"| \\ / _` / __|/ _` | '_ \\ | | | / _ \\ '_ ` _ \\ / _ \\ \n"
"| |\\ \\ (_| \\__ \\ (_| | | | | | |/ / __/ | | | | | (_) |\n"
"\\_| \\_/\\__,_|___/\\__,_|_| |_| |___/ \\___|_| |_| |_|\\___/ \n\n"
);

//
// Open the device.
//

hDevice = CreateFile("\\\\.\\KasanTrigger",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (hDevice == INVALID_HANDLE_VALUE) {
printf("CreateFile failed: %d. Did you forget to load kasantrigger.sys?\n",
GetLastError());
return;
}

//
// Check whether KASAN is enabled on the driver.
//

success = DeviceIoControl(hDevice,
(DWORD)IOCTL_KASANTRIGGER_INFO,
NULL,
0,
&isKasanEnabledOnDriver,
sizeof(isKasanEnabledOnDriver),
&bytesReturned,
NULL);
if (!success) {
printf("DeviceIoControl failed: %d\n\n", GetLastError());
return;
}

if (!isKasanEnabledOnDriver) {
printf("WARNING: KASAN is not enabled on kasantrigger.sys\n\n");
}

printf("Enter a number in the menu below to trigger the desired condition:\n");
printf("1. Trigger a stack out-of-bounds read\n");
printf("2. Trigger a global out-of-bounds read\n");
printf("3. Trigger a heap out-of-bounds read\n\n");

while (TRUE) {
printf("> ");
while ((choice = getchar()) == '\n');

switch (choice) {
case '1':
ioctlCode = (DWORD)IOCTL_KASANTRIGGER_OOBR_STACK;
break;
case '2':
ioctlCode = (DWORD)IOCTL_KASANTRIGGER_OOBR_GLOBAL;
break;
case '3':
ioctlCode = (DWORD)IOCTL_KASANTRIGGER_OOBR_HEAP;
break;
default:
printf("Incorrect input, try again\n");
continue;
}

printf("You have selected %c. Excellent choice. ", choice);
Sleep(1000);
printf("Triggering in 3...");
Sleep(1000);
printf(" 2...");
Sleep(1000);
printf(" 1...");
Sleep(1000);
printf("\n");

index = KASANTRIGGER_ARRAY_SIZE;
value = 0;

success = DeviceIoControl(hDevice,
ioctlCode,
&index,
sizeof(index),
&value,
sizeof(value),
&bytesReturned,
NULL);
if (!success) {
printf("DeviceIoControl failed: %d\n", GetLastError());
return;
}

//
// KASAN should have normally triggered a bugcheck, so this should be
// unreachable.
//

if (isKasanEnabledOnDriver) {
printf("Still alive. The bugcheck was not issued. This is not expected.\n");
} else {
printf("Still alive, because KASAN was not enabled on the driver. The illegal access went undetected.\n");
}
}

CloseHandle(hDevice);
}
Loading

0 comments on commit ea026ed

Please sign in to comment.