Windows用户层使用指令操作内核程序执行指令! (7) 命令执行

为了确保用户应用程序能够顺利调用Windows内核功能,我们需要采取一种类似于Linux shell的方式来执行相应的指令。最初,我计划利用Microsoft提供的内核AVL树,并结合C++类来优化搜索操作的时间复杂度至O(log n)。然而,无论我如何尝试编写代码或查阅相关资料,最终都遭遇了系统蓝屏的困境,这让我无计可施。

在对比链表(时间复杂度为O(n))和哈希表(unordered_map,时间复杂度为O(1))的性能时,我发现当数据量低于10000条时,链表的速度最多仅比哈希表慢2到3倍。鉴于此,我决定改用链表来实现这一功能。尽管链表相对简单,但它无法接受C++类作为参数传递,这又一次导致了系统的蓝屏问题。

面对这一挑战,我不得不采取更为直接的方法,即使用if语句来判断和处理数据。虽然这种方法在速度上绝对优于链表,但它也不可避免地导致了代码结构的复杂化,形成了所谓的“史山代码”。在这里,我必须承认自己的能力有限,并请求您的理解和宽恕。

command.h

#pragma once
#include <ntifs.h>

#include "Logging.h"
#include "data.h"
#include "file.h"

extern UNICODE_STRING *commands;
extern ULONG commandCount;

NTSTATUS InitializeCommands();
VOID UninitializeCommands();


//可以根据自己的需求添加指令
//必须遵循NTSTATUS command_命令名字(UNICODE_STRING* args, ULONG length);
//否则您就要重构代码了
NTSTATUS command_help(UNICODE_STRING* args, ULONG length);
NTSTATUS command_echo(UNICODE_STRING* args, ULONG length);

NTSTATUS execute(UNICODE_STRING command, UNICODE_STRING* args, ULONG length);

command.cpp

#include "command.h"

UNICODE_STRING *commands;
ULONG commandCount;

NTSTATUS InitializeCommands()
{
	NTSTATUS status = STATUS_SUCCESS;
	commandCount = 2;
	commands = (UNICODE_STRING*)ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(UNICODE_STRING) * commandCount, 'CMD');
	if (commands == NULL) {
		WriteLog("[LyKernelService] Failed to allocate memory for commands, status = 0x%x\n", status);
		return STATUS_NO_MEMORY;
	}
	RtlInitUnicodeString(&commands[0], L"help");
	RtlInitUnicodeString(&commands[1], L"echo");
}

VOID UninitializeCommands()
{
	ExFreePoolWithTag(commands, 'CMD');
}

NTSTATUS command_help(UNICODE_STRING* args, ULONG length)
{
	NTSTATUS status = STATUS_SUCCESS;
	status = CleanResult();
	if (!NT_SUCCESS(status)) {
		WriteLog("[LyKernelService] Failed to clean result, status = 0x%x\n", status);
		return status;
	}
	for (ULONG i = 0; i < commandCount; i++) {
		WriteLog("[LyKernelService] %wZ\n", &commands[i]);
		WriteResult("%wZ\n", &commands[i]);
	}
	setResponseData("file(result)\n");
	return status;
}

NTSTATUS command_echo(UNICODE_STRING* args, ULONG length)
{
	for (ULONG i = 0; i < length; i++) {
		WriteLog("[LyKernelService] %wZ\n", &args[i]);
	}
	setResponseData("ok!\n");
	return STATUS_SUCCESS;
}

NTSTATUS execute(UNICODE_STRING command, UNICODE_STRING* args, ULONG length)
{
	if (RtlEqualUnicodeString(&command, &commands[0], TRUE)) {
		command_help(args, length);
	} else if (RtlEqualUnicodeString(&command, &commands[1], TRUE)) {
		command_echo(args, length);
	}
	else {
		WriteLog("[LyKernelService] Invalid command.");
		return STATUS_INVALID_PARAMETER;
	}
}

一定要注意,关于setResponseData和WriteResult的区别,前者速度快但是只能写入1024字节的数据(超级小),而后者适合大量数据写入(不用担心会覆盖,这个方法属于追加数据)

Windows用户层使用指令操作内核程序执行指令! (8) 应用驱动对接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值