Windows内核Dll注入(一)

Windows内核Dll注入

近期在云桌面中遇到许多情况都需要对应用层程序的函数进行HOOK,并需要对函数参数进行各种修改,以便能够在虚拟桌面里面支持一些特性(尤其是一些3D的场景)。对API的HOOK是比较简单的,微软提供了开源的代码就能够实现;因此这里最主要的就是需要对HOOK的进程进行注入,来实现HOOK函数的功能。

在早期开发中,就实现过DLL注入的功能,不过都是基于用户层的注入来实现的,例如有远线程注入,消息钩子注入,用户层OPE注入。本篇中分享的是基于内核的注入技术,其中内核注入主要有:

  • HOOK函数注入。
  • 远程线程注入(使用ZwCreateThreadEx)。
  • OEP注入。
  • APC注入。

下面的文章主要是针对HOOK函数的注入,这个函数是NtTestAlert,接下来分析整个实现过程。

1. NtTestAlert

HOOK注入的第一步是需要找到一个函数,这个函数可以确保所有的进程启动的时候都会被调用,这个函数就是NtTestAlert,如下:

NTSYSAPI 
NTSTATUS
NTAPI
NtTestAlert(
);

该函数的作用是什么呢?我们知道,Windows在从内核切换到用户层的时候,就会判断线程的APC状态标记Thread->ApcState.UserApcPending,如下:

cmp     [ebx+_KTHREAD.___u12.ApcState.UserApcPending], 0

如果Thread->ApcState.UserApcPending为TRUE,那么就会对用户层的APC进行处理,那么什么情况下Thread->ApcState.UserApcPending才会被设置为TRUE呢?两个情况都满足:

  1. 调用Alertable的函数。
  2. 当前线程有用户态APC(一般放入线程APC链表中)。

Alertable的函数有如下:

DWORD SleepEx(
  DWORD dwMilliseconds,
  BOOL  bAlertable
);

DWORD WaitForSingleObjectEx(
  HANDLE hHandle,
  DWORD  dwMilliseconds,
  BOOL   bAlertable
);

这也是很多地方说的,只有在当前线程处于Alertable状态的时候,用户层APC才能被分发。

那么有没有一种办法,不用让线程调用Alertable的函数也能实现APC的分发呢?答案是有的;这个函数就是NtTestAlert,该函数的作用大致可以理解如下:

if ((AlertMode == UserMode) &&
    (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) != TRUE)) 
{
   
    Thread->ApcState.UserApcPending = TRUE;
}

主要就是设置Thread->ApcState.UserApcPending = TRUE,让APC可以被调度分发。

在每个线程启动的时候,都会调用NtTestAlert来分发用户层的APC例程,如下:

0:000> k
 # Child-SP          RetAddr               Call Site
00 0000005b`aedef448 00007fff`81703f88     ntdll!NtTestAlert
01 0000005b`aedef450 00007fff`81703ea3     ntdll!_LdrpInitialize+0xac
02 0000005b`aedef4d0 00007fff`81703dce     ntdll!LdrpInitializeInternal+0x6b
03 0000005b`aedef750 00000000`00000000     ntdll!LdrInitializeThunk+0xe

因此我们找到了一个进程(线程)启动一定会调用的函数了。注入的原理就是HOOK该函数,当NtTestAlert被执行的时候,就会跳转到我们HOOK的函数,然后该函数中通过LoadLibrary加载需要注入的Dll。

2. 技术分析

首先我们需要对进程的事件进行监控,记录进程的一些信息,例如:

  • 判断该进程是
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值