Skip to content

Commit

Permalink
Merge pull request #22 from tarterp/21_driver_plugin_architecture
Browse files Browse the repository at this point in the history
21 driver plugin architecture
  • Loading branch information
stevemk14ebr authored Nov 17, 2023
2 parents 3aab9b9 + 4a1993d commit edabce6
Show file tree
Hide file tree
Showing 20 changed files with 3,391 additions and 452 deletions.
10 changes: 10 additions & 0 deletions C/FileDeleteRecordPluginDriver/Constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#define DRIVER_POOL_TAG ' xtS'
#define DRIVER_NAME_WITH_EXT L"strace.sys"
#define NT_DEVICE_NAME L"\\Device\\STrace"
#define DOS_DEVICES_LINK_NAME L"\\DosDevices\\STrace"
#define DEVICE_SDDL L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"

#define IOCTL_LOADDLL CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 0), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define IOCTL_UNLOADDLL CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 1), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
195 changes: 195 additions & 0 deletions C/FileDeleteRecordPluginDriver/FileDeleteRecordPluginDriver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#pragma warning(disable: 4996) //exallocatepoolwithtag
#include <ntifs.h>

#include "interface.h"

#include "utils.h"

const unsigned long PLUGIN_POOL_TAG = 'LEDS';

#pragma warning(disable: 6011)
PluginApis g_Apis;

#if defined(ENABLE_LOG)
#if defined(__GNUC__) || defined(__clang__)

// On GCC and Clang __VA_ARGS__ must be used differently.
#define DBGPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[STRACE] " format "\n", ##__VA_ARGS__)
#define LOG_DEBUG(fmt,...) g_Apis.pLogPrint(LogLevelDebug, __FUNCTION__, fmt, ##__VA_ARGS__)
#define LOG_INFO(fmt,...) g_Apis.pLogPrint(LogLevelInfo, __FUNCTION__, fmt, ##__VA_ARGS__)
#define LOG_WARN(fmt,...) g_Apis.pLogPrint(LogLevelWarn, __FUNCTION__, fmt, ##__VA_ARGS__)
#define LOG_ERROR(fmt,...) g_Apis.pLogPrint(LogLevelError, __FUNCTION__, fmt, ##__VA_ARGS__)
#else

#define DBGPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[STRACE] " format "\n", __VA_ARGS__)
#define LOG_DEBUG(fmt,...) g_Apis.pLogPrint(LogLevelDebug, __FUNCTION__, fmt, __VA_ARGS__)
#define LOG_INFO(fmt,...) g_Apis.pLogPrint(LogLevelInfo, __FUNCTION__, fmt, __VA_ARGS__)
#define LOG_WARN(fmt,...) g_Apis.pLogPrint(LogLevelWarn, __FUNCTION__, fmt, __VA_ARGS__)
#define LOG_ERROR(fmt,...) g_Apis.pLogPrint(LogLevelError, __FUNCTION__, fmt, __VA_ARGS__)
#endif // __GNUC__ || __clang__

#else

#define DBGPRINT(format, ...) ((void)format)

#endif // _DEBUG

enum PROBE_IDS : ULONG64 {
IdSetInformationFile = 0,
};

extern "C" __declspec(dllexport) void StpInitialize(PluginApis & pApis) {
g_Apis = pApis;
LOG_INFO("Plugin Initializing...\r\n");

g_Apis.pSetCallback("SetInformationFile", PROBE_IDS::IdSetInformationFile);
LOG_INFO("Plugin Initialized\r\n");
}
ASSERT_INTERFACE_IMPLEMENTED(StpInitialize, tStpInitialize, "StpInitialize does not match the interface type");

extern "C" __declspec(dllexport) void StpDeInitialize() {
LOG_INFO("Plugin DeInitializing...\r\n");

g_Apis.pUnsetCallback("SetInformationFile");

LOG_INFO("Plugin DeInitialized\r\n");
}
ASSERT_INTERFACE_IMPLEMENTED(StpDeInitialize, tStpDeInitialize, "StpDeInitialize does not match the interface type");

extern "C" __declspec(dllexport) bool StpIsTarget(CallerInfo & callerinfo) {
UNREFERENCED_PARAMETER(callerinfo);
return true;
}
ASSERT_INTERFACE_IMPLEMENTED(StpIsTarget, tStpIsTarget, "StpIsTarget does not match the interface type");

void PrintStackTrace(CallerInfo& callerinfo) {
for (int i = 0; i < callerinfo.frameDepth; i++) {
if ((callerinfo.frames)[i].frameaddress) {
const auto modulePathLen = (callerinfo.frames)[i].modulePath ? strlen((callerinfo.frames)[i].modulePath) : 0;

// add brackets around module dynamically
if (modulePathLen) {
char moduleName[sizeof(CallerInfo::StackFrame::modulePath) + 2] = { 0 };
moduleName[0] = '[';
strcpy(&moduleName[1], (callerinfo.frames)[i].modulePath);
moduleName[modulePathLen + 1] = ']';

LOG_INFO(" %-18s +0x%08llx\r\n", moduleName, (callerinfo.frames)[i].frameaddress - (callerinfo.frames)[i].modulebase);
}
else {
LOG_INFO(" %-18s 0x%016llx\r\n", "[UNKNOWN MODULE]", (callerinfo.frames)[i].frameaddress);
}
}
else {
LOG_INFO(" Frame Missing\r\n");
}
}
}



OBJECT_NAME_INFORMATION* getFilePathFromHandle(HANDLE hFile) {
ULONG dwSize = 0;
OBJECT_NAME_INFORMATION* pObjectName = nullptr;
NTSTATUS status = ZwQueryObject(hFile, (OBJECT_INFORMATION_CLASS)1 /*ObjectNameInformation*/, pObjectName, 0, &dwSize);
if (dwSize)
{
pObjectName = (OBJECT_NAME_INFORMATION*)ExAllocatePoolWithTag(NonPagedPoolNx, dwSize, PLUGIN_POOL_TAG);
if (pObjectName) {
status = ZwQueryObject(hFile, (OBJECT_INFORMATION_CLASS)1 /*ObjectNameInformation*/, pObjectName, dwSize, &dwSize);
}
}

if (status == STATUS_SUCCESS && pObjectName) {
return pObjectName;
}

if (pObjectName) {
ExFreePoolWithTag(pObjectName, PLUGIN_POOL_TAG);
pObjectName = nullptr;
}
return nullptr;
}

extern "C" __declspec(dllexport) void StpCallbackEntry(ULONG64 pService, ULONG32 probeId, MachineState & ctx, CallerInfo & callerinfo)
{
//LOG_INFO("[ENTRY] %s[0x%x](%d) Id: %d Parameters: [%d]\r\n", callerinfo.processName, callerinfo.processId, callerinfo.isWow64 ? 32 : 64, pService, probeId, ctx.paramCount);
UNREFERENCED_PARAMETER(pService);
UNREFERENCED_PARAMETER(probeId);
UNREFERENCED_PARAMETER(ctx);
UNREFERENCED_PARAMETER(callerinfo);
switch (probeId) {
case PROBE_IDS::IdSetInformationFile: {
auto hFile = (HANDLE)ctx.read_argument(0);
auto InformationClass = ctx.read_argument(4);
if (InformationClass == 13) { // FileDispositionInformation
auto pInformation = (char*)ctx.read_argument(2); // 1 == DeleteFile
if (*pInformation == 1) {
auto pFilePath = getFilePathFromHandle(hFile);

if (pFilePath) {
LOG_INFO("File %wZ deleted\r\n", pFilePath->Name);
//backupFile((wchar_t*)backup_directory, pFilePath->Name, hFile);
//ExFreePoolWithTag(pFilePath, PLUGIN_POOL_TAG);
//pFilePath = nullptr;
LOG_INFO("File Backup Complete\r\n");
}
else {
LOG_INFO("File [unknown] deleted\r\n");
}

PrintStackTrace(callerinfo);
}
}
break;
}
}
}
ASSERT_INTERFACE_IMPLEMENTED(StpCallbackEntry, tStpCallbackEntryPlugin, "StpCallbackEntry does not match the interface type");

extern "C" __declspec(dllexport) void StpCallbackReturn(ULONG64 pService, ULONG32 probeId, MachineState & ctx, CallerInfo & callerinfo) {
UNREFERENCED_PARAMETER(pService);
UNREFERENCED_PARAMETER(probeId);
UNREFERENCED_PARAMETER(ctx);
UNREFERENCED_PARAMETER(callerinfo);
//LOG_INFO("[RETURN] %s[%x](%d) %016llx Id: %d\r\n", callerinfo.processName, callerinfo.processId, callerinfo.isWow64 ? 32 : 64, pService, probeId);
}
ASSERT_INTERFACE_IMPLEMENTED(StpCallbackReturn, tStpCallbackReturnPlugin, "StpCallbackEntry does not match the interface type");


NTSTATUS DeviceCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return STATUS_SUCCESS;
}

VOID DeviceUnload(_In_ PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
DBGPRINT("FileDeleteRecord::DeviceUnload");
}


/*
* /GS- must be set to disable stack cookies and have DriverEntry
* be the entrypoint. GsDriverEntry sets up stack cookie and calls
* Driver Entry normally.
*/
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(RegistryPath);

DBGPRINT("FileDeleteRecord::DriverEntry()");


DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceCreateClose;
DriverObject->DriverUnload = DeviceUnload;

return STATUS_SUCCESS;
}
34 changes: 34 additions & 0 deletions C/FileDeleteRecordPluginDriver/FileDeleteRecordPluginDriver.inf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
;
; FileDeleteRecordPluginDriver.inf
;

[Version]
Signature="$WINDOWS NT$"
Class=System
ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
Provider=%ManufacturerName%
DriverVer=
CatalogFile=FileDeleteRecordPluginDriver.cat
PnpLockdown=1

;This template is supported for OS version 17763 (Windows 10 version 1809) and after.
;For Windows OS prior to Windows 10 1809 set DefaultDestDir = 12
[DestinationDirs]
DefaultDestDir = 13


[SourceDisksNames]
1 = %DiskName%,,,""

[SourceDisksFiles]


[Manufacturer]
%ManufacturerName%=Standard,NT$ARCH$

[Standard.NT$ARCH$]


[Strings]
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
DiskName="FileDeleteRecordPluginDriver Source Disk"
133 changes: 133 additions & 0 deletions C/FileDeleteRecordPluginDriver/FileDeleteRecordPluginDriver.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?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|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{CD47158C-73E3-4197-AE90-92DC38D8BC0E}</ProjectGuid>
<TemplateGuid>{dd38f7fc-d7bd-488b-9242-7d8754cde80d}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">x64</Platform>
<RootNamespace>FileDeleteRecordPluginDriver</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<ClCompile>
<StructMemberAlignment>Default</StructMemberAlignment>
</ClCompile>
<ClCompile>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<LanguageStandard>stdcpp20</LanguageStandard>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;ENABLE_LOG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<ClCompile>
<ControlFlowGuard>false</ControlFlowGuard>
<BufferSecurityCheck>false</BufferSecurityCheck>
<StructMemberAlignment>Default</StructMemberAlignment>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="FileDeleteRecordPluginDriver.cpp" />
<ClCompile Include="Interface.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Constants.h" />
<ClInclude Include="Interface.h" />
<ClInclude Include="MyStdint.h" />
<ClInclude Include="NtBuild.h" />
<ClInclude Include="NtStructs.h" />
<ClInclude Include="utils.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Loading

0 comments on commit edabce6

Please sign in to comment.