windows驱动保活的思路/apc demo

本文介绍了如何通过注册关机回调函数,使驱动在系统关机时检查自身服务和文件状态。同时展示了在用户模式和内核模式下使用Apc(异步过程调用)的示例代码,确保驱动在下次启动时能够正常运行。尽管这种方法可以在某些情况下确保驱动的启动,但在安全模式下仍可能被检测到。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:某驱动云下发器

   通过注册关机回调,使得驱动能够接收系统的关机时间,在这个时候检测自己的服务及文件是否正常。如下图:

                                              *注册关机回调

                                         *系统关机消息处理函数

注意:

当然还可以寻找更晚的时机来确保驱动能在下次开机能够启动。 不过,这种还是会在比如,安全模式下被发现的。

*kernel shellcode

//apc demo

//user-mode 

//
//ethread is the target execution environment,
//addr is the user-mode shellcode address
//
VOID UsermodeApc(PETHREAD ethread, PVOID address)
{
	PRKAPC apc = NULL;

	//check the apcs condition
	if (KeAreAllApcsDisabled() == FALSE&&
		address)
	{
		//we can use apcs
		apc = (PRKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC));
		if (apc)
		{
			//initialize apc structure
			//
			// for user mode apc
			// set RundownRoutine to NULL
			// ProcessorMode to UserMode
			// NormalRoutine to user-mdoe routine address
			//
			KeInitializeApc(
				apc,   //apc
				ethread,               //thread set the target thread obejct ,PsLookupThreadByThradId
				OriginalApcEnvironment,               //Enviroment
				KernelRoutine,               //KernelRoutine
				NULL,//RundownRoutine,               //RundownRoutine
				(PKNORMAL_ROUTINE)address,               //NormalRoutine
				UserMode,         //ProcessMode,specify under which mode the NormalRoutine will run
				NULL);              //NormalContext

			//insert apc into apc list
			DbgPrint("[%s]inserting user-mode apc!\n", __FUNCTION__);
			KeInsertQueueApc(
				apc,               //apc
			    NULL,                        //SystemArguemnt1,which can be used in KernelRoutine and NormalRoutine
				NULL,                           //SystemArgument2,which can be used in KernelRoutine and NormalRoutine
				IO_NO_INCREMENT                 //Increment
			);
		}
	}
}

//kernel mode 

//using KernelMode apc

void NTAPI KernelRoutine(PKAPC apc,
	PKNORMAL_ROUTINE* NormalRoutine,
	PVOID* NormalContext,
	PVOID* SystemArgument1, 
	PVOID* SystemArgument2)
{
	UNREFERENCED_PARAMETER(NormalRoutine);
	UNREFERENCED_PARAMETER(NormalContext);
	UNREFERENCED_PARAMETER(SystemArgument1);
	UNREFERENCED_PARAMETER(SystemArgument2);

	ExFreePool(apc);
}

void NTAPI RundownRoutine(PRKAPC apc)
{
	ExFreePool(apc);
}

void NTAPI NormalRoutine(PVOID NormalContext,
	PVOID SystemArgument1,
	PVOID SystemArgument2)
{
	UNREFERENCED_PARAMETER(NormalContext);
	UNREFERENCED_PARAMETER(SystemArgument1);
	UNREFERENCED_PARAMETER(SystemArgument2);

	//to do something
	DbgPrint("%s", (char*)SystemArgument1);
}

VOID TestKernelApc()
{
	PRKAPC apc =NULL;
	CHAR RawData[0x100] = "in apc NormalRoutine";

	//check the apcs condition
	if (KeAreAllApcsDisabled()==FALSE)
	{
		//we can use apcs
		apc = (PRKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC));
		if (apc)
		{
			//initialize apc structure
			//
			// for user mode apc
			// set RundownRoutine to NULL
			// ProcessorMode to UserMode
			// NormalRoutine to user-mdoe routine address
			//
			KeInitializeApc(apc,   //apc
				PsGetCurrentThread(),               //thread set the target thread obejct ,PsLookupThreadByThradId
				OriginalApcEnvironment,               //Enviroment
				KernelRoutine,               //KernelRoutine
				RundownRoutine,               //RundownRoutine
				NormalRoutine,               //NormalRoutine
				KernelMode,         //ProcessMode,specify under which mode the NormalRoutine will run
				NULL);              //NormalContext

			//insert apc into apc list
			DbgPrint("[%s]inserting apc!\n",__FUNCTION__);
			KeInsertQueueApc(apc,               //apc
				RawData,                        //SystemArguemnt1,which can be used in KernelRoutine and NormalRoutine
				NULL,                           //SystemArgument2,which can be used in KernelRoutine and NormalRoutine
				IO_NO_INCREMENT                 //Increment
			);
		}
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值