summaryrefslogtreecommitdiff
path: root/general/obcallback
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /general/obcallback
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'general/obcallback')
-rw-r--r--general/obcallback/ReadMe.md42
-rw-r--r--general/obcallback/control/ObCallbackTestCtrl.vcxproj236
-rw-r--r--general/obcallback/control/ObCallbackTestCtrl.vcxproj.Filters28
-rw-r--r--general/obcallback/control/common.h86
-rw-r--r--general/obcallback/control/main.cpp320
-rw-r--r--general/obcallback/control/pch.h18
-rw-r--r--general/obcallback/control/pchsrc.cpp1
-rw-r--r--general/obcallback/control/readme.txt57
-rw-r--r--general/obcallback/control/utils.cpp727
-rw-r--r--general/obcallback/driver/ObCallbackTest.vcxproj210
-rw-r--r--general/obcallback/driver/ObCallbackTest.vcxproj.Filters35
-rw-r--r--general/obcallback/driver/callback.c479
-rw-r--r--general/obcallback/driver/pch.h13
-rw-r--r--general/obcallback/driver/pchsrc.c1
-rw-r--r--general/obcallback/driver/shared.h95
-rw-r--r--general/obcallback/driver/tdriver.c532
-rw-r--r--general/obcallback/driver/tdriver.h125
-rw-r--r--general/obcallback/driver/util.c73
-rw-r--r--general/obcallback/obcallback.sln46
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