内核中通过给线程插apc注入dll

void ApcLoadDll(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2);
void ApcLoadDllEnd();
PMDL pMdl = NULL;
void ApcKernelRoutine( IN struct _KAPC *Apc, 
					  IN OUT PKNORMAL_ROUTINE *NormalRoutine, 
					  IN OUT PVOID *NormalContext, 
					  IN OUT PVOID *SystemArgument1, 
					  IN OUT PVOID *SystemArgument2 ) 
{
	if (Apc)
		ExFreePool(Apc);
	if(pMdl)
	{
		MmUnlockPages(pMdl);
		IoFreeMdl (pMdl);
		pMdl = NULL;
	}
	DbgPrint("ApcKernelRoutine called. Memory freed.");
}
VOID AddApcIngectDll(LPSTR DllFullPath, PETHREAD Thread,ULONG pTargetProcess,void *LoadLibraryWAddr)
{
	PRKAPC pApc = NULL; 
	PVOID pMappedAddress = NULL; 
	ULONG dwSize = 0;
	KAPC_STATE ApcState; 
	int *p=NULL;

	NTSTATUS Status = STATUS_UNSUCCESSFUL;
	if ( MmIsAddressValid((PVOID)Thread) == TRUE)
	{
		pApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
		if (!pApc)
		{
			DbgPrint("Failed to allocate memory for the APC structure");
			return ;
		}
		dwSize = 386;//这个长度是我们写的大片的nop
		pMdl = IoAllocateMdl (ApcLoadDll, dwSize, FALSE,FALSE,NULL);
		if (!pMdl)
		{
			DbgPrint(" Failed to allocate MDL");
			ExFreePool (pApc);
			return STATUS_INSUFFICIENT_RESOURCES;
		}
		__try
		{
			MmProbeAndLockPages (pMdl,KernelMode,IoWriteAccess);
		}
		__except (EXCEPTION_EXECUTE_HANDLER)
		{
			DbgPrint("Exception during MmProbeAndLockPages");
			IoFreeMdl (pMdl);
			ExFreePool (pApc);
			return STATUS_UNSUCCESSFUL;
		}
		KeStackAttachProcess((ULONG *)pTargetProcess,&ApcState);//进入目标进程的上下文
		pMappedAddress = MmMapLockedPagesSpecifyCache (pMdl,UserMode,MmCached,NULL,FALSE,NormalPagePriority);//把分配好的内存映射进目标进程里面
		if (!pMappedAddress)
		{
			DbgPrint("Cannot map address");
			KeUnstackDetachProcess (&ApcState);
			IoFreeMdl (pMdl);
			ExFreePool (pApc);
			return STATUS_UNSUCCESSFUL;
		}
		else 
			DbgPrint("UserMode memory at address: 0x%p",pMappedAddress);
		wcscpy ((unsigned char*)pMappedAddress + 0x16, DllFullPath);//将dll路径拷贝到目标进程空间
		p=(int*)((unsigned char*)pMappedAddress+6);
		*p=(int)((unsigned char*)pMappedAddress + 0x16);
		p=(int*)((unsigned char*)pMappedAddress+1);
		*p=LoadLibraryWAddr;
		KeUnstackDetachProcess (&ApcState); //恢复咱原来的上下文
		//初始化APC,插APC
		KeInitializeApc(pApc,
			(PETHREAD)Thread,
			OriginalApcEnvironment,
			&ApcKernelRoutine,
			NULL,
			(PKNORMAL_ROUTINE)pMappedAddress,
			UserMode,
			(PVOID) NULL);
		if (!KeInsertQueueApc(pApc,0,NULL,0))
		{
			DbgPrint("KernelExec -> Failed to insert APC");
			MmUnlockPages(pMdl);
			IoFreeMdl (pMdl);
			ExFreePool (pApc);
			return STATUS_UNSUCCESSFUL;
		}
		else
		{
			DbgPrint("APC delivered");
		}
		//使线程处于警告状态,注意不同操作系统的ETHREAD
		if(!*(char *)((char *)Thread+0x4a))
		{
			*(char *)((char *)Thread+0x4a) = TRUE;
		}
	}
}

//枚举指定进程的线程
NTSTATUS IngectDll(PEPROCESS Process,LPSTR DllFullPath,void *LoadLibraryWAddr)
{
	ULONG i;
	PETHREAD txtd;
	PEPROCESS txps;
	NTSTATUS st = STATUS_UNSUCCESSFUL;
	for (i=8;i<=65536;i=i+4)
	{
		st = PsLookupThreadByThreadId(i,&txtd);
		if ( NT_SUCCESS(st) )
		{
			txps=IoThreadToProcess(txtd); 
			if ( txps == Process )    
			{
				AddApcIngectDll(DllFullPath, txtd,Process,LoadLibraryWAddr);
				return STATUS_SUCCESS;      //只需要枚举一个线程就够了。因为我们注入dll只需要调用一次

			}
		}
	}
	return STATUS_SUCCESS;
}
__declspec(naked) void ApcLoadDll(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
	__asm 
	{       
		mov eax,0xabcdef //LoadLibraryW的地址这是是需要复制到目标进程空间之后再赋值的
			push 0xabcdef //这是是需要复制到目标进程空间之后再赋值的
			call eax
			jmp end
			nop //分配内存
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
end:
		ret 0x0c
	}
}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值