Skip to content

Commit edabce6

Browse files
authored
Merge pull request #22 from tarterp/21_driver_plugin_architecture
21 driver plugin architecture
2 parents 3aab9b9 + 4a1993d commit edabce6

20 files changed

+3391
-452
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#define DRIVER_POOL_TAG ' xtS'
4+
#define DRIVER_NAME_WITH_EXT L"strace.sys"
5+
#define NT_DEVICE_NAME L"\\Device\\STrace"
6+
#define DOS_DEVICES_LINK_NAME L"\\DosDevices\\STrace"
7+
#define DEVICE_SDDL L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"
8+
9+
#define IOCTL_LOADDLL CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 0), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
10+
#define IOCTL_UNLOADDLL CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 1), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
#pragma warning(disable: 4996) //exallocatepoolwithtag
2+
#include <ntifs.h>
3+
4+
#include "interface.h"
5+
6+
#include "utils.h"
7+
8+
const unsigned long PLUGIN_POOL_TAG = 'LEDS';
9+
10+
#pragma warning(disable: 6011)
11+
PluginApis g_Apis;
12+
13+
#if defined(ENABLE_LOG)
14+
#if defined(__GNUC__) || defined(__clang__)
15+
16+
// On GCC and Clang __VA_ARGS__ must be used differently.
17+
#define DBGPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[STRACE] " format "\n", ##__VA_ARGS__)
18+
#define LOG_DEBUG(fmt,...) g_Apis.pLogPrint(LogLevelDebug, __FUNCTION__, fmt, ##__VA_ARGS__)
19+
#define LOG_INFO(fmt,...) g_Apis.pLogPrint(LogLevelInfo, __FUNCTION__, fmt, ##__VA_ARGS__)
20+
#define LOG_WARN(fmt,...) g_Apis.pLogPrint(LogLevelWarn, __FUNCTION__, fmt, ##__VA_ARGS__)
21+
#define LOG_ERROR(fmt,...) g_Apis.pLogPrint(LogLevelError, __FUNCTION__, fmt, ##__VA_ARGS__)
22+
#else
23+
24+
#define DBGPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[STRACE] " format "\n", __VA_ARGS__)
25+
#define LOG_DEBUG(fmt,...) g_Apis.pLogPrint(LogLevelDebug, __FUNCTION__, fmt, __VA_ARGS__)
26+
#define LOG_INFO(fmt,...) g_Apis.pLogPrint(LogLevelInfo, __FUNCTION__, fmt, __VA_ARGS__)
27+
#define LOG_WARN(fmt,...) g_Apis.pLogPrint(LogLevelWarn, __FUNCTION__, fmt, __VA_ARGS__)
28+
#define LOG_ERROR(fmt,...) g_Apis.pLogPrint(LogLevelError, __FUNCTION__, fmt, __VA_ARGS__)
29+
#endif // __GNUC__ || __clang__
30+
31+
#else
32+
33+
#define DBGPRINT(format, ...) ((void)format)
34+
35+
#endif // _DEBUG
36+
37+
enum PROBE_IDS : ULONG64 {
38+
IdSetInformationFile = 0,
39+
};
40+
41+
extern "C" __declspec(dllexport) void StpInitialize(PluginApis & pApis) {
42+
g_Apis = pApis;
43+
LOG_INFO("Plugin Initializing...\r\n");
44+
45+
g_Apis.pSetCallback("SetInformationFile", PROBE_IDS::IdSetInformationFile);
46+
LOG_INFO("Plugin Initialized\r\n");
47+
}
48+
ASSERT_INTERFACE_IMPLEMENTED(StpInitialize, tStpInitialize, "StpInitialize does not match the interface type");
49+
50+
extern "C" __declspec(dllexport) void StpDeInitialize() {
51+
LOG_INFO("Plugin DeInitializing...\r\n");
52+
53+
g_Apis.pUnsetCallback("SetInformationFile");
54+
55+
LOG_INFO("Plugin DeInitialized\r\n");
56+
}
57+
ASSERT_INTERFACE_IMPLEMENTED(StpDeInitialize, tStpDeInitialize, "StpDeInitialize does not match the interface type");
58+
59+
extern "C" __declspec(dllexport) bool StpIsTarget(CallerInfo & callerinfo) {
60+
UNREFERENCED_PARAMETER(callerinfo);
61+
return true;
62+
}
63+
ASSERT_INTERFACE_IMPLEMENTED(StpIsTarget, tStpIsTarget, "StpIsTarget does not match the interface type");
64+
65+
void PrintStackTrace(CallerInfo& callerinfo) {
66+
for (int i = 0; i < callerinfo.frameDepth; i++) {
67+
if ((callerinfo.frames)[i].frameaddress) {
68+
const auto modulePathLen = (callerinfo.frames)[i].modulePath ? strlen((callerinfo.frames)[i].modulePath) : 0;
69+
70+
// add brackets around module dynamically
71+
if (modulePathLen) {
72+
char moduleName[sizeof(CallerInfo::StackFrame::modulePath) + 2] = { 0 };
73+
moduleName[0] = '[';
74+
strcpy(&moduleName[1], (callerinfo.frames)[i].modulePath);
75+
moduleName[modulePathLen + 1] = ']';
76+
77+
LOG_INFO(" %-18s +0x%08llx\r\n", moduleName, (callerinfo.frames)[i].frameaddress - (callerinfo.frames)[i].modulebase);
78+
}
79+
else {
80+
LOG_INFO(" %-18s 0x%016llx\r\n", "[UNKNOWN MODULE]", (callerinfo.frames)[i].frameaddress);
81+
}
82+
}
83+
else {
84+
LOG_INFO(" Frame Missing\r\n");
85+
}
86+
}
87+
}
88+
89+
90+
91+
OBJECT_NAME_INFORMATION* getFilePathFromHandle(HANDLE hFile) {
92+
ULONG dwSize = 0;
93+
OBJECT_NAME_INFORMATION* pObjectName = nullptr;
94+
NTSTATUS status = ZwQueryObject(hFile, (OBJECT_INFORMATION_CLASS)1 /*ObjectNameInformation*/, pObjectName, 0, &dwSize);
95+
if (dwSize)
96+
{
97+
pObjectName = (OBJECT_NAME_INFORMATION*)ExAllocatePoolWithTag(NonPagedPoolNx, dwSize, PLUGIN_POOL_TAG);
98+
if (pObjectName) {
99+
status = ZwQueryObject(hFile, (OBJECT_INFORMATION_CLASS)1 /*ObjectNameInformation*/, pObjectName, dwSize, &dwSize);
100+
}
101+
}
102+
103+
if (status == STATUS_SUCCESS && pObjectName) {
104+
return pObjectName;
105+
}
106+
107+
if (pObjectName) {
108+
ExFreePoolWithTag(pObjectName, PLUGIN_POOL_TAG);
109+
pObjectName = nullptr;
110+
}
111+
return nullptr;
112+
}
113+
114+
extern "C" __declspec(dllexport) void StpCallbackEntry(ULONG64 pService, ULONG32 probeId, MachineState & ctx, CallerInfo & callerinfo)
115+
{
116+
//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);
117+
UNREFERENCED_PARAMETER(pService);
118+
UNREFERENCED_PARAMETER(probeId);
119+
UNREFERENCED_PARAMETER(ctx);
120+
UNREFERENCED_PARAMETER(callerinfo);
121+
switch (probeId) {
122+
case PROBE_IDS::IdSetInformationFile: {
123+
auto hFile = (HANDLE)ctx.read_argument(0);
124+
auto InformationClass = ctx.read_argument(4);
125+
if (InformationClass == 13) { // FileDispositionInformation
126+
auto pInformation = (char*)ctx.read_argument(2); // 1 == DeleteFile
127+
if (*pInformation == 1) {
128+
auto pFilePath = getFilePathFromHandle(hFile);
129+
130+
if (pFilePath) {
131+
LOG_INFO("File %wZ deleted\r\n", pFilePath->Name);
132+
//backupFile((wchar_t*)backup_directory, pFilePath->Name, hFile);
133+
//ExFreePoolWithTag(pFilePath, PLUGIN_POOL_TAG);
134+
//pFilePath = nullptr;
135+
LOG_INFO("File Backup Complete\r\n");
136+
}
137+
else {
138+
LOG_INFO("File [unknown] deleted\r\n");
139+
}
140+
141+
PrintStackTrace(callerinfo);
142+
}
143+
}
144+
break;
145+
}
146+
}
147+
}
148+
ASSERT_INTERFACE_IMPLEMENTED(StpCallbackEntry, tStpCallbackEntryPlugin, "StpCallbackEntry does not match the interface type");
149+
150+
extern "C" __declspec(dllexport) void StpCallbackReturn(ULONG64 pService, ULONG32 probeId, MachineState & ctx, CallerInfo & callerinfo) {
151+
UNREFERENCED_PARAMETER(pService);
152+
UNREFERENCED_PARAMETER(probeId);
153+
UNREFERENCED_PARAMETER(ctx);
154+
UNREFERENCED_PARAMETER(callerinfo);
155+
//LOG_INFO("[RETURN] %s[%x](%d) %016llx Id: %d\r\n", callerinfo.processName, callerinfo.processId, callerinfo.isWow64 ? 32 : 64, pService, probeId);
156+
}
157+
ASSERT_INTERFACE_IMPLEMENTED(StpCallbackReturn, tStpCallbackReturnPlugin, "StpCallbackEntry does not match the interface type");
158+
159+
160+
NTSTATUS DeviceCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
161+
{
162+
UNREFERENCED_PARAMETER(DeviceObject);
163+
164+
Irp->IoStatus.Status = STATUS_SUCCESS;
165+
Irp->IoStatus.Information = 0;
166+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
167+
168+
return STATUS_SUCCESS;
169+
}
170+
171+
VOID DeviceUnload(_In_ PDRIVER_OBJECT DriverObject)
172+
{
173+
UNREFERENCED_PARAMETER(DriverObject);
174+
DBGPRINT("FileDeleteRecord::DeviceUnload");
175+
}
176+
177+
178+
/*
179+
* /GS- must be set to disable stack cookies and have DriverEntry
180+
* be the entrypoint. GsDriverEntry sets up stack cookie and calls
181+
* Driver Entry normally.
182+
*/
183+
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
184+
{
185+
UNREFERENCED_PARAMETER(RegistryPath);
186+
187+
DBGPRINT("FileDeleteRecord::DriverEntry()");
188+
189+
190+
DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceCreateClose;
191+
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceCreateClose;
192+
DriverObject->DriverUnload = DeviceUnload;
193+
194+
return STATUS_SUCCESS;
195+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
;
2+
; FileDeleteRecordPluginDriver.inf
3+
;
4+
5+
[Version]
6+
Signature="$WINDOWS NT$"
7+
Class=System
8+
ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
9+
Provider=%ManufacturerName%
10+
DriverVer=
11+
CatalogFile=FileDeleteRecordPluginDriver.cat
12+
PnpLockdown=1
13+
14+
;This template is supported for OS version 17763 (Windows 10 version 1809) and after.
15+
;For Windows OS prior to Windows 10 1809 set DefaultDestDir = 12
16+
[DestinationDirs]
17+
DefaultDestDir = 13
18+
19+
20+
[SourceDisksNames]
21+
1 = %DiskName%,,,""
22+
23+
[SourceDisksFiles]
24+
25+
26+
[Manufacturer]
27+
%ManufacturerName%=Standard,NT$ARCH$
28+
29+
[Standard.NT$ARCH$]
30+
31+
32+
[Strings]
33+
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
34+
DiskName="FileDeleteRecordPluginDriver Source Disk"
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup Label="ProjectConfigurations">
4+
<ProjectConfiguration Include="Debug|x64">
5+
<Configuration>Debug</Configuration>
6+
<Platform>x64</Platform>
7+
</ProjectConfiguration>
8+
<ProjectConfiguration Include="Release|x64">
9+
<Configuration>Release</Configuration>
10+
<Platform>x64</Platform>
11+
</ProjectConfiguration>
12+
<ProjectConfiguration Include="Debug|ARM64">
13+
<Configuration>Debug</Configuration>
14+
<Platform>ARM64</Platform>
15+
</ProjectConfiguration>
16+
<ProjectConfiguration Include="Release|ARM64">
17+
<Configuration>Release</Configuration>
18+
<Platform>ARM64</Platform>
19+
</ProjectConfiguration>
20+
</ItemGroup>
21+
<PropertyGroup Label="Globals">
22+
<ProjectGuid>{CD47158C-73E3-4197-AE90-92DC38D8BC0E}</ProjectGuid>
23+
<TemplateGuid>{dd38f7fc-d7bd-488b-9242-7d8754cde80d}</TemplateGuid>
24+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
25+
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
26+
<Configuration>Debug</Configuration>
27+
<Platform Condition="'$(Platform)' == ''">x64</Platform>
28+
<RootNamespace>FileDeleteRecordPluginDriver</RootNamespace>
29+
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
30+
</PropertyGroup>
31+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
32+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
33+
<TargetVersion>Windows10</TargetVersion>
34+
<UseDebugLibraries>true</UseDebugLibraries>
35+
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
36+
<ConfigurationType>Driver</ConfigurationType>
37+
<DriverType>WDM</DriverType>
38+
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
39+
</PropertyGroup>
40+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
41+
<TargetVersion>Windows10</TargetVersion>
42+
<UseDebugLibraries>false</UseDebugLibraries>
43+
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
44+
<ConfigurationType>Driver</ConfigurationType>
45+
<DriverType>WDM</DriverType>
46+
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
47+
</PropertyGroup>
48+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
49+
<TargetVersion>Windows10</TargetVersion>
50+
<UseDebugLibraries>true</UseDebugLibraries>
51+
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
52+
<ConfigurationType>Driver</ConfigurationType>
53+
<DriverType>WDM</DriverType>
54+
</PropertyGroup>
55+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
56+
<TargetVersion>Windows10</TargetVersion>
57+
<UseDebugLibraries>false</UseDebugLibraries>
58+
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
59+
<ConfigurationType>Driver</ConfigurationType>
60+
<DriverType>WDM</DriverType>
61+
</PropertyGroup>
62+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
63+
<ImportGroup Label="ExtensionSettings">
64+
</ImportGroup>
65+
<ImportGroup Label="PropertySheets">
66+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
67+
</ImportGroup>
68+
<PropertyGroup Label="UserMacros" />
69+
<PropertyGroup />
70+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
71+
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
72+
<EnableInf2cat>false</EnableInf2cat>
73+
</PropertyGroup>
74+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
75+
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
76+
<EnableInf2cat>false</EnableInf2cat>
77+
</PropertyGroup>
78+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
79+
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
80+
</PropertyGroup>
81+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
82+
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
83+
</PropertyGroup>
84+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
85+
<DriverSign>
86+
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
87+
</DriverSign>
88+
<ClCompile>
89+
<StructMemberAlignment>Default</StructMemberAlignment>
90+
</ClCompile>
91+
<ClCompile>
92+
<BufferSecurityCheck>false</BufferSecurityCheck>
93+
<ControlFlowGuard>false</ControlFlowGuard>
94+
<LanguageStandard>stdcpp20</LanguageStandard>
95+
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;ENABLE_LOG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
96+
</ClCompile>
97+
<Link>
98+
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
99+
</Link>
100+
</ItemDefinitionGroup>
101+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
102+
<DriverSign>
103+
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
104+
</DriverSign>
105+
<ClCompile>
106+
<ControlFlowGuard>false</ControlFlowGuard>
107+
<BufferSecurityCheck>false</BufferSecurityCheck>
108+
<StructMemberAlignment>Default</StructMemberAlignment>
109+
<LanguageStandard>stdcpp20</LanguageStandard>
110+
</ClCompile>
111+
<Link>
112+
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
113+
</Link>
114+
</ItemDefinitionGroup>
115+
<ItemGroup>
116+
<FilesToPackage Include="$(TargetPath)" />
117+
</ItemGroup>
118+
<ItemGroup>
119+
<ClCompile Include="FileDeleteRecordPluginDriver.cpp" />
120+
<ClCompile Include="Interface.cpp" />
121+
</ItemGroup>
122+
<ItemGroup>
123+
<ClInclude Include="Constants.h" />
124+
<ClInclude Include="Interface.h" />
125+
<ClInclude Include="MyStdint.h" />
126+
<ClInclude Include="NtBuild.h" />
127+
<ClInclude Include="NtStructs.h" />
128+
<ClInclude Include="utils.h" />
129+
</ItemGroup>
130+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
131+
<ImportGroup Label="ExtensionTargets">
132+
</ImportGroup>
133+
</Project>

0 commit comments

Comments
 (0)