diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /general/obcallback | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'general/obcallback')
| -rw-r--r-- | general/obcallback/ReadMe.md | 42 | ||||
| -rw-r--r-- | general/obcallback/control/ObCallbackTestCtrl.vcxproj | 236 | ||||
| -rw-r--r-- | general/obcallback/control/ObCallbackTestCtrl.vcxproj.Filters | 28 | ||||
| -rw-r--r-- | general/obcallback/control/common.h | 86 | ||||
| -rw-r--r-- | general/obcallback/control/main.cpp | 320 | ||||
| -rw-r--r-- | general/obcallback/control/pch.h | 18 | ||||
| -rw-r--r-- | general/obcallback/control/pchsrc.cpp | 1 | ||||
| -rw-r--r-- | general/obcallback/control/readme.txt | 57 | ||||
| -rw-r--r-- | general/obcallback/control/utils.cpp | 727 | ||||
| -rw-r--r-- | general/obcallback/driver/ObCallbackTest.vcxproj | 210 | ||||
| -rw-r--r-- | general/obcallback/driver/ObCallbackTest.vcxproj.Filters | 35 | ||||
| -rw-r--r-- | general/obcallback/driver/callback.c | 479 | ||||
| -rw-r--r-- | general/obcallback/driver/pch.h | 13 | ||||
| -rw-r--r-- | general/obcallback/driver/pchsrc.c | 1 | ||||
| -rw-r--r-- | general/obcallback/driver/shared.h | 95 | ||||
| -rw-r--r-- | general/obcallback/driver/tdriver.c | 532 | ||||
| -rw-r--r-- | general/obcallback/driver/tdriver.h | 125 | ||||
| -rw-r--r-- | general/obcallback/driver/util.c | 73 | ||||
| -rw-r--r-- | general/obcallback/obcallback.sln | 46 |
19 files changed, 3124 insertions, 0 deletions
diff --git a/general/obcallback/ReadMe.md b/general/obcallback/ReadMe.md new file mode 100644 index 00000000..def34eac --- /dev/null +++ b/general/obcallback/ReadMe.md @@ -0,0 +1,42 @@ +ObCallback Callback Registration Driver +======================================= + +The ObCallback sample driver demonstrates the use of registered callbacks for process protection. The driver registers control callbacks which are called at process creation. + + +Design and Operation +-------------------- + +The sample exercises both the [**PsSetCreateProcessNotifyRoutineEx**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff559951) and the [**ObRegisterCallbacks**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff558692) routines. The first example uses the **ObRegisterCallbacks** routine and a callback to restrict requested access rights during a open process action. The second example uses the **PsSetCreateProcessNotifyRoutineEx** routine to reject a process creation by examining the command line. + +The following is a command line usage scenario to exercise access restriction: + +``` {.syntax xml:space="preserve"} +C:\> obcallbacktestctrl.exe -? (for command line help) +C:\> obcallbacktestctrl.exe -install (installs the kernel driver) +C:\> obcallbacktestctrl.exe -name notepad (specifies that the string “notepad” will be watched as a protected executable) + (now you can start up “notepad.exe”) +C:\> notepad + +C:\> tlist (locate the process ID of notepad.exe) + +C:\> kill –f 2329 (attempt to kill off the notepad.exe with a PID of 2329) +process notepad.exe (2329) – ‘Untitled – Notepad’ could not be killed + +C:\> obcallbacktestctrl.exe -deprotect (remove the protections on the notepad process) + +C:\> kill –f 2329 (attempt to kill off the process – which will succeed) +C:\> obcallbacktestctrl.exe -uninstall (uninstall the kernel driver) + + +``` + +The following is another sample test you can run to prevent a process from being created: + +``` {.syntax xml:space="preserve"} +C:\> obcallbacktestctrl.exe -install (installs the kernel driver) +C:\> obcallbacktestctrl.exe -reject notepad (specifies that the string “notepad” will be watched and prevented from starting as a process) + +C:\> notepad (now you can start up “notepad.exe”) +Access is denied. +``` diff --git a/general/obcallback/control/ObCallbackTestCtrl.vcxproj b/general/obcallback/control/ObCallbackTestCtrl.vcxproj new file mode 100644 index 00000000..d9ea7f08 --- /dev/null +++ b/general/obcallback/control/ObCallbackTestCtrl.vcxproj @@ -0,0 +1,236 @@ +<?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|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</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>{8B053BEE-EA21-4D12-984B-6C93FE6D4992}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{BED8786D-3B67-42D0-AC7B-D7D2F45E551E}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</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>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</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)'=='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)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <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>ObCallbackTestCtrl</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>ObCallbackTestCtrl</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>ObCallbackTestCtrl</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>ObCallbackTestCtrl</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Link> + <AdditionalOptions>%(AdditionalOptions) /LARGEADDRESSAWARE</AdditionalOptions> + <AdditionalDependencies>%(AdditionalDependencies);ntdll.lib;kernel32.lib;advapi32.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Link> + <AdditionalOptions>%(AdditionalOptions) /LARGEADDRESSAWARE</AdditionalOptions> + <AdditionalDependencies>%(AdditionalDependencies);ntdll.lib;kernel32.lib;advapi32.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Link> + <AdditionalOptions>%(AdditionalOptions) /LARGEADDRESSAWARE</AdditionalOptions> + <AdditionalDependencies>%(AdditionalDependencies);ntdll.lib;kernel32.lib;advapi32.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Link> + <AdditionalOptions>%(AdditionalOptions) /LARGEADDRESSAWARE</AdditionalOptions> + <AdditionalDependencies>%(AdditionalDependencies);ntdll.lib;kernel32.lib;advapi32.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>pch.h</PreCompiledHeaderFile> + <PreCompiledHeader>Use</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\pch.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + <ClCompile Include="pchsrc.cpp"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>pch.h</PreCompiledHeaderFile> + <PreCompiledHeader>Create</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\pch.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + <ClCompile Include="utils.cpp"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>pch.h</PreCompiledHeaderFile> + <PreCompiledHeader>Use</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\pch.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" /> + </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/general/obcallback/control/ObCallbackTestCtrl.vcxproj.Filters b/general/obcallback/control/ObCallbackTestCtrl.vcxproj.Filters new file mode 100644 index 00000000..b9258c52 --- /dev/null +++ b/general/obcallback/control/ObCallbackTestCtrl.vcxproj.Filters @@ -0,0 +1,28 @@ +<?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>{5FCF0F0F-49FE-446D-9A27-490CBE156E8F}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{F9488019-A49A-430B-818A-BB8ADC3106D1}</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>{DBBA22E4-2B2D-4D16-8C9A-26B358D8752E}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pchsrc.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="utils.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/general/obcallback/control/common.h b/general/obcallback/control/common.h new file mode 100644 index 00000000..1ba366a2 --- /dev/null +++ b/general/obcallback/control/common.h @@ -0,0 +1,86 @@ + +// Notice: +// +// Use this sample code at your own risk; there is no support from Microsoft for the sample code. +// In addition, this sample code is licensed to you under the terms of the Microsoft Public License +// (http://www.microsoft.com/opensource/licenses.mspx) + +#pragma once + +#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union + +#include "..\driver\shared.h" + +// +// Logging support macros. +// +// LOG_INFO +// LOG_INFO_FAILURE +// LOG_PASSED +// LOG_ERROR +// + + +#ifdef DEBUG +#define LOG_INFO(fmt, ...) \ + _tprintf(_T("%hs: ") fmt, __FUNCTION__, __VA_ARGS__);_tprintf(_T("\n")); +#define LOG_INFO_FAILURE(fmt, ...) \ + _tprintf(_T("ReportFailure %hs: ") fmt, __FUNCTION__, __VA_ARGS__);_tprintf(_T("\n")); + +#define LOG_PASSED(fmt, ...) \ + _tprintf(_T("\n!!!PASSED: %hs (%hs:%u): ") fmt, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__);_tprintf(_T("\n")); +#define LOG_ERROR(fmt, ...) \ + _tprintf(_T("\n!!!FAILED: %hs (%hs:%u): ") fmt, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); _tprintf(_T("\n")); + +#else + +#define LOG_INFO(FormatString, ...) +#define LOG_INFO_FAILURE(FormatString, ...) + +#define LOG_PASSED(FormatString, ...) +#define LOG_ERROR(FormatString, ...) + +#endif + + +extern HANDLE TcDeviceHandle; + +BOOL TcInitialize(); +BOOL TcUnInitialize(); +BOOL TcCleanupSCM(); + +BOOL TcInstallDriver(); + +BOOL TcUninstallDriver(); + +BOOL TcRemoveProtection (); + +BOOL TcProcessName ( + _In_ int argc, + _In_reads_(argc) LPCWSTR argv[], + _In_ ULONG ulOperation +); + +BOOL TcUnprotectCallback (); + +BOOL TcProcessNameCallback ( + _In_reads_(NAME_SIZE+1) PCWSTR pnametoprotect, + _In_ ULONG ulOperation +); + +// +// Utility functions +// + +BOOL TcInitializeGlobals(); +BOOL TcLoadDriver(); +BOOL TcUnloadDriver(); + +BOOL TcCreateService(); +BOOL TcDeleteService(); +BOOL TcStartService(); +BOOL TcStopService(); + +BOOL TcOpenDevice(); +BOOL TcCloseDevice(); + diff --git a/general/obcallback/control/main.cpp b/general/obcallback/control/main.cpp new file mode 100644 index 00000000..e5a36224 --- /dev/null +++ b/general/obcallback/control/main.cpp @@ -0,0 +1,320 @@ +/*++ + +Module Name: + + main.cpp + +Abstract: + + Main module for for ps/Ob sample + +Notice: + + Use this sample code at your own risk; there is no support from Microsoft for the sample code. + In addition, this sample code is licensed to you under the terms of the Microsoft Public License + (http://www.microsoft.com/opensource/licenses.mspx) + + +--*/ + +#include "pch.h" +#include "common.h" + +// +// PrintUsage +// + +void TcPrintUsage() +{ + puts ("Usage:"); + puts (""); + puts(" ObCallbackTestCtrl.exe -install -name NameofExe -reject NameofExe -uninstall -deprotect [-?]"); + puts(" -install install driver"); + puts(" -uninstall uninstall driver"); + puts(" -name NameofExe protect/filter access to NameofExe"); + puts(" -reject NameofExe prevents execution of NameofExe"); + puts(" -deprotect unprotect/unfilter"); +} + +// +// wmain() +// + +int _cdecl +wmain ( + _In_ int argc, + _In_reads_(argc) LPCWSTR argv[] +) +{ + int ExitCode = ERROR_SUCCESS; + + if (argc > 1) + { + const wchar_t * arg = argv[1]; + + // initialize globals and logging + if (!TcInitialize()) { + puts("Initialization failed - program exiting"); + ExitCode = ERROR_FUNCTION_FAILED; + goto Exit; + } + + if (0 == wcscmp (arg, L"-install")) { + TcInstallDriver(); + } else + if (0 == wcscmp (arg, L"-uninstall")) { + TcUninstallDriver(); + } else + if ((0 == wcscmp (arg, L"-?")) || (0 == wcscmp (arg, L"-h")) || (0 == wcscmp (arg, L"-help"))) { + TcPrintUsage(); + } else + if (0 == wcscmp (arg, L"-deprotect")) { + TcRemoveProtection(); + } else + if (0 == wcscmp (arg, L"-name")) { + TcProcessName (argc, argv, TDProtectName_Protect); + } else + if (0 == wcscmp (arg, L"-reject")) { + TcProcessName (argc, argv, TDProtectName_Reject); + } else { + puts ("Unknown command!"); + TcPrintUsage(); + } + + } + else + { + TcPrintUsage(); + } + +Exit: + + if (!TcUnInitialize()) { + puts("UnInitialization failed"); + ExitCode = ERROR_FUNCTION_FAILED; + } + + return ExitCode; +} + + + +// +// TcRemoveProtection +// + +BOOL TcRemoveProtection () +{ + BOOL ReturnValue = FALSE; + + LOG_INFO(_T("TcRemoveProtection: Entering")); + + + // + // Open a handle to the device. + // + + ReturnValue = TcOpenDevice(); + if (ReturnValue != TRUE) + { + LOG_INFO_FAILURE (_T("TcOpenDevice failed")); + goto Exit; + } + + + // + // Send the command to the driver + // + ReturnValue = TcUnprotectCallback(); + if (ReturnValue != TRUE) + { + LOG_INFO_FAILURE (_T("TcUnprotectCallback failed")); + goto Exit; + } + +Exit: + + // + // Close our handle to the device. + // + + ReturnValue = TcCloseDevice(); + if (ReturnValue != TRUE) + { + LOG_INFO_FAILURE (_T("TcCloseDevice failed")); + } + + + LOG_INFO(_T("TcRemoveProtection: Exiting")); + + return ReturnValue; +} + + +// +// TcProcessName +// + +BOOL TcProcessName( + _In_ int argc, + _In_reads_(argc) LPCWSTR argv[], + _In_ ULONG ulOperation +) +{ + BOOL ReturnValue = FALSE; + + PCWSTR pwProcessName = NULL; + + LOG_INFO(L"TcProcessName: Entering"); + + + // + // Parse command line. + // + // argv[1] is "-name" so starting from arg #2 that should be the process name to protect + // + + if (argc < 3) { + LOG_INFO_FAILURE (L"TcProcessName: Too few parameters"); + LOG_INFO_FAILURE (L"TcProcessName: Usage -name nameofExe -reject nameofExe"); + ReturnValue = FALSE; + goto Exit; + } + + pwProcessName = argv[2]; + + if (!pwProcessName) { + LOG_INFO_FAILURE (L"TcProcessName: NULL process name to process"); + ReturnValue = FALSE; + goto Exit; + } + + + LOG_INFO(L"Ready to copy process name"); + LOG_INFO(L"Name to pass to driver %ls", pwProcessName); + + + // + // Open a handle to the device. + // + + ReturnValue = TcOpenDevice(); + if (ReturnValue != TRUE) + { + LOG_INFO_FAILURE (L"TcProcessName: TcOpenDevice failed"); + goto Exit; + } + + + // + // Send process name to protect and the command to the driver + // + ReturnValue = TcProcessNameCallback(pwProcessName, ulOperation); + if (ReturnValue != TRUE) + { + LOG_INFO_FAILURE (L"TcProcessName: TcProcessNameCallback failed"); + goto Exit; + } + +Exit: + + // + // Close our handle to the device. + // + + ReturnValue = TcCloseDevice(); + if (ReturnValue != TRUE) + { + LOG_INFO_FAILURE (L"TcProtectProcess: TcCloseDevice failed"); + } + + + LOG_INFO(L"TcProtectProcess: Exiting"); + + return ReturnValue; +} + + + +// +// TcInstallDriver - installs the kernel driver +// + +BOOL TcInstallDriver () +{ + BOOL bRC = TRUE; + + LOG_INFO(L"TcInstallDriver: Entering"); + BOOL Result = TcLoadDriver(); + + if (Result != TRUE) + { + LOG_ERROR (L"TcLoadDriver failed, exiting"); + bRC = FALSE; + goto Exit; + } + +Exit: + + LOG_INFO(L"TcInstallDriver: Exiting"); + return bRC; +} + + +// +// TcUninstallDriver - uninstalls the kernel driver +// + +BOOL TcUninstallDriver () +{ + BOOL bRC = TRUE; + + LOG_INFO(L"TcUninstallDriver: Entering"); + BOOL Result = TcUnloadDriver(); + + if (Result != TRUE) + { + LOG_ERROR (L"TcUnloadDriver failed, exiting"); + bRC = FALSE; + goto Exit; + } + +Exit: + + LOG_INFO(L"TcUninstallDriver: Exiting"); + return bRC; +} + + +// +// TcInitialize +// + +BOOL bLoggingInitialized = FALSE; + +BOOL TcInitialize () +{ + + BOOL Result = TcInitializeGlobals(); + if (Result != TRUE) + { + LOG_ERROR (L"TcInitializeGlobals failed, exiting"); + return FALSE; + } + + LOG_INFO(L"TcInitialize: Entering"); + return TRUE; + +} + +// +// TcUnInitialize +// + +BOOL TcUnInitialize() +{ + if (TcCleanupSCM() == FALSE){ + LOG_ERROR (L"TcUnInitialize failed cleanup of SCM"); + } + return TRUE; +} diff --git a/general/obcallback/control/pch.h b/general/obcallback/control/pch.h new file mode 100644 index 00000000..d165c04f --- /dev/null +++ b/general/obcallback/control/pch.h @@ -0,0 +1,18 @@ + +// Notice: +// +// Use this sample code at your own risk; there is no support from Microsoft for the sample code. +// In addition, this sample code is licensed to you under the terms of the Microsoft Public License +// (http://www.microsoft.com/opensource/licenses.mspx) + +#pragma once + +//#include <nt.h> +//#include <ntrtl.h> +//#include <nturtl.h> +#include <windows.h> +#include <stdlib.h> +#include <tchar.h> +#include <strsafe.h> +#include <winioctl.h> + diff --git a/general/obcallback/control/pchsrc.cpp b/general/obcallback/control/pchsrc.cpp new file mode 100644 index 00000000..17305716 --- /dev/null +++ b/general/obcallback/control/pchsrc.cpp @@ -0,0 +1 @@ +#include "pch.h"
\ No newline at end of file diff --git a/general/obcallback/control/readme.txt b/general/obcallback/control/readme.txt new file mode 100644 index 00000000..694696ad --- /dev/null +++ b/general/obcallback/control/readme.txt @@ -0,0 +1,57 @@ +The sample code exercises both PsSetCreateProcessNotifyRoutineEx() and ObRegisterCallbacks(). +These routines were introduced in Vista SP1 and are present in Windows7. They are available in both 32bit OS and 64bit OS. +The first example uses ObRegisterCallbacks() and a callback to restrict requested access rights during a open process action. +The second example uses PsSetCreateProcessNotifyRoutineEx() to reject a process creation by examining the command line. + +The code once compiled produces two files: ObCallbackTest.sys and ObCallbackTestCtrl.exe + +It is important to change the names of the binaries in the sample code to be unique for your own use. +#define TD_DRIVER_NAME L"ObCallbackTest" +#define TD_DRIVER_NAME_WITH_EXT L"ObCallbackTest.sys" + +#define TD_NT_DEVICE_NAME L"\\Device\\ObCallbackTest" +#define TD_DOS_DEVICES_LINK_NAME L"\\DosDevices\\ObCallbackTest" +#define TD_WIN32_DEVICE_NAME L"\\\\.\\ObCallbackTest" + + + + +For running the code you can use (run as administrator): + + C:\> obcallbacktest.exe -? (for command line help) + C:\> obcallbacktest.exe -install (installs the kernel driver) + C:\> obcallbacktest.exe -name notepad (specifies that the string �notepad� will be watched as a protected executable) + + (now you can start up �notepad.exe�) + C:\> notepad + + (locate the process ID of notepad.exe) + C:\> tlist + + (attempt to kill off the notepad.exe with a PID of 2329) + C:\> kill �f 2329 + process notepad.exe (2329) � �Untitled � Notepad� could not be killed + + (remove the protections on the notepad process) + C:\> obcallbacktest.exe -deprotect + + (attempt to kill off the process � which will succeed) + C:\> kill �f 2329 + + (uninstall the kernel driver) + C:\> obcallbacktest.exe -uninstall + +Another sample test you can run is to prevent a process from being created + + C:\> obcallbacktest.exe -install (installs the kernel driver) + C:\> obcallbacktest.exe -reject notepad (specifies that the string �notepad� will be watched and prevented from starting as a process) + + (now you can start up �notepad.exe�) + C:\> notepad + Access is denied. + + +Use this sample code at your own risk; there is no support from Microsoft for the sample code. In addition, this sample code is licensed to you under the terms of the Microsoft Public License (http://www.microsoft.com/opensource/licenses.mspx). + +May 2009 + diff --git a/general/obcallback/control/utils.cpp b/general/obcallback/control/utils.cpp new file mode 100644 index 00000000..3c1cb617 --- /dev/null +++ b/general/obcallback/control/utils.cpp @@ -0,0 +1,727 @@ +// +// Module: utils.cpp +// +// Helper functions for Ob sample code tests. +// +// Notice: +// +// Use this sample code at your own risk; there is no support from Microsoft for the sample code. +// In addition, this sample code is licensed to you under the terms of the Microsoft Public License +// (http://www.microsoft.com/opensource/licenses.mspx) +// +// + +#include "pch.h" +#include "common.h" + +// +// Globals +// + +SC_HANDLE TcScmHandle = NULL; +HANDLE TcDeviceHandle = INVALID_HANDLE_VALUE; + +WCHAR TcDriverPath[MAX_PATH]; + + +// +// TcUnprotectCallback +// +// Sends unprotect callback ioctl to the driver. +// + +BOOL TcUnprotectCallback () +{ + TD_UNPROTECT_CALLBACK_INPUT UnprotectCallbackInput = {0}; + + DWORD BytesReturned = 0; + + LOG_INFO (L"TcUnprotectCallback: entering"); + + BOOL Result = DeviceIoControl ( + TcDeviceHandle, + TD_IOCTL_UNPROTECT_CALLBACK, + &UnprotectCallbackInput, + sizeof(UnprotectCallbackInput), + NULL, + 0, + &BytesReturned, + NULL + ); + + if (Result == TRUE) + { + LOG_INFO (L"TcUnprotectCallback: succeeded"); + } + else + { + LOG_INFO_FAILURE (L"TcUnprotectCallback: DeviceIoControl failed, last error 0x%x", GetLastError()); + } + + + LOG_INFO (L"TcUnprotectCallback: exiting"); + return Result; +} + + +// +// TcUnprotectCallback +// +// Sends unprotect callback ioctl to the driver. +// + +BOOL TcProcessNameCallback ( + _In_reads_(NAME_SIZE+1) PCWSTR pnametoprotect, + _In_ ULONG ulOperation +) +{ + TD_PROTECTNAME_INPUT ProtectNameCallbackInput = {0}; + BOOL Result = FALSE; + DWORD BytesReturned = 0; + + LOG_INFO (L"TcProtectNameCallback: entering - nametoprotect %ls", pnametoprotect); + + // Copy the name of the exececutible to protect into IOCTL structure + if (!pnametoprotect) { + LOG_INFO_FAILURE (L"TcProcessNameCallback: NULL Protect Name"); + Result = FALSE; + goto Exit; + } + wcsncpy_s(ProtectNameCallbackInput.Name, pnametoprotect, NAME_SIZE); + ProtectNameCallbackInput.Operation = ulOperation; + + + LOG_INFO (L"TcProtectNameCallback: IOCTL sending nametoprotect %ls", ProtectNameCallbackInput.Name); + + Result = DeviceIoControl ( + TcDeviceHandle, + TD_IOCTL_PROTECT_NAME_CALLBACK, + &ProtectNameCallbackInput, + sizeof(ProtectNameCallbackInput), + NULL, + 0, + &BytesReturned, + NULL + ); + + if (Result == TRUE) + { + LOG_INFO (L"TcProcessNameCallback: succeeded"); + } + else + { + LOG_INFO_FAILURE (L"TcProcessNameCallback: DeviceIoControl failed, last error 0x%x", GetLastError()); + } + +Exit: + + LOG_INFO (L"TcProcessNameCallback: exiting"); + return Result; +} + + + +// +// TcInitializeGlobals +// + +BOOL TcInitializeGlobals() +{ + WCHAR SysDir[MAX_PATH]; + BOOL ReturnValue = FALSE; + +#if !defined (_WIN64) + + BOOL Result = FALSE; + BOOL Wow64Process = FALSE; + PVOID OldWowRedirectionValue = NULL; + + Result = IsWow64Process ( + GetCurrentProcess(), + &Wow64Process + ); + + if (Result == FALSE) + { + LOG_INFO_FAILURE (L"IsWow64Process failed, last error 0x%x", GetLastError()); + goto Exit; + } + + if (Wow64Process == TRUE) + { + // + // Disable FS redirection to make sure a 32 bit test process will + // copy our (64 bit) driver to system32\drivers rather than syswow64\drivers. + // + + Result = Wow64DisableWow64FsRedirection (&OldWowRedirectionValue); + + if (Result == FALSE) + { + LOG_INFO_FAILURE (L"Wow64DisableWow64FsRedirection failed, last error 0x%x", GetLastError()); + goto Exit; + } + } + +#endif + + // + // Open the service control manager if not already open + // + + if (TcScmHandle == NULL) { + TcScmHandle = OpenSCManager ( + NULL, + NULL, + SC_MANAGER_ALL_ACCESS + ); + + if (TcScmHandle == NULL) + { + LOG_INFO_FAILURE (L"OpenSCManager failed, last error 0x%x", GetLastError()); + goto Exit; + } + } + // + // Construct driver path. + // + + UINT Size = GetSystemDirectory (SysDir, ARRAYSIZE(SysDir)); + + if (Size == 0) + { + LOG_INFO_FAILURE (L"GetSystemDirectory failed, last error 0x%x", GetLastError()); + goto Exit; + } + + HRESULT hr = StringCchPrintf ( + TcDriverPath, + ARRAYSIZE(TcDriverPath), + L"%ls\\drivers\\%ls.sys", + SysDir, + TD_DRIVER_NAME + ); + + if (FAILED (hr)) + { + LOG_INFO_FAILURE (L"StringCchPrintf failed, hr 0x%08x", hr); + goto Exit; + } + + ReturnValue = TRUE; + +Exit: + return ReturnValue; +} + + +// +// TcUnInitialize +// + +BOOL TcCleanupSCM() +{ + if (TcScmHandle != NULL) { + CloseServiceHandle(TcScmHandle); + TcScmHandle = NULL; + } + + return TRUE; +} + +// +// TcLoadDriver +// + +BOOL TcLoadDriver() +{ + BOOL ReturnValue = FALSE; + + LOG_INFO(L"TcLoadDriver: Entering"); + + // + // First, uninstall and unload the driver. + // + + ReturnValue = TcUnloadDriver(); + + if (ReturnValue != TRUE) + { + LOG_INFO_FAILURE (L"TcUnloadDriver failed"); + goto Exit; + } + + // + // Copy the driver to system32\drivers + // + + ReturnValue = CopyFile (TD_DRIVER_NAME_WITH_EXT, TcDriverPath, FALSE); + + if (ReturnValue == FALSE) + { + LOG_INFO_FAILURE ( + L"CopyFile(%ls, %ls) failed, last error 0x%x", + TD_DRIVER_NAME_WITH_EXT, TcDriverPath, GetLastError() + ); + + goto Exit; + } + + // + // Install the driver. + // + + ReturnValue = TcCreateService(); + + if (ReturnValue == FALSE) + { + LOG_INFO_FAILURE (L"TcCreateService failed"); + goto Exit; + } + + // + // Load the driver. + // + + ReturnValue = TcStartService(); + + if (ReturnValue == FALSE) + { + LOG_INFO_FAILURE (L"TcStartService failed"); + goto Exit; + } + + + ReturnValue = TRUE; + +Exit: + + LOG_INFO(L"TcLoadDriver: Exiting"); + return ReturnValue; +} + + + +// +// TcUnloadDriver +// + +BOOL TcUnloadDriver() +{ + BOOL ReturnValue = FALSE; + + LOG_INFO(L"TcUnloadDriver: Entering"); + + + // + // Unload the driver. + // + + ReturnValue = TcStopService(); + + if (ReturnValue == FALSE) + { + LOG_INFO_FAILURE (L"TcStopService failed"); + goto Exit; + } + + // + // Delete the service. + // + + ReturnValue = TcDeleteService(); + + if (ReturnValue == FALSE) + { + LOG_INFO_FAILURE (L"TcDeleteService failed"); + goto Exit; + } + + ReturnValue = TRUE; + +Exit: + + LOG_INFO(L"TcUnloadDriver: Exiting"); + + return ReturnValue; +} + +// +// TcGetServiceState +// + +BOOL TcGetServiceState ( + _In_ SC_HANDLE ServiceHandle, + _Out_ DWORD* State +) +{ + SERVICE_STATUS_PROCESS ServiceStatus; + DWORD BytesNeeded; + + *State = 0; + + BOOL Result = QueryServiceStatusEx ( + ServiceHandle, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(ServiceStatus), + &BytesNeeded + ); + + if (Result == FALSE) + { + LOG_INFO_FAILURE (L"TcGetServiceState: QueryServiceStatusEx failed, last error 0x%x", GetLastError()); + return FALSE; + } + + *State = ServiceStatus.dwCurrentState; + + return TRUE; +} + +// +// Wait for service to enter specified state. +// + +BOOL TcWaitForServiceState ( + _In_ SC_HANDLE ServiceHandle, + _In_ DWORD State +) +{ + for (;;) + { + LOG_INFO (L"TcWaitForServiceState: Waiting for service %p to enter state %u...", (DWORD_PTR)ServiceHandle, State); + + DWORD ServiceState; + BOOL Result = TcGetServiceState (ServiceHandle, &ServiceState); + + if (Result == FALSE) + { + return FALSE; + } + + if (ServiceState == State) + { + break; + } + + Sleep (1000); + } + + return TRUE; +} + +// +// TcCreateService +// + +BOOL TcCreateService() +{ + BOOL ReturnValue = FALSE; + + LOG_INFO(L"TcCreateService: Entering"); + + // + // Create the service + // + + SC_HANDLE ServiceHandle = CreateService ( + TcScmHandle, // handle to SC manager + TD_DRIVER_NAME, // name of service + TD_DRIVER_NAME, // display name + SERVICE_ALL_ACCESS, // access mask + SERVICE_KERNEL_DRIVER, // service type + SERVICE_DEMAND_START, // start type + SERVICE_ERROR_NORMAL, // error control + TcDriverPath, // full path to driver + NULL, // load ordering + NULL, // tag id + NULL, // dependency + NULL, // account name + NULL // password + ); + + DWORD LastError = GetLastError(); + + if (ServiceHandle == NULL && LastError != ERROR_SERVICE_EXISTS) + { + LOG_INFO_FAILURE (L"CreateService failed, last error 0x%x", LastError); + goto Exit; + } + + ReturnValue = TRUE; + +Exit: + + if (ServiceHandle) + { + CloseServiceHandle (ServiceHandle); + } + + LOG_INFO(L"TcCreateService: Exiting"); + + return ReturnValue; +} + +// +// TcStartService +// + +BOOL TcStartService() +{ + BOOL ReturnValue = FALSE; + + // + // Open the service. The function assumes that + // TdCreateService has been called before this one + // and the service is already installed. + // + + SC_HANDLE ServiceHandle = OpenService ( + TcScmHandle, + TD_DRIVER_NAME, + SERVICE_ALL_ACCESS + ); + + if (ServiceHandle == NULL) + { + LOG_INFO_FAILURE (L"TcStartService: OpenService failed, last error 0x%x", GetLastError()); + goto Exit; + } + + // + // Start the service + // + + if (! StartService (ServiceHandle, 0, NULL)) + { + if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) + { + LOG_INFO_FAILURE (L"TcStartService: StartService failed, last error 0x%x", GetLastError()); + goto Exit; + } + } + + if (FALSE == TcWaitForServiceState (ServiceHandle, SERVICE_RUNNING)) + { + goto Exit; + } + + ReturnValue = TRUE; + +Exit: + + if (ServiceHandle) + { + CloseServiceHandle (ServiceHandle); + } + + return ReturnValue; +} + + +// +// TcStopService +// + +BOOL TcStopService() +{ + BOOL ReturnValue = FALSE; + + LOG_INFO(L"TcStopService: Entering"); + + // + // Open the service so we can stop it + // + + SC_HANDLE ServiceHandle = OpenService ( + TcScmHandle, + TD_DRIVER_NAME, + SERVICE_ALL_ACCESS + ); + + DWORD LastError = GetLastError(); + + if (ServiceHandle == NULL) + { + if (LastError == ERROR_SERVICE_DOES_NOT_EXIST) + { + ReturnValue = TRUE; + } + else + { + LOG_INFO_FAILURE (L"TcStopService: OpenService failed, last error 0x%x", LastError); + } + + goto Exit; + } + + // + // Stop the service + // + + SERVICE_STATUS ServiceStatus; + + if (FALSE == ControlService (ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus)) + { + LastError = GetLastError(); + + if (LastError != ERROR_SERVICE_NOT_ACTIVE) + { + LOG_INFO_FAILURE (L"TcStopService: ControlService failed, last error 0x%x", LastError); + goto Exit; + } + } + + if (FALSE == TcWaitForServiceState (ServiceHandle, SERVICE_STOPPED)) + { + goto Exit; + } + + ReturnValue = TRUE; + +Exit: + + if (ServiceHandle) + { + CloseServiceHandle (ServiceHandle); + } + + LOG_INFO(L"TcStopService: Exiting"); + + return ReturnValue; +} + +// +// TcDeleteService +// + +BOOL TcDeleteService() +{ + BOOL ReturnValue = FALSE; + + + LOG_INFO(L"TcDeleteService: Entering"); + + // + // Open the service so we can delete it + // + + SC_HANDLE ServiceHandle = OpenService ( + TcScmHandle, + TD_DRIVER_NAME, + SERVICE_ALL_ACCESS + ); + + DWORD LastError = GetLastError(); + + if (ServiceHandle == NULL) + { + if (LastError == ERROR_SERVICE_DOES_NOT_EXIST) + { + ReturnValue = TRUE; + } + else + { + LOG_INFO_FAILURE (L"TcDeleteService: OpenService failed, last error 0x%x", LastError); + } + + goto Exit; + } + + // + // Delete the service + // + + if (! DeleteService (ServiceHandle)) + { + LastError = GetLastError(); + + if (LastError != ERROR_SERVICE_MARKED_FOR_DELETE) + { + LOG_INFO_FAILURE (L"TcDeleteService: DeleteService failed, last error 0x%x", LastError); + goto Exit; + } + } + + ReturnValue = TRUE; + +Exit: + + if (ServiceHandle) + { + CloseServiceHandle (ServiceHandle); + } + + LOG_INFO(L"TcDeleteService: Exiting"); + + return ReturnValue; +} + +// +// TcOpenDevice +// + +BOOL TcOpenDevice() +{ + BOOL ReturnValue = FALSE; + + LOG_INFO(L"TcOpenDevice: Entering"); + + + // + // Open the device if not already opened + // + if (TcDeviceHandle == INVALID_HANDLE_VALUE) { + TcDeviceHandle = CreateFile ( + TD_WIN32_DEVICE_NAME, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + + if (TcDeviceHandle == INVALID_HANDLE_VALUE) + { + LOG_INFO_FAILURE (L"TcOpenDevice: CreateFile(%ls) failed, last error 0x%x", TD_WIN32_DEVICE_NAME, GetLastError()); + goto Exit; + } + } + + + ReturnValue = TRUE; + +Exit: + + LOG_INFO(L"TcOpenDevice: Exiting"); + return ReturnValue; +} + +// +// TcOpenDevice +// + +BOOL TcCloseDevice() +{ + BOOL ReturnValue = FALSE; + + LOG_INFO(L"TcCloseDevice: Entering"); + + // + // Close our handle to the device. + // + + if (TcDeviceHandle != INVALID_HANDLE_VALUE) + { + CloseHandle (TcDeviceHandle); + TcDeviceHandle = INVALID_HANDLE_VALUE; + } + + ReturnValue = TRUE; + + LOG_INFO(L"TcCloseDevice: Exiting"); + return ReturnValue; +} + diff --git a/general/obcallback/driver/ObCallbackTest.vcxproj b/general/obcallback/driver/ObCallbackTest.vcxproj new file mode 100644 index 00000000..e781eb3a --- /dev/null +++ b/general/obcallback/driver/ObCallbackTest.vcxproj @@ -0,0 +1,210 @@ +<?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|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</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>{C696D115-0970-4E9C-8FED-31A99E039ED5}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{F7152E7D-34B2-4B88-A5D9-17D68B786DFC}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</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>Desktop</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</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)'=='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)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <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>ObCallbackTest</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>ObCallbackTest</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>ObCallbackTest</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>ObCallbackTest</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalOptions>%(AdditionalOptions) /INTEGRITYCHECK</AdditionalOptions> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalOptions>%(AdditionalOptions) /INTEGRITYCHECK</AdditionalOptions> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalOptions>%(AdditionalOptions) /INTEGRITYCHECK</AdditionalOptions> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalOptions>%(AdditionalOptions) /INTEGRITYCHECK</AdditionalOptions> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="callback.c"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>pch.h</PreCompiledHeaderFile> + <PreCompiledHeader>Use</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\pch.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + <ClCompile Include="pchsrc.c"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>pch.h</PreCompiledHeaderFile> + <PreCompiledHeader>Create</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\pch.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + <ClCompile Include="tdriver.c"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>pch.h</PreCompiledHeaderFile> + <PreCompiledHeader>Use</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\pch.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + <ClCompile Include="util.c"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>pch.h</PreCompiledHeaderFile> + <PreCompiledHeader>Use</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\pch.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" /> + </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/general/obcallback/driver/ObCallbackTest.vcxproj.Filters b/general/obcallback/driver/ObCallbackTest.vcxproj.Filters new file mode 100644 index 00000000..6fb49bed --- /dev/null +++ b/general/obcallback/driver/ObCallbackTest.vcxproj.Filters @@ -0,0 +1,35 @@ +<?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>{5962AF0C-70AA-4F9A-870A-9CA844475924}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{B9BBA35B-98FC-4830-9A01-41A3227755C9}</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>{75DE6DD6-44CF-4D1B-BC2C-1EF556200FC9}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{593EF94F-8BBC-4C56-999C-5D894DD5456F}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="callback.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pchsrc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="tdriver.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="util.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/general/obcallback/driver/callback.c b/general/obcallback/driver/callback.c new file mode 100644 index 00000000..39ecd1b4 --- /dev/null +++ b/general/obcallback/driver/callback.c @@ -0,0 +1,479 @@ + +// Callback functions for Ob sample code tests. +// +// Notice: +// +// Use this sample code at your own risk; there is no support from Microsoft for the sample code. +// In addition, this sample code is licensed to you under the terms of the Microsoft Public License +// (http://www.microsoft.com/opensource/licenses.mspx) +// +// + + +#include "pch.h" +#include "tdriver.h" + +// +// Globals +// + +KGUARDED_MUTEX TdCallbacksMutex; +BOOLEAN bCallbacksInstalled = FALSE; + + +#define CB_PROCESS_TERMINATE 0x0001 +#define CB_THREAD_TERMINATE 0x0001 + +// The following are for setting up callbacks for Process and Thread filtering +PVOID pCBRegistrationHandle = NULL; + +OB_CALLBACK_REGISTRATION CBObRegistration = { 0 }; +OB_OPERATION_REGISTRATION CBOperationRegistrations[2] = { { 0 }, { 0 } }; +UNICODE_STRING CBAltitude = {0}; +TD_CALLBACK_REGISTRATION CBCallbackRegistration = {0}; + +// Here is the protected process +WCHAR TdwProtectName[NAME_SIZE+1] = {0}; +PVOID TdProtectedTargetProcess = NULL; +HANDLE TdProtectedTargetProcessId = {0}; + + +// +// TdDeleteProtectNameCallback +// +NTSTATUS TdDeleteProtectNameCallback () +{ + NTSTATUS Status = STATUS_SUCCESS; + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdDeleteProtectNameCallback entering\n"); + + KeAcquireGuardedMutex (&TdCallbacksMutex); + + // if the callbacks are active - remove them + if (bCallbacksInstalled == TRUE) { + ObUnRegisterCallbacks(pCBRegistrationHandle); + pCBRegistrationHandle = NULL; + bCallbacksInstalled = FALSE; + } + + + KeReleaseGuardedMutex (&TdCallbacksMutex); + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdDeleteProtectNameCallback exiting - status 0x%x\n", Status + ); + + return Status; +} + + +// +// TdProtectNameCallback +// + +NTSTATUS TdProtectNameCallback ( + _In_ PTD_PROTECTNAME_INPUT pProtectName +) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (!pProtectName) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, + "ObCallbackTest: TdProtectNameCallback: name to protect/filter NULL pointer\n" + ); + } + else { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdProtectNameCallback: entering name to protect/filter %ls\n", pProtectName->Name + ); + } + KeAcquireGuardedMutex (&TdCallbacksMutex); + + // Need to copy out the name and then set the flag to filter + // This will allow process creation to watch for the process to be created and get the PID + // and then prevent any other process from opening up that PID to terminate + + memcpy(TdwProtectName, pProtectName->Name, sizeof(TdwProtectName)); + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: name copied %ls\n", TdwProtectName + ); + + // Need to enable the OB callbacks + // once the process is matched to a newly created process, the callbacks will protect the process + if (bCallbacksInstalled == FALSE) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdProtectNameCallback: installing callbacks\n" + ); + + // Setup the Ob Registration calls + + CBOperationRegistrations[0].ObjectType = PsProcessType; + CBOperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_CREATE; + CBOperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_DUPLICATE; + CBOperationRegistrations[0].PreOperation = CBTdPreOperationCallback; + CBOperationRegistrations[0].PostOperation = CBTdPostOperationCallback; + + CBOperationRegistrations[1].ObjectType = PsThreadType; + CBOperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_CREATE; + CBOperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_DUPLICATE; + CBOperationRegistrations[1].PreOperation = CBTdPreOperationCallback; + CBOperationRegistrations[1].PostOperation = CBTdPostOperationCallback; + + + RtlInitUnicodeString (&CBAltitude, L"1000"); + + CBObRegistration.Version = OB_FLT_REGISTRATION_VERSION; + CBObRegistration.OperationRegistrationCount = 2; + CBObRegistration.Altitude = CBAltitude; + CBObRegistration.RegistrationContext = &CBCallbackRegistration; + CBObRegistration.OperationRegistration = CBOperationRegistrations; + + + Status = ObRegisterCallbacks ( + &CBObRegistration, + &pCBRegistrationHandle // save the registration handle to remove callbacks later + ); + + if (!NT_SUCCESS (Status)) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, + "ObCallbackTest: installing OB callbacks failed status 0x%x\n", Status + ); + KeReleaseGuardedMutex (&TdCallbacksMutex); // Release the lock before exit + goto Exit; + } + bCallbacksInstalled = TRUE; + + } + + + KeReleaseGuardedMutex (&TdCallbacksMutex); + + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdProtectNameCallback: name to protect/filter %ls\n", TdwProtectName + ); + +Exit: + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdProtectNameCallback: exiting status 0x%x\n", Status + ); + return Status; +} + + +// +// TdCheckProcessMatch - function to test a command line to see if the process is to be protected +// +NTSTATUS TdCheckProcessMatch ( + _In_ PCUNICODE_STRING pustrCommand, + _In_ PEPROCESS Process, + _In_ HANDLE ProcessId +) +{ + NTSTATUS Status = STATUS_UNSUCCESSFUL; + WCHAR CommandLineBuffer[NAME_SIZE + 1] = {0}; // force a NULL termination + USHORT CommandLineBytes = 0; + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdCheckProcessMatch: entering\n"); + + if (!pustrCommand || !pustrCommand->Buffer) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, + "ObCallbackTest: TdCheckProcessMatch: no Command line provided\n" + ); + Status = FALSE; + goto Exit; + } + else { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdCheckProcessMatch: checking for %ls\n", TdwProtectName + ); + } + + KeAcquireGuardedMutex (&TdCallbacksMutex); + + + // Make sure that the CommandLineBuffer is NULL terminated + if (pustrCommand->Length < (NAME_SIZE * sizeof(WCHAR))) + CommandLineBytes = pustrCommand->Length; + else + CommandLineBytes = NAME_SIZE * sizeof(WCHAR); + + if (CommandLineBytes) { + memcpy(CommandLineBuffer, pustrCommand->Buffer, CommandLineBytes); + + // now check if the process to protect is in the command line + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdCheckProcessMatch: command line %ls\n", CommandLineBuffer + ); + + if (NULL != wcsstr (CommandLineBuffer, TdwProtectName)) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdCheckProcessMatch: match FOUND\n" + ); + + // Set the process to watch + TdProtectedTargetProcess = Process; + TdProtectedTargetProcessId = ProcessId; + + Status = STATUS_SUCCESS; + } + } + else { + Status = FALSE; // no command line buffer provided + } + + KeReleaseGuardedMutex (&TdCallbacksMutex); + + +Exit: + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdCheckProcessMatch: leaving status 0x%x\n", Status + ); + return Status; +} + + +// +// CBTdPreOperationCallback +// +OB_PREOP_CALLBACK_STATUS +CBTdPreOperationCallback ( + _In_ PVOID RegistrationContext, + _Inout_ POB_PRE_OPERATION_INFORMATION PreInfo +) +{ + PTD_CALLBACK_REGISTRATION CallbackRegistration; + + ACCESS_MASK AccessBitsToClear = 0; + ACCESS_MASK AccessBitsToSet = 0; + ACCESS_MASK InitialDesiredAccess = 0; + ACCESS_MASK OriginalDesiredAccess = 0; + + + PACCESS_MASK DesiredAccess = NULL; + + LPCWSTR ObjectTypeName = NULL; + LPCWSTR OperationName = NULL; + + // Not using driver specific values at this time + CallbackRegistration = (PTD_CALLBACK_REGISTRATION)RegistrationContext; + + + TD_ASSERT (PreInfo->CallContext == NULL); + + // Only want to filter attempts to access protected process + // all other processes are left untouched + + if (PreInfo->ObjectType == *PsProcessType) { + // + // Ignore requests for processes other than our target process. + // + + // if (TdProtectedTargetProcess != NULL && + // TdProtectedTargetProcess != PreInfo->Object) + if (TdProtectedTargetProcess != PreInfo->Object) + { + goto Exit; + } + + // + // Also ignore requests that are trying to open/duplicate the current + // process. + // + + if (PreInfo->Object == PsGetCurrentProcess()) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: CBTdPreOperationCallback: ignore process open/duplicate from the protected process itself\n"); + goto Exit; + } + + ObjectTypeName = L"PsProcessType"; + AccessBitsToClear = CB_PROCESS_TERMINATE; + AccessBitsToSet = 0; + } + else if (PreInfo->ObjectType == *PsThreadType) { + HANDLE ProcessIdOfTargetThread = PsGetThreadProcessId ((PETHREAD)PreInfo->Object); + + // + // Ignore requests for threads belonging to processes other than our + // target process. + // + + // if (CallbackRegistration->TargetProcess != NULL && + // CallbackRegistration->TargetProcessId != ProcessIdOfTargetThread) + if (TdProtectedTargetProcessId != ProcessIdOfTargetThread) { + goto Exit; + } + + // + // Also ignore requests for threads belonging to the current processes. + // + + if (ProcessIdOfTargetThread == PsGetCurrentProcessId()) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: CBTdPreOperationCallback: ignore thread open/duplicate from the protected process itself\n"); + goto Exit; + } + + ObjectTypeName = L"PsThreadType"; + AccessBitsToClear = CB_THREAD_TERMINATE; + AccessBitsToSet = 0; + } + else { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, + "ObCallbackTest: CBTdPreOperationCallback: unexpected object type\n"); + goto Exit; + } + + switch (PreInfo->Operation) { + case OB_OPERATION_HANDLE_CREATE: + DesiredAccess = &PreInfo->Parameters->CreateHandleInformation.DesiredAccess; + OriginalDesiredAccess = PreInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess; + + OperationName = L"OB_OPERATION_HANDLE_CREATE"; + break; + + case OB_OPERATION_HANDLE_DUPLICATE: + DesiredAccess = &PreInfo->Parameters->DuplicateHandleInformation.DesiredAccess; + OriginalDesiredAccess = PreInfo->Parameters->DuplicateHandleInformation.OriginalDesiredAccess; + + OperationName = L"OB_OPERATION_HANDLE_DUPLICATE"; + break; + + default: + TD_ASSERT (FALSE); + break; + } + + InitialDesiredAccess = *DesiredAccess; + + // Filter only if request made outside of the kernel + if (PreInfo->KernelHandle != 1) { + *DesiredAccess &= ~AccessBitsToClear; + *DesiredAccess |= AccessBitsToSet; + } + + // + // Set call context. + // + + TdSetCallContext (PreInfo, CallbackRegistration); + + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "ObCallbackTest: CBTdPreOperationCallback: PROTECTED process %p (ID 0x%p)\n", + TdProtectedTargetProcess, + (PVOID)TdProtectedTargetProcessId + ); + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: CBTdPreOperationCallback\n" + " Client Id: %p:%p\n" + " Object: %p\n" + " Type: %ls\n" + " Operation: %ls (KernelHandle=%d)\n" + " OriginalDesiredAccess: 0x%x\n" + " DesiredAccess (in): 0x%x\n" + " DesiredAccess (out): 0x%x\n", + PsGetCurrentProcessId(), + PsGetCurrentThreadId(), + PreInfo->Object, + ObjectTypeName, + OperationName, + PreInfo->KernelHandle, + OriginalDesiredAccess, + InitialDesiredAccess, + *DesiredAccess + ); + +Exit: + + return OB_PREOP_SUCCESS; +} + +// +// TdPostOperationCallback +// + +VOID +CBTdPostOperationCallback ( + _In_ PVOID RegistrationContext, + _In_ POB_POST_OPERATION_INFORMATION PostInfo + ) +{ + PTD_CALLBACK_REGISTRATION CallbackRegistration = (PTD_CALLBACK_REGISTRATION)RegistrationContext; + + TdCheckAndFreeCallContext (PostInfo, CallbackRegistration); + + if (PostInfo->ObjectType == *PsProcessType) { + // + // Ignore requests for processes other than our target process. + // + + if (CallbackRegistration->TargetProcess != NULL && + CallbackRegistration->TargetProcess != PostInfo->Object + ) { + return; + } + + // + // Also ignore requests that are trying to open/duplicate the current + // process. + // + + if (PostInfo->Object == PsGetCurrentProcess()) { + return; + } + } + else if (PostInfo->ObjectType == *PsThreadType) { + HANDLE ProcessIdOfTargetThread = PsGetThreadProcessId ((PETHREAD)PostInfo->Object); + + // + // Ignore requests for threads belonging to processes other than our + // target process. + // + + if (CallbackRegistration->TargetProcess != NULL && + CallbackRegistration->TargetProcessId != ProcessIdOfTargetThread + ) { + return; + } + + // + // Also ignore requests for threads belonging to the current processes. + // + + if (ProcessIdOfTargetThread == PsGetCurrentProcessId()) { + return; + } + } + else { + TD_ASSERT (FALSE); + } + +} + diff --git a/general/obcallback/driver/pch.h b/general/obcallback/driver/pch.h new file mode 100644 index 00000000..9cab74cc --- /dev/null +++ b/general/obcallback/driver/pch.h @@ -0,0 +1,13 @@ + +// Notice: +// +// Use this sample code at your own risk; there is no support from Microsoft for the sample code. +// In addition, this sample code is licensed to you under the terms of the Microsoft Public License +// (http://www.microsoft.com/opensource/licenses.mspx) + +#pragma once + +#include <ntddk.h> +#include <ntstrsafe.h> + + diff --git a/general/obcallback/driver/pchsrc.c b/general/obcallback/driver/pchsrc.c new file mode 100644 index 00000000..17305716 --- /dev/null +++ b/general/obcallback/driver/pchsrc.c @@ -0,0 +1 @@ +#include "pch.h"
\ No newline at end of file diff --git a/general/obcallback/driver/shared.h b/general/obcallback/driver/shared.h new file mode 100644 index 00000000..cea7f5f9 --- /dev/null +++ b/general/obcallback/driver/shared.h @@ -0,0 +1,95 @@ +/*++ + +Module Name: + + shared.h + +Abstract: + + This contains declarations shared by the Ob/Ps callback test driver and + the user mode test app. + + +// Notice: +// +// Use this sample code at your own risk; there is no support from Microsoft for the sample code. +// In addition, this sample code is licensed to you under the terms of the Microsoft Public License +// (http://www.microsoft.com/opensource/licenses.mspx) + +--*/ + +#pragma once + +#pragma warning(disable:4214) // bit field types other than int +#pragma warning(disable:4201) // nameless struct/union + +// +// TD_ASSERT +// +// This macro is identical to NT_ASSERT but works in fre builds as well. +// +// It is used for error checking in the driver in cases where +// we can't easily report the error to the user mode app, or the +// error is so severe that we should break in immediately to +// investigate. +// +// It's better than DbgBreakPoint because it provides additional info +// that can be dumped with .exr -1, and individual asserts can be disabled +// from kd using 'ahi' command. +// + +#define TD_ASSERT(_exp) \ + ((!(_exp)) ? \ + (__annotation(L"Debug", L"AssertFail", L#_exp), \ + DbgRaiseAssertionFailure(), FALSE) : \ + TRUE) + +// +// Driver and device names +// It is important to change the names of the binaries +// in the sample code to be unique for your own use. +// + +#define TD_DRIVER_NAME L"ObCallbackTest" +#define TD_DRIVER_NAME_WITH_EXT L"ObCallbackTest.sys" + +#define TD_NT_DEVICE_NAME L"\\Device\\ObCallbackTest" +#define TD_DOS_DEVICES_LINK_NAME L"\\DosDevices\\ObCallbackTest" +#define TD_WIN32_DEVICE_NAME L"\\\\.\\ObCallbackTest" + + +#define NAME_SIZE 200 + +#define TD_INVALID_CALLBACK_ID ((ULONG)-1) + +// +// IOCTLs exposed by the driver. +// + +// #define TD_IOCTL_REGISTER_CALLBACK CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 0), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +// #define TD_IOCTL_UNREGISTER_CALLBACK CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 1), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define TD_IOCTL_PROTECT_NAME_CALLBACK CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 2), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define TD_IOCTL_UNPROTECT_CALLBACK CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 3), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) + + +#define TDProtectName_Protect 0 // name of programs to proect and filter out the desiredAccess on Process Open +#define TDProtectName_Reject 1 // name of programs to reject during ProcessCreate + +// +// Structures used by TD_IOCTL_PROTECTNAME +// + +typedef struct _TD_PROTECTNAME_INPUT { + ULONG Operation; + WCHAR Name[NAME_SIZE+1]; // what is the filename to protect - extra wchar for forced NULL +} +TD_PROTECTNAME_INPUT, *PTD_PROTECTNAME_INPUT; + +// +// Structures used by TD_IOCTL_UNPROTECT_CALLBACK +// + +typedef struct _TD_UNPROTECT_CALLBACK_INPUT { + ULONG UnusedParameter; +} +TD_UNPROTECT_CALLBACK_INPUT, *PTD_UNPROTECT_CALLBACK_INPUT; diff --git a/general/obcallback/driver/tdriver.c b/general/obcallback/driver/tdriver.c new file mode 100644 index 00000000..641635ee --- /dev/null +++ b/general/obcallback/driver/tdriver.c @@ -0,0 +1,532 @@ +/*++ + +Module Name: + + tdriver.c + +Abstract: + + Main module for the Ob and Ps sample code + +Notice: + Use this sample code at your own risk; there is no support from Microsoft for the sample code. + In addition, this sample code is licensed to you under the terms of the Microsoft Public License + (http://www.microsoft.com/opensource/licenses.mspx) + + +--*/ + +#include "pch.h" +#include "tdriver.h" + +// +// Process notify routines. +// + +BOOLEAN TdProcessNotifyRoutineSet2 = FALSE; + +// allow filter the requested access +BOOLEAN TdbProtectName = FALSE; +BOOLEAN TdbRejectName = FALSE; + +// +// Function declarations +// +DRIVER_INITIALIZE DriverEntry; + +_Dispatch_type_(IRP_MJ_CREATE) DRIVER_DISPATCH TdDeviceCreate; +_Dispatch_type_(IRP_MJ_CLOSE) DRIVER_DISPATCH TdDeviceClose; +_Dispatch_type_(IRP_MJ_CLEANUP) DRIVER_DISPATCH TdDeviceCleanup; +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) DRIVER_DISPATCH TdDeviceControl; + +DRIVER_UNLOAD TdDeviceUnload; + +VOID +TdCreateProcessNotifyRoutine2 ( + _Inout_ PEPROCESS Process, + _In_ HANDLE ProcessId, + _In_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo + ) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (CreateInfo != NULL) + { + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdCreateProcessNotifyRoutine2: process %p (ID 0x%p) created, creator %Ix:%Ix\n" + " command line %wZ\n" + " file name %wZ (FileOpenNameAvailable: %d)\n", + Process, + (PVOID)ProcessId, + (ULONG_PTR)CreateInfo->CreatingThreadId.UniqueProcess, + (ULONG_PTR)CreateInfo->CreatingThreadId.UniqueThread, + CreateInfo->CommandLine, + CreateInfo->ImageFileName, + CreateInfo->FileOpenNameAvailable + ); + + // Search for matching process to protect only if filtering + if (TdbProtectName) { + if (CreateInfo->CommandLine != NULL) + { + Status = TdCheckProcessMatch(CreateInfo->CommandLine, Process, ProcessId); + + if (Status == STATUS_SUCCESS) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "ObCallbackTest: TdCreateProcessNotifyRoutine2: PROTECTING process %p (ID 0x%p)\n", + Process, + (PVOID)ProcessId + ); + } + } + + } + + // Search for matching process to reject process creation + if (TdbRejectName) { + if (CreateInfo->CommandLine != NULL) + { + Status = TdCheckProcessMatch(CreateInfo->CommandLine, Process, ProcessId); + + if (Status == STATUS_SUCCESS) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "ObCallbackTest: TdCreateProcessNotifyRoutine2: REJECTING process %p (ID 0x%p)\n", + Process, + (PVOID)ProcessId + ); + + CreateInfo->CreationStatus = STATUS_ACCESS_DENIED; + } + } + + } + } + else + { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "ObCallbackTest: TdCreateProcessNotifyRoutine2: process %p (ID 0x%p) destroyed\n", + Process, + (PVOID)ProcessId + ); + } +} + +// +// DriverEntry +// + +NTSTATUS +DriverEntry ( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath +) +{ + NTSTATUS Status; + UNICODE_STRING NtDeviceName = RTL_CONSTANT_STRING (TD_NT_DEVICE_NAME); + UNICODE_STRING DosDevicesLinkName = RTL_CONSTANT_STRING (TD_DOS_DEVICES_LINK_NAME); + PDEVICE_OBJECT Device = NULL; + BOOLEAN SymLinkCreated = FALSE; + USHORT CallbackVersion; + + UNREFERENCED_PARAMETER (RegistryPath); + + DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "ObCallbackTest: DriverEntry: Driver loaded. Use ed nt!Kd_IHVDRIVER_Mask f (or 7) to enable more traces\n"); + + CallbackVersion = ObGetFilterVersion(); + + DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ObCallbackTest: DriverEntry: Callback version 0x%hx\n", CallbackVersion); + + // + // Initialize globals. + // + + KeInitializeGuardedMutex (&TdCallbacksMutex); + + // + // Create our device object. + // + + Status = IoCreateDevice ( + DriverObject, // pointer to driver object + 0, // device extension size + &NtDeviceName, // device name + FILE_DEVICE_UNKNOWN, // device type + 0, // device characteristics + FALSE, // not exclusive + &Device); // returned device object pointer + + if (! NT_SUCCESS(Status)) + { + goto Exit; + } + + TD_ASSERT (Device == DriverObject->DeviceObject); + + // + // Set dispatch routines. + // + + DriverObject->MajorFunction[IRP_MJ_CREATE] = TdDeviceCreate; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = TdDeviceClose; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TdDeviceCleanup; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TdDeviceControl; + DriverObject->DriverUnload = TdDeviceUnload; + + // + // Create a link in the Win32 namespace. + // + + Status = IoCreateSymbolicLink (&DosDevicesLinkName, &NtDeviceName); + + if (! NT_SUCCESS(Status)) + { + goto Exit; + } + + SymLinkCreated = TRUE; + + // + // Set process create routines. + // + + Status = PsSetCreateProcessNotifyRoutineEx ( + TdCreateProcessNotifyRoutine2, + FALSE + ); + + if (! NT_SUCCESS(Status)) + { + DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "ObCallbackTest: DriverEntry: PsSetCreateProcessNotifyRoutineEx(2) returned 0x%x\n", Status); + goto Exit; + } + + TdProcessNotifyRoutineSet2 = TRUE; + +Exit: + + if (!NT_SUCCESS (Status)) + { + if (TdProcessNotifyRoutineSet2 == TRUE) + { + Status = PsSetCreateProcessNotifyRoutineEx ( + TdCreateProcessNotifyRoutine2, + TRUE + ); + + TD_ASSERT (Status == STATUS_SUCCESS); + + TdProcessNotifyRoutineSet2 = FALSE; + } + + if (SymLinkCreated == TRUE) + { + IoDeleteSymbolicLink (&DosDevicesLinkName); + } + + if (Device != NULL) + { + IoDeleteDevice (Device); + } + } + + return Status; +} + +// +// Function: +// +// TdDeviceUnload +// +// Description: +// +// This function handles driver unloading. All this driver needs to do +// is to delete the device object and the symbolic link between our +// device name and the Win32 visible name. +// + +VOID +TdDeviceUnload ( + _In_ PDRIVER_OBJECT DriverObject +) +{ + NTSTATUS Status = STATUS_SUCCESS; + UNICODE_STRING DosDevicesLinkName = RTL_CONSTANT_STRING (TD_DOS_DEVICES_LINK_NAME); + + DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "ObCallbackTest: TdDeviceUnload\n"); + + // + // Unregister process notify routines. + // + + if (TdProcessNotifyRoutineSet2 == TRUE) + { + Status = PsSetCreateProcessNotifyRoutineEx ( + TdCreateProcessNotifyRoutine2, + TRUE + ); + + TD_ASSERT (Status == STATUS_SUCCESS); + + TdProcessNotifyRoutineSet2 = FALSE; + } + + // remove filtering and remove any OB callbacks + TdbProtectName = FALSE; + Status = TdDeleteProtectNameCallback(); + TD_ASSERT (Status == STATUS_SUCCESS); + + // + // Delete the link from our device name to a name in the Win32 namespace. + // + + Status = IoDeleteSymbolicLink (&DosDevicesLinkName); + if (Status != STATUS_INSUFFICIENT_RESOURCES) { + // + // IoDeleteSymbolicLink can fail with STATUS_INSUFFICIENT_RESOURCES. + // + + TD_ASSERT (NT_SUCCESS (Status)); + + } + + + // + // Delete our device object. + // + + IoDeleteDevice (DriverObject->DeviceObject); +} + +// +// Function: +// +// TdDeviceCreate +// +// Description: +// +// This function handles the 'create' irp. +// + + +NTSTATUS +TdDeviceCreate ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + UNREFERENCED_PARAMETER (DeviceObject); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +// +// Function: +// +// TdDeviceClose +// +// Description: +// +// This function handles the 'close' irp. +// + +NTSTATUS +TdDeviceClose ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + UNREFERENCED_PARAMETER (DeviceObject); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +// +// Function: +// +// TdDeviceCleanup +// +// Description: +// +// This function handles the 'cleanup' irp. +// + +NTSTATUS +TdDeviceCleanup ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + UNREFERENCED_PARAMETER (DeviceObject); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +// +// TdControlProtectName +// + +NTSTATUS TdControlProtectName ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + NTSTATUS Status = STATUS_SUCCESS; + PIO_STACK_LOCATION IrpStack = NULL; + ULONG InputBufferLength = 0; + PTD_PROTECTNAME_INPUT pProtectNameInput = NULL; + + UNREFERENCED_PARAMETER (DeviceObject); + + + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdControlProtectName: Entering\n"); + + IrpStack = IoGetCurrentIrpStackLocation (Irp); + InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; + + if (InputBufferLength < sizeof (TD_PROTECTNAME_INPUT)) + { + Status = STATUS_BUFFER_OVERFLOW; + goto Exit; + } + + pProtectNameInput = (PTD_PROTECTNAME_INPUT)Irp->AssociatedIrp.SystemBuffer; + + Status = TdProtectNameCallback (pProtectNameInput); + + switch (pProtectNameInput->Operation) { + case TDProtectName_Protect: + // Begin filtering access rights + TdbProtectName = TRUE; + TdbRejectName = FALSE; + break; + + case TDProtectName_Reject: + // Begin reject process creation on match + TdbProtectName = FALSE; + TdbRejectName = TRUE; + break; + } + + +Exit: + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TD_IOCTL_PROTECTNAME: Status %x\n", Status); + + return Status; +} + +// +// TdControlUnprotect +// + +NTSTATUS TdControlUnprotect ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + NTSTATUS Status = STATUS_SUCCESS; + // PIO_STACK_LOCATION IrpStack = NULL; + // ULONG InputBufferLength = 0; + + UNREFERENCED_PARAMETER (DeviceObject); + UNREFERENCED_PARAMETER (Irp); + + // IrpStack = IoGetCurrentIrpStackLocation (Irp); + // InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; + + // No need to check length of passed in parameters as we do not need any information from that + + // do not filter requested access + Status = TdDeleteProtectNameCallback(); + if (Status != STATUS_SUCCESS) { + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TdDeleteProtectNameCallback: status 0x%x\n", Status); + } + TdbProtectName = FALSE; + TdbRejectName = FALSE; + +//Exit: + DbgPrintEx ( + DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, + "ObCallbackTest: TD_IOCTL_UNPROTECT: exiting - status 0x%x\n", Status); + + return Status; +} + + +// +// Function: +// +// TdDeviceControl +// +// Description: +// +// This function handles 'control' irp. +// + +NTSTATUS +TdDeviceControl ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + PIO_STACK_LOCATION IrpStack; + ULONG Ioctl; + NTSTATUS Status; + + UNREFERENCED_PARAMETER (DeviceObject); + + + Status = STATUS_SUCCESS; + + IrpStack = IoGetCurrentIrpStackLocation (Irp); + Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; + + DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TdDeviceControl: entering - ioctl code 0x%x\n", Ioctl); + + switch (Ioctl) + { + case TD_IOCTL_PROTECT_NAME_CALLBACK: + + Status = TdControlProtectName (DeviceObject, Irp); + break; + + case TD_IOCTL_UNPROTECT_CALLBACK: + + Status = TdControlUnprotect (DeviceObject, Irp); + break; + + + default: + DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "TdDeviceControl: unrecognized ioctl code 0x%x\n", Ioctl); + break; + } + + // + // Complete the irp and return. + // + + Irp->IoStatus.Status = Status; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + + DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TdDeviceControl leaving - status 0x%x\n", Status); + return Status; +} diff --git a/general/obcallback/driver/tdriver.h b/general/obcallback/driver/tdriver.h new file mode 100644 index 00000000..b7dedd02 --- /dev/null +++ b/general/obcallback/driver/tdriver.h @@ -0,0 +1,125 @@ +/*++ + +Module Name: + + tdriver.h + +Abstract: + + This module declarations for the Ob/Ps callback test driver. + + +// Notice: +// +// Use this sample code at your own risk; there is no support from Microsoft for the sample code. +// In addition, this sample code is licensed to you under the terms of the Microsoft Public License +// (http://www.microsoft.com/opensource/licenses.mspx) + +--*/ + +#pragma once + +#include "shared.h" + +#define TD_CALLBACK_REGISTRATION_TAG '0bCO' // TD_CALLBACK_REGISTRATION structure. +#define TD_CALL_CONTEXT_TAG '1bCO' // TD_CALL_CONTEXT structure. + + +typedef struct _TD_CALLBACK_PARAMETERS { + ACCESS_MASK AccessBitsToClear; + ACCESS_MASK AccessBitsToSet; +} +TD_CALLBACK_PARAMETERS, *PTD_CALLBACK_PARAMETERS; + +// +// TD_CALLBACK_REGISTRATION +// + +typedef struct _TD_CALLBACK_REGISTRATION { + + // + // Handle returned by ObRegisterCallbacks. + // + + PVOID RegistrationHandle; + + // + // If not NULL, filter only requests to open/duplicate handles to this + // process (or one of its threads). + // + + PVOID TargetProcess; + HANDLE TargetProcessId; + + + // + // Currently each TD_CALLBACK_REGISTRATION has at most one process and one + // thread callback. That is, we can't register more than one callback for + // the same object type with a single ObRegisterCallbacks call. + // + + TD_CALLBACK_PARAMETERS ProcessParams; + TD_CALLBACK_PARAMETERS ThreadParams; + + ULONG RegistrationId; // Index in the global TdCallbacks array. + +} +TD_CALLBACK_REGISTRATION, *PTD_CALLBACK_REGISTRATION; + +// +// TD_CALL_CONTEXT +// + +typedef struct _TD_CALL_CONTEXT +{ + PTD_CALLBACK_REGISTRATION CallbackRegistration; + + OB_OPERATION Operation; + PVOID Object; + POBJECT_TYPE ObjectType; +} +TD_CALL_CONTEXT, *PTD_CALL_CONTEXT; + +extern KGUARDED_MUTEX TdCallbacksMutex; + +NTSTATUS TdDeleteCallback ( + _In_ ULONG RegistrationId +); + +// delete the process/thead OB callbacks +NTSTATUS TdDeleteProtectNameCallback (); + + + +NTSTATUS TdProtectNameCallback( + _In_ PTD_PROTECTNAME_INPUT pProtectName +); + +NTSTATUS TdCheckProcessMatch ( + _In_ PCUNICODE_STRING pustrCommand, + _In_ PEPROCESS Process, + _In_ HANDLE ProcessId +); + +OB_PREOP_CALLBACK_STATUS +CBTdPreOperationCallback ( + _In_ PVOID RegistrationContext, + _Inout_ POB_PRE_OPERATION_INFORMATION PreInfo +); + +VOID +CBTdPostOperationCallback ( + _In_ PVOID RegistrationContext, + _In_ POB_POST_OPERATION_INFORMATION PostInfo +); + +VOID TdSetCallContext ( + _Inout_ POB_PRE_OPERATION_INFORMATION PreInfo, + _In_ PTD_CALLBACK_REGISTRATION CallbackRegistration +); + +VOID TdCheckAndFreeCallContext ( + _Inout_ POB_POST_OPERATION_INFORMATION PostInfo, + _In_ PTD_CALLBACK_REGISTRATION CallbackRegistration +); + diff --git a/general/obcallback/driver/util.c b/general/obcallback/driver/util.c new file mode 100644 index 00000000..c00e96a3 --- /dev/null +++ b/general/obcallback/driver/util.c @@ -0,0 +1,73 @@ +/*++ + +Module Name: + + util.c + +Notice: + Use this sample code at your own risk; there is no support from Microsoft for the sample code. + In addition, this sample code is licensed to you under the terms of the Microsoft Public License + (http://www.microsoft.com/opensource/licenses.mspx) + + +--*/ + +#include "pch.h" +#include "tdriver.h" + +// +// TdSetCallContext +// +// Creates a call context object and stores a pointer to it +// in the supplied OB_PRE_OPERATION_INFORMATION structure. +// +// This function is called from a pre-notification. The created call context +// object then has to be freed in a corresponding post-notification using +// TdCheckAndFreeCallContext. +// + +void TdSetCallContext ( + _Inout_ POB_PRE_OPERATION_INFORMATION PreInfo, + _In_ PTD_CALLBACK_REGISTRATION CallbackRegistration +) +{ + PTD_CALL_CONTEXT CallContext; + + CallContext = (PTD_CALL_CONTEXT) ExAllocatePoolWithTag ( + PagedPool, sizeof(TD_CALL_CONTEXT), TD_CALL_CONTEXT_TAG + ); + + if (CallContext == NULL) + { + return; + } + + RtlZeroMemory (CallContext, sizeof(TD_CALL_CONTEXT)); + + CallContext->CallbackRegistration = CallbackRegistration; + CallContext->Operation = PreInfo->Operation; + CallContext->Object = PreInfo->Object; + CallContext->ObjectType = PreInfo->ObjectType; + + PreInfo->CallContext = CallContext; +} + +void TdCheckAndFreeCallContext ( + _Inout_ POB_POST_OPERATION_INFORMATION PostInfo, + _In_ PTD_CALLBACK_REGISTRATION CallbackRegistration +) +{ + PTD_CALL_CONTEXT CallContext = (PTD_CALL_CONTEXT)PostInfo->CallContext; + + if (CallContext != NULL) + { + TD_ASSERT (CallContext->CallbackRegistration == CallbackRegistration); + + TD_ASSERT (CallContext->Operation == PostInfo->Operation); + TD_ASSERT (CallContext->Object == PostInfo->Object); + TD_ASSERT (CallContext->ObjectType == PostInfo->ObjectType); + + ExFreePoolWithTag (CallContext, TD_CALL_CONTEXT_TAG); + } +} + diff --git a/general/obcallback/obcallback.sln b/general/obcallback/obcallback.sln new file mode 100644 index 00000000..ed5a27b9 --- /dev/null +++ b/general/obcallback/obcallback.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}") = "Control", "Control", "{D429EFC9-09E8-495C-81B0-32340C75C2BA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{5DA38202-119A-41F8-B5A6-CB8D38191147}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ObCallbackTestCtrl", "control\ObCallbackTestCtrl.vcxproj", "{8B053BEE-EA21-4D12-984B-6C93FE6D4992}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ObCallbackTest", "driver\ObCallbackTest.vcxproj", "{C696D115-0970-4E9C-8FED-31A99E039ED5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Debug|Win32.ActiveCfg = Debug|Win32 + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Debug|Win32.Build.0 = Debug|Win32 + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Release|Win32.ActiveCfg = Release|Win32 + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Release|Win32.Build.0 = Release|Win32 + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Debug|x64.ActiveCfg = Debug|x64 + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Debug|x64.Build.0 = Debug|x64 + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Release|x64.ActiveCfg = Release|x64 + {8B053BEE-EA21-4D12-984B-6C93FE6D4992}.Release|x64.Build.0 = Release|x64 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Debug|Win32.ActiveCfg = Debug|Win32 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Debug|Win32.Build.0 = Debug|Win32 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Release|Win32.ActiveCfg = Release|Win32 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Release|Win32.Build.0 = Release|Win32 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Debug|x64.ActiveCfg = Debug|x64 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Debug|x64.Build.0 = Debug|x64 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Release|x64.ActiveCfg = Release|x64 + {C696D115-0970-4E9C-8FED-31A99E039ED5}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {8B053BEE-EA21-4D12-984B-6C93FE6D4992} = {D429EFC9-09E8-495C-81B0-32340C75C2BA} + {C696D115-0970-4E9C-8FED-31A99E039ED5} = {5DA38202-119A-41F8-B5A6-CB8D38191147} + EndGlobalSection +EndGlobal |
