diff options
| author | JohnMcSandwich <[email protected]> | 2024-11-04 17:16:47 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-11-04 14:16:47 -0800 |
| commit | ea026ed7e82fe5b45f0d978661e68c7f3249f3fc (patch) | |
| tree | 82dfe3e7887b7ccccf24cc3ebc7c94577e38b1a7 | |
| parent | 55daf853968b2f555bb69da38623da7e28bcab42 (diff) | |
Add a KASAN demo sample (#1228)
10 files changed, 968 insertions, 0 deletions
diff --git a/tools/kasan/samples/KasanDemo-WDM/KasanDemo.sln b/tools/kasan/samples/KasanDemo-WDM/KasanDemo.sln new file mode 100644 index 00000000..fe0c0464 --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/KasanDemo.sln @@ -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 diff --git a/tools/kasan/samples/KasanDemo-WDM/README.md b/tools/kasan/samples/KasanDemo-WDM/README.md new file mode 100644 index 00000000..0c9c6fef --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/README.md @@ -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. diff --git a/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.c b/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.c new file mode 100644 index 00000000..2b6b726c --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.c @@ -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); +}
\ No newline at end of file diff --git a/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.vcxproj b/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.vcxproj new file mode 100644 index 00000000..9556e374 --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.vcxproj @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{61899E58-10C2-4EB1-9508-58AE7DC3B3A9}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">x64</Platform> + <SampleGuid>{14E9681A-41C8-43B1-885D-6CD8CB06AAD8}</SampleGuid> + <ProjectName>kasanagent</ProjectName> + <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>kasanagent</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <TargetName>kasanagent</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>kasanagent</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <TargetName>kasanagent</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="kasanagent.c" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.vcxproj.Filters b/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.vcxproj.Filters new file mode 100644 index 00000000..445aa804 --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/exe/kasanagent.vcxproj.Filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{49310AE5-27D6-4E5F-8E16-7787FBBFC870}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{10285CDD-3CE2-48BD-9108-C546303EC345}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{4DC87590-E3DB-45A9-8BF6-F0552982B4A7}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="kasanagent.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.c b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.c new file mode 100644 index 00000000..3605f7ff --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.c @@ -0,0 +1,303 @@ +/*++ + +Copyright (c) 2024 Microsoft Corporation All Rights Reserved + +Module Name: + + kasantrigger.c + +Abstract: + + The purpose of this driver is to demonstrate how KASAN detects illegal + memory accesses. + +Environment: + + Kernel mode only. + +--*/ + +#include <ntddk.h> +#include <string.h> +#include "kasantrigger.h" + +#define NT_DEVICE_NAME L"\\Device\\KASANTRIGGER" +#define DOS_DEVICE_NAME L"\\DosDevices\\KasanTrigger" + +DRIVER_INITIALIZE DriverEntry; + +_Dispatch_type_(IRP_MJ_CREATE) +_Dispatch_type_(IRP_MJ_CLOSE) +DRIVER_DISPATCH KasanTriggerCreateClose; + +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) +DRIVER_DISPATCH KasanTriggerDeviceControl; + +DRIVER_UNLOAD KasanTriggerUnloadDriver; + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT, DriverEntry) +#pragma alloc_text(PAGE, KasanTriggerCreateClose) +#pragma alloc_text(PAGE, KasanTriggerDeviceControl) +#pragma alloc_text(PAGE, KasanTriggerUnloadDriver) +#endif + +// ----------------------------------------------------------------------------- + +UCHAR GlobalVariable[KASANTRIGGER_ARRAY_SIZE]; + +static +UCHAR +TriggerOobrStack( + _In_ ULONG Index + ) +{ + UCHAR StackVariable[KASANTRIGGER_ARRAY_SIZE]; + + // + // This copy is only here to force the compiler not to optimize out the + // stack variable. + // + + RtlCopyMemory(StackVariable, GlobalVariable, KASANTRIGGER_ARRAY_SIZE); + + // + // WARNING: this is an intentionally INCORRECT code! + // + + return StackVariable[Index]; +} + +static +UCHAR +TriggerOobrGlobal( + _In_ ULONG Index + ) +{ + // + // WARNING: this is an intentionally INCORRECT code! + // + + return GlobalVariable[Index]; +} + +static +UCHAR +TriggerOobrHeap( + _In_ ULONG Index + ) +{ + PCHAR buffer; + UCHAR retVal; + + buffer = ExAllocatePool2(POOL_FLAG_PAGED, KASANTRIGGER_ARRAY_SIZE, 'mDaK'); + if (buffer == NULL) { + return 0; + } + + // + // WARNING: this is an intentionally INCORRECT code! + // + + retVal = buffer[Index]; + + ExFreePool(buffer); + + return retVal; +} + +// ----------------------------------------------------------------------------- + +NTSTATUS +DriverEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath + ) +{ + NTSTATUS ntStatus; + UNICODE_STRING ntUnicodeString; + UNICODE_STRING ntWin32NameString; + PDEVICE_OBJECT deviceObject; + + UNREFERENCED_PARAMETER(RegistryPath); + + RtlInitUnicodeString(&ntUnicodeString, NT_DEVICE_NAME); + + ntStatus = IoCreateDevice(DriverObject, + 0, + &ntUnicodeString, + FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &deviceObject); + if (!NT_SUCCESS(ntStatus)) { + return ntStatus; + } + + DriverObject->MajorFunction[IRP_MJ_CREATE] = KasanTriggerCreateClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = KasanTriggerCreateClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KasanTriggerDeviceControl; + DriverObject->DriverUnload = KasanTriggerUnloadDriver; + + RtlInitUnicodeString(&ntWin32NameString, DOS_DEVICE_NAME); + + ntStatus = IoCreateSymbolicLink(&ntWin32NameString, &ntUnicodeString); + + if (!NT_SUCCESS(ntStatus)) { + IoDeleteDevice(deviceObject); + } + + return ntStatus; +} + +NTSTATUS +KasanTriggerCreateClose( + PDEVICE_OBJECT DeviceObject, + PIRP Irp + ) +{ + UNREFERENCED_PARAMETER(DeviceObject); + + PAGED_CODE(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +VOID +KasanTriggerUnloadDriver( + _In_ PDRIVER_OBJECT DriverObject + ) +{ + PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; + UNICODE_STRING uniWin32NameString; + + PAGED_CODE(); + + RtlInitUnicodeString(&uniWin32NameString, DOS_DEVICE_NAME); + IoDeleteSymbolicLink(&uniWin32NameString); + + if (deviceObject != NULL) { + IoDeleteDevice(deviceObject); + } + + return; +} + +NTSTATUS +KasanTriggerDeviceControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp + ) +{ + PIO_STACK_LOCATION irpSp; + NTSTATUS ntStatus; + ULONG inBufLength; + ULONG inIndex; + ULONG outBufLength; + PUCHAR outValue; + PBOOLEAN isKasanEnabledOnDriver; + + UNREFERENCED_PARAMETER(DeviceObject); + + PAGED_CODE(); + + irpSp = IoGetCurrentIrpStackLocation(Irp); + inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; + outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; + + ntStatus = STATUS_SUCCESS; + + switch (irpSp->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_KASANTRIGGER_INFO: + + // + // Return information. Just a BOOLEAN that indicates whether the + // driver was compiled with KASAN or not. + // + + if (inBufLength != 0 || outBufLength != sizeof(BOOLEAN)) { + ntStatus = STATUS_INVALID_PARAMETER; + goto End; + } + + isKasanEnabledOnDriver = (PBOOLEAN)Irp->AssociatedIrp.SystemBuffer; +#if defined(__SANITIZE_ADDRESS__) + *isKasanEnabledOnDriver = TRUE; +#else + *isKasanEnabledOnDriver = FALSE; +#endif + + Irp->IoStatus.Information = sizeof(BOOLEAN); + break; + + case IOCTL_KASANTRIGGER_OOBR_STACK: + + // + // Trigger an out-of-bounds read on the stack. + // + + if (inBufLength != sizeof(ULONG) || outBufLength != sizeof(UCHAR)) { + ntStatus = STATUS_INVALID_PARAMETER; + goto End; + } + + inIndex = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + outValue = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; + *outValue = TriggerOobrStack(inIndex); + + Irp->IoStatus.Information = sizeof(UCHAR); + break; + + case IOCTL_KASANTRIGGER_OOBR_GLOBAL: + + // + // Trigger an out-of-bounds read on a global variable. + // + + if (inBufLength != sizeof(ULONG) || outBufLength != sizeof(UCHAR)) { + ntStatus = STATUS_INVALID_PARAMETER; + goto End; + } + + inIndex = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + outValue = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; + *outValue = TriggerOobrGlobal(inIndex); + + Irp->IoStatus.Information = sizeof(UCHAR); + break; + + case IOCTL_KASANTRIGGER_OOBR_HEAP: + + // + // Trigger an out-of-bounds read on a heap buffer. + // + + if (inBufLength != sizeof(ULONG) || outBufLength != sizeof(UCHAR)) { + ntStatus = STATUS_INVALID_PARAMETER; + goto End; + } + + inIndex = *((PULONG)Irp->AssociatedIrp.SystemBuffer); + outValue = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; + *outValue = TriggerOobrHeap(inIndex); + + Irp->IoStatus.Information = sizeof(UCHAR); + break; + + default: + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + break; + } + +End: + + Irp->IoStatus.Status = ntStatus; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return ntStatus; +} diff --git a/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.h b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.h new file mode 100644 index 00000000..aad3b5c2 --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.h @@ -0,0 +1,30 @@ +/*++ + +Copyright (c) 2024 Microsoft Corporation + +Module Name: + + kasantrigger.h + +--*/ + +// +// Device type. +// + +#define KASANTRIGGER_TYPE 40000 + +// +// The IOCTL function codes from 0x800 to 0xFFF are for customer use. +// + +#define IOCTL_KASANTRIGGER_INFO \ + CTL_CODE(KASANTRIGGER_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_KASANTRIGGER_OOBR_STACK \ + CTL_CODE(KASANTRIGGER_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_KASANTRIGGER_OOBR_GLOBAL \ + CTL_CODE(KASANTRIGGER_TYPE, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_KASANTRIGGER_OOBR_HEAP \ + CTL_CODE(KASANTRIGGER_TYPE, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define KASANTRIGGER_ARRAY_SIZE 8 diff --git a/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.rc b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.rc new file mode 100644 index 00000000..409221ac --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.rc @@ -0,0 +1,10 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM +#define VER_FILEDESCRIPTION_STR "Sample Driver" +#define VER_INTERNALNAME_STR "kasantrigger.sys" + +#include "common.ver" diff --git a/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.vcxproj b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.vcxproj new file mode 100644 index 00000000..f5946ed5 --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.vcxproj @@ -0,0 +1,155 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{29BD96E0-B6C5-42A0-B683-FD9740810699}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">x64</Platform> + <SampleGuid>{A08AE94A-35FF-4A31-B152-5E3A43CE78A0}</SampleGuid> + <ProjectName>kasantrigger</ProjectName> + <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <EnableKASAN>true</EnableKASAN> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <EnableKASAN>true</EnableKASAN> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Windows Driver</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>kasantrigger</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <TargetName>kasantrigger</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>kasantrigger</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <TargetName>kasantrigger</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <DriverSign> + <FileDigestAlgorithm>sha256</FileDigestAlgorithm> + </DriverSign> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="kasantrigger.c" /> + <ResourceCompile Include="kasantrigger.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="kasantrigger.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.vcxproj.Filters b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.vcxproj.Filters new file mode 100644 index 00000000..afae3e08 --- /dev/null +++ b/tools/kasan/samples/KasanDemo-WDM/sys/kasantrigger.vcxproj.Filters @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{70613DC7-CE18-48E4-A282-83BAD5F14DB8}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{61600929-B133-4CE1-A15E-E4E6B15BAFDD}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{E7360814-7364-44AA-933C-DD4BFBF95E8D}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{CF3AF6D6-43D2-4102-8996-8EF19621C095}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="kasantrigger.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="kasantrigger.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="kasantrigger.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file |
