Minifilter过滤驱动与R3程序通讯实现文件保护

实现保护文件或目录、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";
//wchar_t* fileName = L"mimikatz.exe";
//  Defines the commands between the utility and the filter
typedef enum _MINI_COMMAND {
    ENUM_PASS = 0,
    ENUM_BLOCK
} MINI_COMMAND;

//  Defines the command structure between the utility and the filter.
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;
    //文件IO执行放过可以执行
    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;
            }
            // 判断拓展名COM
            if (RtlCompareUnicodeString(&FileNameInfo->Extension, &ProtectedExtention, TRUE) == 0) {
            //IO拒绝请求
                Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                Data->IoStatus.Information = 0;
                ret = FLT_PREOP_COMPLETE;
            }
            // Clean up file name information.
            FltReleaseFileNameInformation(FileNameInfo);
        }
    }
    return ret;
}
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
    { IRP_MJ_CREATE, 0, NPPreCreate, NULL },				// DELETE_ON_CLOSE creation flag.
    { IRP_MJ_SET_INFORMATION, 0, NPPreCreate, NULL },		// FileInformationClass == FileDispositionInformation(Ex).
    { 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");
    //return 0;
}

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: %p\r\n", InputBuffer);
        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);

    /*PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
        ("MiniFilter!DriverEntry: Entered\n"));*/

    //
    //  Register with FltMgr to tell it our callback routines
    //

    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);
    //FltFreeSecurityDescriptor(sd);
    DbgPrint("FltCreateCommunicationPort OK\r\n");
    return status;
}

你可能感兴趣的:(开发,操作系统,win内核,驱动开发,web安全,安全架构,系统安全)