代码语言: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
}
}