前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >内核中通过给线程插apc注入dll

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

作者头像
战神伽罗
发布2019-11-18 22:18:05
1.3K0
发布2019-11-18 22:18:05
举报
代码语言:javascript
复制
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 //分配内存
end:
		ret 0x0c
	}
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档