实现保护文件或目录、R3层通过与过滤驱动通讯通知要保护的文件或目录,可执行创建不可删除或修改。
R3层
#include
#include
#include
HANDLE g_hPort = INVALID_HANDLE_VALUE;
#define NPMINI_NAME L"FileiPortMin"
#define NPMINI_PORT_NAME L"\\FileiPortMin"
#pragma comment (lib,"fltLib.lib")
typedef struct _COMAND_MESSAGE
{
wchar_t Command[512];
}COMMAND_MESSAGE, * PCOMMAND_MESSAGE;
int NPSendMessage(PVOID InputBuffer) {
DWORD bytesReturned = 0;
DWORD hResult = 0;
PCOMMAND_MESSAGE command_message = (PCOMMAND_MESSAGE)InputBuffer;
hResult=FilterSendMessage(g_hPort, command_message,sizeof(COMMAND_MESSAGE),NULL,NULL,&bytesReturned);
if (hResult!=S_OK) {
printf("消息发送失败:%d\r\n", hResult);
return hResult;
}
else {
return true;
}
}
LPWSTR ConvertAnsiToUnicode(LPSTR ansiString) {
int requiredSize = MultiByteToWideChar(CP_ACP, 0, ansiString, -1, NULL, 0);
if (requiredSize > 0) {
LPWSTR unicodeString = (LPWSTR)malloc(requiredSize * sizeof(wchar_t));
if (unicodeString != NULL) {
MultiByteToWideChar(CP_ACP, 0, ansiString, -1, unicodeString, requiredSize);
return unicodeString;
}
}
return NULL;
}
int main(){
DWORD hResult = FilterConnectCommunicationPort(NPMINI_PORT_NAME, 0, NULL, 0, NULL, &g_hPort);
if (hResult != S_OK) {
printf("通讯失败\r\n");
printf("%d\r\n", hResult);
return hResult;
}
else {
printf("通讯成功\r\n");
wchar_t buffer[512];
LPWSTR cmdLineW = GetCommandLine();
LPSTR cmdLineA = GetCommandLineA();
int argc;
if (cmdLineW != NULL && cmdLineW[0] != L'\0' && wcslen(cmdLineW) > 0) {
LPWSTR* argv = CommandLineToArgvW(cmdLineW, &argc);
if (argv[1] != NULL) {
ZeroMemory(buffer, 512);
wcscpy(buffer, argv[1]);
printf("w:%ws", buffer);
NPSendMessage(buffer);
exit(0);
}
}
if (cmdLineA != NULL && cmdLineA[0] != '\0' && strlen(cmdLineA) > 0) {
LPWSTR res = ConvertAnsiToUnicode(cmdLineA);
LPWSTR* argv = CommandLineToArgvW(res, &argc);
if (argv[1] != NULL) {
ZeroMemory(buffer, 512);
wcscpy(buffer, argv[1]);
printf("A:%ws", buffer);
NPSendMessage(buffer);
exit(0);
}
}
}
return 0;
}
内核层
#include
#include
#include
#define MINISPY_PORT_NAME L"\\FileiPortMin"
PFLT_PORT gServerPort;
PFLT_PORT gClientPort;
static UNICODE_STRING ProtectedExtention = RTL_CONSTANT_STRING(L"com");
wchar_t fileName[512]=L"mimikatz";
typedef enum _MINI_COMMAND {
ENUM_PASS = 0,
ENUM_BLOCK
} MINI_COMMAND;
typedef struct _COMMAND_MESSAGE {
MINI_COMMAND Command;
} COMMAND_MESSAGE, * PCOMMAND_MESSAGE;
FLT_PREOP_CALLBACK_STATUS NPPreCreate(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID* CompletionContext) {
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();
FLT_PREOP_CALLBACK_STATUS ret = FLT_PREOP_SUCCESS_NO_CALLBACK;
NTSTATUS status;
PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
if (Data->Iopb->MajorFunction == IRP_MJ_CREATE) {
if (!FlagOn(Data->Iopb->Parameters.Create.Options, FILE_DISALLOW_EXCLUSIVE)) {
return ret;
}
}
if (FltObjects->FileObject != NULL) {
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);
if (NT_SUCCESS(status)) {
FltParseFileNameInformation(FileNameInfo);
WCHAR pTempBuf[512] = { 0 };
RtlCopyMemory(pTempBuf, FileNameInfo->Name.Buffer, FileNameInfo->Name.MaximumLength);
if (wcsstr(pTempBuf, fileName) != NULL) {
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
ret = FLT_PREOP_COMPLETE;
}
if (RtlCompareUnicodeString(&FileNameInfo->Extension, &ProtectedExtention, TRUE) == 0) {
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
ret = FLT_PREOP_COMPLETE;
}
FltReleaseFileNameInformation(FileNameInfo);
}
}
return ret;
}
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
{ IRP_MJ_CREATE, 0, NPPreCreate, NULL },
{ IRP_MJ_SET_INFORMATION, 0, NPPreCreate, NULL },
{ IRP_MJ_OPERATION_END }
};
PFLT_FILTER gFileterHandle;
NTSTATUS PtUnload(__in FLT_FILTER_UNLOAD_FLAGS Flags) {
UNREFERENCED_PARAMETER(Flags);
FltUnregisterFilter(gFileterHandle);
return STATUS_SUCCESS;
}
CONST FLT_REGISTRATION FilterRegistration = {
sizeof(FLT_REGISTRATION),
FLT_REGISTRATION_VERSION,
0,
NULL,
Callbacks,
PtUnload,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
NTSTATUS OnConnectInternal(
IN PFLT_PORT ClientPort,
IN PVOID ServerPortCookie,
IN PVOID ConnectionContext,
IN ULONG SizeOfContext,
OUT PVOID* ConnectionPortCookie
) {
DbgPrint("OnConnectInternal");
return 0;
}
VOID OnDisconnectInternal(
IN PVOID ConnectionContext
) {
DbgPrint("OnDisconnectInternal");
}
VOID MessData(__in PVOID ConnectionCookie,
__in_bcount_opt(InputBufferSize) PVOID InputBuffer,
__in ULONG InputBufferSize,
__out_bcount_part_opt(OutputBufferSize, *ReturnOutputBufferLength) PVOID OutputBuffer,
__in ULONG OutputBufferSize,
__out PULONG ReturnOutputBufferLength) {
MINI_COMMAND command;
NTSTATUS status;
PAGED_CODE();
UNREFERENCED_PARAMETER(ConnectionCookie);
UNREFERENCED_PARAMETER(OutputBufferSize);
UNREFERENCED_PARAMETER(OutputBuffer);
if (InputBufferSize>0) {
DbgPrint("InputBuffer: %s\r\n", (wchar_t*)InputBuffer);
RtlCopyMemory(fileName, InputBuffer, InputBufferSize);
}
}
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
DbgPrint("DriverEntryOK\r\n");
NTSTATUS status;
PSECURITY_DESCRIPTOR sd;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString;
UNREFERENCED_PARAMETER(RegistryPath);
status = FltRegisterFilter(DriverObject,
&FilterRegistration,
&gFileterHandle);
FLT_ASSERT(NT_SUCCESS(status));
if (NT_SUCCESS(status)) {
status = FltStartFiltering(gFileterHandle);
if (!NT_SUCCESS(status)) {
FltUnregisterFilter(gFileterHandle);
}
}
status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);
RtlInitUnicodeString(&uniString, MINISPY_PORT_NAME);
InitializeObjectAttributes(&oa,
&uniString,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
sd);
status = FltCreateCommunicationPort(gFileterHandle, &gServerPort, &oa, NULL, OnConnectInternal, OnDisconnectInternal, MessData, 1);
DbgPrint("FltCreateCommunicationPort OK\r\n");
return status;
}