一种消息钩子防注入方法、装置以及客户端与流程

文档序号:12064179阅读:721来源:国知局
一种消息钩子防注入方法、装置以及客户端与流程

本发明属于系统安全技术领域,具体涉及一种消息钩子防注入方法及装置。



背景技术:

钩子(Hook)是Windows中消息处理机制的一个重要手段,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。钩子注入是病毒、木马常有的行为特征之一,病毒或木马程序不仅仅会钩子注入,它还可能修改硬盘文件、篡改注册表、修改主页等。

目前对于消息钩子的注入,都是在驱动层来进行拦截的,例如句柄匹配,这是一种全局拦截的方式,这种方法会增加消息钩子防注入的复杂性,同时其代码的稳定性也有待验证。



技术实现要素:

本发明提出一种消息钩子防注入方法,包括如下步骤:加载用户回调分配函数的钩子函数;判断所述钩子函数获取的第一参数是否等于预定数值,所述第一参数为用户回调分配函数返回的内核回调索引;若否,调用原有的用户回调分配函数;若是,判断所述钩子函数返回的第二参数偏移处所对应加载的动态链接库是否属于系统白名单;若属于系统白名单,调用原有的用户回调分配函数;若不属于系统白名单,返回系统内核。

本发明还提出一种消息钩子防注入装置,所述装置包括如下模块:

钩子函数加载模块,用于加载用户回调分配函数的钩子函数;

第一判断模块,用于判断所述钩子函数获取的第一参数是否为预定数值,所述第一参数为用户回调分配函数返回的内核回调索引;

第二判断模块,用于在所述第一参数等于预定数值时,判断所述钩子函数返回的第二参数偏移处所对应加载的动态链接库是否属于系统白名单;

调用模块,用于在所述第一参数不等于预定数值时调用原有的用户回调函数;以及在所述第二参数偏移处所对应加载的动态链接库属于系统白名单时调用原有的用户回调函数;

返回模块,用于在所述第二参数偏移处所对应加载的动态链接库不属于系统白名单时,返回系统内核。

本发明具有如下有益效果:本发明利用钩子函数获取用户回调函数返回的系统内核回调索引,以判断是否存在消息钩子注入以及消息钩子注入是否被系统信任。可以拦截所有通过不受信任的消息钩子向客户端应用程序注入的动态链接库(DLL),由此提高客户端应用程序的稳定性和安全性。

附图说明

下面结合附图对本发明的具体实施方式作进一步详细的说明;

图1是本发明实施例一提供的消息钩子防注入方法流程图。

图2是本发明实施例提供的Windows7系统内核回调表。

图3是本发明实施例提供的Windows8系统内核回调表。

图4是本发明实施例提供的Windows10系统内核回调表。

图5是本发明实施例二提供的消息钩子防注入方法流程图。

图6是本发明实施例三提供的消息钩子防注入系统结构示意图。

图7是本发明实施例提供的客户端系统硬件结构模块示意图。

具体实施方式

为了使本技术领域的人员更好地理解本发明方案,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分的实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本发明保护的范围。

本发明涉及的技术术语解释如下:

消息钩子,钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。

钩子注入,即远程线程注入技术,指的是通过在另一个进程中创建远程线程的方法进入目标进程的内存地址空间。钩子注入是病毒、木马常有的行为特征之一,将木马程序以DLL的形式实现后,需要使用插入到目标进程中的远程线程将该木马DLL插入到目标进程的地址空间,即利用该线程通过调用Windows API LoadLibrary函数来加载木马DLL,从而实现木马对系统的侵害。病毒或木马程序不仅仅会钩子注入,它还可能修改硬盘文件、篡改注册表、修改主页等。一些正常程序也往往会采用钩子注入的行为,比如一些要确保和系统紧密结合的防病毒软件、即时通讯工具等。

折叠系统钩子与线程钩子:SetWindowsHookEx()函数的最后一个参数决定了此钩子是系统钩子还是线程钩子。线程钩子用于监视指定线程的事件消息。线程钩子一般在当前线程或者当前线程派生的线程内。系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL)中。系统自动将包含"钩子回调函数"的DLL映射到受钩子函数影响的所有进程的地址空间中,即将这个DLL注入了那些进程。

实施例一:

本实施例提供一种消息钩子防注入方法,如图1所示,方法包括如下步骤:

S101,加载用户回调分配函数的钩子函数。

在步骤S101中,加载用户回调分配函数的钩子函数。用户回调分配函数可以用于获取系统应用层程序所对应的系统内核回调表,其第一个参数为内核回调索引。通过加载用户回调分配函数的钩子函数,可以获取系统回调表中返回的参数。

在一个具体的实施过程中,KiUserCallBackDispatcher即用户回调分配函数,其函数原型为:

VOID WINAPI KiUserCallBackDispatcher(__in ULONG,__in PVOID);

函数的第一参数是内核回调索引,函数的第二参数的偏移处是需要加载的动态链接库(DLL)路径。

当执行HOOK KiUserCallBackDispatcher时,通过钩子函数获取该用户回调分配函数返回的第一参数和第二参数,获得内核回调索引和需要加载的动态链接库路径,为识别应用是否被注入消息钩子提供了可能。

以windows7系统平台下的通用系统进程svchost.exe(PID=1004)为例,其用户回调表如图2所示,回调表中至少包含如下信息:内核回调索引、回调函数名称、当前函数地址、钩子状态(Hook)、原函数地址、当前函数地址所在模块。

在不同windows系统下不同应用程序所对应的用户回调表有所不同,但是各系统下的用户回调表均包含:内核回调索引、回调函数名称、当前函数地址、钩子状态(Hook)、原函数地址、当前函数地址所在模块。

S102,判断所述钩子函数返回的第一参数是否为预定数值,若是,执行步骤S103;若否,执行步骤S104。

正如在步骤S101中所提出的HOOK KiUserCallBackDispatcher为识别应用是否被注入消息钩子提供了可能。当应用被注入消息钩子时,必然会涉及到USER32!__ClientLoadLibrary的调用,即该函数所对应的索引会发生改变,此时,Hook KiUserCallBackDispatcher会返回ClientLoadLibrary函数所对应的系统内核回调表中的索引。也就是说,只需判断Hook KiUserCallBackDispatcher返回的索引是否是ClientLoadLibrary的索引,就能判断是否存在消息钩子注入。因此,在本步骤中,判断钩子函数返回的第一参数是否等于应用所对应的系统内核回调表中ClientLoadLibrary函数的索引,若不等于则说明当前的应用没有消息钩子注入,执行步骤S104;若等于则说明当前的应用存在消息钩子注入,应用存在被消息钩子注入的风险,执行步骤S103。

在具体的实施过程中,不同的操作系统对应的系统内核回调表中ClientLoadLibrary函数的索引不同。

在一个具体的实施过程中,如图2所示,Window7系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为65,即16进制0x41。

在一个具体的实施过程中,如图3所示,Window8系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为71,即16进制0x47。

在一个具体的实施过程中,如图4所示,Window10系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为75,即16进制0x4B。

由于不同操作系统中ClientLoadLibrary函数的索引并不相同,需要检测系统版本,根据系统版本确定对应的ClientLoadLibrary函数索引。

S103,调用原有的用户回调分配函数。

在步骤S102中判断所述钩子函数返回的第一参数是否为预定数值,不等于预定数值的情况下,应用不存在被注入消息钩子的风险,此时应用只需继续执行即可,系统继续调用原有的用户回调分配函数,按照正常步骤执行。

S104,判断所述钩子函数返回的第二参数偏移处所对应加载的动态链接库是否属于系统白名单,若属于系统白名单,执行步骤S105;若不属于系统白名单,执行步骤S106。

在步骤S102中,如果确定应用中存在消息钩子注入,则说明应用有被消息钩子侵入的危险;但是此时还不能判断注入的消息钩子一定是恶意注入,因为部分操作系统的动态链接库(DLL)也是通过消息钩子注入的,还有部分杀毒、安防软件、即时通信或者具有特殊用途的软件也需要通过消息钩子注入的方式来实现,因此,还要对这些动态链接库进行排除。

一个可选的方式是利用系统白名单的方式,对需要排除的动态链接库进行整理,例如需要使用消息注入的extheme.dll、ieframe.dll等。

但是通过目前通过HOOK KiUserCallBackDispatcher返回的参数为函数ClientLoadLibrary的索引,仅仅依靠该函数,无法直接与白名单中的动态链接库进行比较。因此,步骤S104中还需要解决如何排除白名单中的受信任的动态链接库的问题。为此,步骤S104引入了第二参数,第二参数的偏移处是需要加载的动态链接库(DLL)路径。使用该方法的原理是,当出现消息钩子注入时,必然伴随着系统内核回调表中对应项指向新的动态链接库,只要找到该路径就可以获取注入的消息钩子所调用的动态链接库,对该动态链接库进行判断就可以识别出该消息钩子注入是否属于受信任的消息钩子注入。

S105,调用原有的用户回调分配函数。

当步骤S104判断第二参数偏移处所对应加载的动态链接库属于系统白名单时,可以确定该消息钩子并非恶意注入,此时可以继续运行相关应用,系统调用原有的用户回调分配函数,从而继续调用原有的应用。

S106,返回系统内核。

当步骤S104判断第二参数偏移处所对应加载的动态链接库不属于系统白名单时,则判断该消息钩子属于不受信任的注入,为了应用安全,此时不能执行相关应用,因此,应用直接返回系统内核,从而避免消息钩子被调用。

实施例2:

本实施例提供一种消息钩子防注入方法,如图5所示,方法包括如下步骤:

S201,加载用户回调分配函数的钩子函数。

在步骤S201中,加载用户回调分配函数的钩子函数,即HOOK KiUserCallBackDispatcher。用户回调分配函数可以用于获取系统应用层程序所对应的系统内核回调表,其第一个参数为内核回调索引。通过加载用户回调分配函数的钩子函数,可以获取系统回调表中返回的参数。

在一个具体的实施过程中,KiUserCallBackDispatcher即用户回调分配函数,其函数原型为:

VOID WINAPI KiUserCallBackDispatcher(__in ULONG,__in PVOID);

函数的第一参数是内核回调索引,函数的第二参数的偏移处是需要加载的动态链接库(DLL)路径。

当执行HOOK KiUserCallBackDispatcher时,通过钩子函数获取该用户回调分配函数返回的第一参数和第二参数,获得内核回调索引和需要加载的动态链接库路径,为识别应用是否被注入消息钩子提供了可能。

以windows7系统平台下的通用系统进程svchost.exe(PID=1004)为例,其用户回调表如图2所示,回调表中至少包含如下信息:内核回调索引、回调函数名称、当前函数地址、钩子状态(Hook)、原函数地址、当前函数地址所在模块。

在不同windows系统下不同应用程序所对应的用户回调表有所不同,但是各系统下的用户回调表均包含:内核回调索引、回调函数名称、当前函数地址、钩子状态(Hook)、原函数地址、当前函数地址所在模块。

S202,对第一参数进行配置,判断所述钩子函数返回的第一参数是否为预定数值,若是,执行步骤S203;若否,执行步骤S204。

正如在步骤S201中所提出的HOOK KiUserCallBackDispatcher为识别应用是否被注入消息钩子提供了可能。当应用被注入消息钩子时,必然会涉及到USER32!__ClientLoadLibrary的调用,即该函数所对应的索引会发生改变,此时,Hook KiUserCallBackDispatcher会返回用户加载库函数(ClientLoadLibrary)所对应的系统内核回调表中的索引。也就是说,只需判断Hook KiUserCallBackDispatcher返回的索引是否是ClientLoadLibrary的索引,就能判断是否存在消息钩子注入。因此,在本步骤中,判断钩子函数返回的第一参数是否等于应用所对应的系统内核回调表中ClientLoadLibrary函数的索引,若不等于则说明当前的应用没有消息钩子注入,执行步骤S204;若等于则说明当前的应用存在消息钩子注入,应用存在被消息钩子注入的风险,执行步骤S203。

在具体的实施过程中,不同的操作系统对应的系统内核回调表中ClientLoadLibrary函数的索引不同。

在一个具体的实施过程中,如图2所示,Window7系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为65,即16进制0x41。

在一个具体的实施过程中,如图3所示,Window8系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为71,即16进制0x47。

在一个具体的实施过程中,如图4所示,Window10系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为75,即16进制0x4B。

由于不同操作系统中ClientLoadLibrary函数的索引并不相同,需要对第一参数进行配置。因此步骤S202还可以进一步分为子步骤S2020和子步骤S2021。

步骤S2020,对预定值进行配置。

对预定值进行配置是为了使预定值与当前系统所对应的用户加载库函数(ClientLoadLibrary)索引相匹配。

对预定值进行配置可以采用预存列表的方式,因为在各个系统中,ClientLoadLibrary函数索引虽然不同,但是却是确定的,例如Window7系统中回调索引为0x41、Window8系统中回调索引为0x47、Window10系统中回调索引为0x4B,在获得这些索引后,存储于预存列表中,在进行第一参数配置时,首先获得当前系统的版本号,然后根据系统版本号在预存列表中检索,从而获得系统版本对应的回调索引,从而确定预定值。这种方法运算量小,只需获得系统版本即可实现对于预定值的配置,根据上述描述,其分为如下子步骤:

S2020A,获取不同系统版本ClientLoadLibrary函数的内核回调索引,并形成预存列表。

S2020B,获取当前系统的系统版本。

S2020C,在所述预存列表中查询当前系统版本所对应ClientLoadLibrary函数的内核回调索引,并返回。

S2020D,将查询获得的ClientLoadLibrary函数的内核回调索引配置为所述预定值。

当然,也可以采取即时获取预定值的方法,这种方法首先获得当前系统的内核回调表,然后在内核回调表中查找ClientLoadLibrary函数,再获得ClientLoadLibrary函数对应的索引,即预定值。这种方法无需进行预存列表与系统版本号的获取,然而需要对系统内核回调表进行一次抽取,并进行查表,运算量相对较大,根据上述描述,其分为如下子步骤:

S2020A’,获得当前系统的内核回调表。

S2020B’,内核回调表中查找ClientLoadLibrary函数。

S2020C’,获得ClientLoadLibrary函数对应的索引。

S2020D’,将所述ClientLoadLibrary函数对应的索引确定为预定值。

步骤S2021,判断所述钩子函数返回的第一参数是否为预定数值。

在S2020中对预定值进行配置之后,接下来的步骤S2021中只需判断钩子函数的返回值是否等于该预定值即可。如前所述,比较过程可以是一个16位数值的比较过程,例如Window7系统中返回的第一参数是否等于回调索引0x41、Window8系统中返回的第一参数是否等于回调索引0x47、Window10系统中返回的第一参数是否等于回调索引0x4B。

S203,调用原有的用户回调分配函数。

在步骤S202中判断所述钩子函数返回的第一参数是否为预定数值,不等于预定数值的情况下,应用不存在被注入消息钩子的风险,此时应用只需继续执行即可,系统继续调用原有的用户回调分配函数,按照正常步骤执行。

S204,判断所述钩子函数返回的第二参数偏移处所对应加载的动态链接库是否属于系统白名单,若属于系统白名单,执行步骤S105;若不属于系统白名单,执行步骤S206。

在步骤S202中,如果确定应用中存在消息钩子注入,则说明应用有被消息钩子侵入的危险;但是此时还不能判断注入的消息钩子一定是恶意注入,因为部分操作系统的动态链接库(DLL)也是通过消息钩子注入的,还有部分杀毒、安防软件、即时通信或者具有特殊用途的软件也需要通过消息钩子注入的方式来实现,因此,还要对这些动态链接库进行排除。

一个可选的方式是利用系统白名单的方式,对需要排除的动态链接库进行整理,例如需要使用消息注入的extheme.dll、ieframe.dll等。

但是通过目前通过HOOK KiUserCallBackDispatcher返回的参数为函数ClientLoadLibrary的索引,仅仅依靠该函数,无法直接与白名单中的动态链接库进行比较。因此,步骤S204中还需要解决如何排除白名单中的受信任的动态链接库的问题。为此,步骤S204引入了第二参数,第二参数的偏移处是需要加载的动态链接库(DLL)路径。使用该方法的原理是,当出现消息钩子注入时,必然伴随着系统内核回调表中对应项指向新的动态链接库,只要找到该路径就可以获取注入的消息钩子所调用的动态链接库,对该动态链接库进行判断就可以识别出该消息钩子注入是否属于受信任的消息钩子注入。在Window7系统,内核回调表中用于表示需要加载的动态链接库(DLL)路径的函数为fnINDEVICECHANG,其内核回调表索引为0x1c,该函数偏移处所加载的动态链接库即消息钩子所加载的动态链接库,查询该动态链接库是否是系统白名单中受信任的动态链接库。

系统白名单是预先设立的用于存储受信任动态链接库的名单,该名单至少包含系统应用需要正常调用的消息钩子,以及用户添加的可信任消息钩子,当然白名单还可以来源于云系统收集,在安全可靠的同时避免误识别。

经过比较,如果动态链接库属于系统白名单,则目前的消息钩子是受到系统信任的注入,则接下来执行S205。

经过比较,若不属于系统白名单,则判断该消息钩子属于不受信任的注入,执行步骤S206。

S205,调用原有的用户回调分配函数。

当步骤S204判断第二参数偏移处所对应加载的动态链接库属于系统白名单时,可以确定该消息钩子并非恶意注入,此时可以继续运行相关应用,系统调用原有的用户回调分配函数,从而继续调用原有的应用。

这个步骤可以通过UnHook KiUserCallbackDispatcher来实现,进程退出后,反初始化,进入正常调用KiUserCallbackDispatcher函数。

S206,返回系统内核。

当步骤S204判断第二参数偏移处所对应加载的动态链接库不属于系统白名单时,则判断该消息钩子属于不受信任的注入,为了应用安全,此时不能执行相关应用,因此,应用直接返回系统内核,从而避免消息钩子被调用。

在具体的实施过程中,返回系统内核操作是通过调用ntCallback-Return函数来实现的,该函数直接调用KiUserCallbackDispatcher中的返回的函数,以执行返回系统内核的操作。该执行过程可以通过KiUserCallBackDispatcher中的ReturnStatus函数来触发。ReturnStatus是反映返回状态的函数,当其值为零时,会调用NtCallbackReturn函数,进而返回内核。如果当前消息钩子不属于白名单,则将KiUserCallBackDispatcher中的ReturnStatus的值变成0,接下来调用NtCallbackReturn,则直接返回系统内核,无论消息钩子指向和调用任何动态链接库,其都不会得到响应,相当于将该消息钩子隔离。

实施例3:

本实施例提供一种消息钩子防注入装置,如图6所示,所述装置包括如下模块:

钩子函数加载模块,用于加载用户回调分配函数的钩子函数,即HOOK KiUserCallBackDispatcher。用户回调分配函数可以用于获取系统应用层程序所对应的系统内核回调表,其第一个参数为内核回调索引。通过加载用户回调分配函数的钩子函数,可以获取系统回调表中返回的参数。

在一个具体的实施过程中,KiUserCallBackDispatcher即用户回调分配函数,其函数原型为:

VOID WINAPI KiUserCallBackDispatcher(__in ULONG,__in PVOID);

函数的第一参数是内核回调索引,函数的第二参数的偏移处是需要加载的动态链接库(DLL)路径。

当执行HOOK KiUserCallBackDispatcher时,通过钩子函数获取该用户回调分配函数返回的第一参数和第二参数,获得内核回调索引和需要加载的动态链接库路径,为识别应用是否被注入消息钩子提供了可能。

以windows7系统平台下的通用系统进程svchost.exe(PID=1004)为例,其用户回调表如图2所示,回调表中至少包含如下信息:内核回调索引、回调函数名称、当前函数地址、钩子状态(Hook)、原函数地址、当前函数地址所在模块。

在不同windows系统下不同应用程序所对应的用户回调表有所不同,但是各系统下的用户回调表均包含:内核回调索引、回调函数名称、当前函数地址、钩子状态(Hook)、原函数地址、当前函数地址所在模块。

第一判断模块,用于对预定值进行配置,判断所述钩子函数返回的第一参数是否为预定数值。

钩子函数加载模块所提出的HOOK KiUserCallBackDispatcher为识别应用是否被注入消息钩子提供了可能。当应用被注入消息钩子时,必然会涉及到USER32!__ClientLoadLibrary的调用,即该函数所对应的索引会发生改变,此时,Hook KiUserCallBackDispatcher会返回用户加载库函数(ClientLoadLibrary)所对应的系统内核回调表中的索引。也就是说,只需判断Hook KiUserCallBackDispatcher返回的索引是否是ClientLoadLibrary的索引,就能判断是否存在消息钩子注入。因此,在本步骤中,判断钩子函数返回的第一参数是否等于应用所对应的系统内核回调表中ClientLoadLibrary函数的索引,若不等于则说明当前的应用没有消息钩子注入;若等于则说明当前的应用存在消息钩子注入,应用存在被消息钩子注入的风险。

在具体的实施过程中,不同的操作系统对应的系统内核回调表中ClientLoadLibrary函数的索引不同。

在一个具体的实施过程中,如图2所示,Window7系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为65,即16进制0x41。

在一个具体的实施过程中,如图3所示,Window8系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为71,即16进制0x47。

在一个具体的实施过程中,如图4所示,Window10系统所对应的系统内核回调表中ClientLoadLibrary函数的索引为75,即16进制0x4B。

由于不同操作系统中ClientLoadLibrary函数的索引并不相同,需要对第一参数进行配置。因此第一判断模块还可以进一步分为预定值配置子模块和预定值比较子模块。

预定值配置子模块,对预定值进行配置是为了使预定值与当前系统所对应的用户加载库函数(ClientLoadLibrary)索引相匹配。

对预定值进行配置可以采用预存列表的方式,因为在各个系统中,ClientLoadLibrary函数索引虽然不同,但是却是确定的,例如Window7系统中回调索引为0x41、Window8系统中回调索引为0x47、Window10系统中回调索引为0x4B,在获得这些索引后,存储于预存列表中,在进行第一参数配置时,首先获得当前系统的版本号,然后根据系统版本号在预存列表中检索,从而获得系统版本对应的回调索引,从而确定预定值。这种方法运算量小,只需获得系统版本即可实现对于预定值的配置,根据上述描述,其分为如下子模块:

预存列表生成子模块,获取不同系统版本ClientLoadLibrary函数的内核回调索引,并形成预存列表。

系统版本获取子模块,获取当前系统的系统版本。

查询子模块,在所述预存列表中查询当前系统版本所对应ClientLoadLibrary函数的内核回调索引,并返回。

确定子模块,将查询获得的ClientLoadLibrary函数的内核回调索引配置为所述预定值。

当然,也可以采取即时获取预定值的方法,这种方法首先获得当前系统的内核回调表,然后在内核回调表中查找ClientLoadLibrary函数,再获得ClientLoadLibrary函数对应的索引,即预定值。这种方法无需进行预存列表与系统版本号的获取,然而需要对系统内核回调表进行一次抽取,并进行查表,运算量相对较大,根据上述描述,其分为如下子步骤:

内核回调表获取子模块,获得当前系统的内核回调表。

函数查询子模块,内核回调表中查找ClientLoadLibrary函数。

索引获取子模块,获得ClientLoadLibrary函数对应的索引。

确定子模块,将所述ClientLoadLibrary函数对应的索引确定为预定值。

预定值比较子模块,判断所述钩子函数返回的第一参数是否为预定数值。

在预定值配置子模块中对预定值进行配置之后,接下来的预定值比较子模块中只需判断钩子函数的返回值是否等于该预定值即可。如前所述,比较过程可以是一个16位数值的比较过程,例如Window7系统中返回的第一参数是否等于回调索引0x41、Window8系统中返回的第一参数是否等于回调索引0x47、Window10系统中返回的第一参数是否等于回调索引0x4B。

如果第一判断模块的判断结果为,当前应用存在消息钩子注入则,使用第二判断模块进行第二次判断。

否则,使用调用模块,在所述第一参数不等于预定数值时调用原有的用户回调函数。这个可以通过UnHook KiUserCallbackDispatcher来实现,进程退出后,反初始化,进入正常调用KiUserCallbackDispatcher函数。

第二判断模块,用于在所述第一参数等于预定数值时,判断所述钩子函数返回的第二参数偏移处所对应加载的动态链接库是否属于系统白名单。

在第一判断模块中,如果确定应用中存在消息钩子注入,则说明应用有被消息钩子侵入的危险;但是此时还不能判断注入的消息钩子一定是恶意注入,因为部分操作系统的动态链接库(DLL)也是通过消息钩子注入的,还有部分杀毒、安防软件、即时通信或者具有特殊用途的软件也需要通过消息钩子注入的方式来实现,因此,还要对这些动态链接库进行排除。

一个可选的方式是利用系统白名单的方式,对需要排除的动态链接库进行整理,例如需要使用消息注入的extheme.dll、ieframe.dll等。

但是通过目前通过HOOK KiUserCallBackDispatcher返回的参数为函数ClientLoadLibrary的索引,仅仅依靠该函数,无法直接与白名单中的动态链接库进行比较。因此,第二判断模块中还需要解决如何排除白名单中的受信任的动态链接库的问题。为此,第二判断模块引入了第二参数,第二参数的偏移处是需要加载的动态链接库(DLL)路径。使用该方法的原理是,当出现消息钩子注入时,必然伴随着系统内核回调表中对应项指向新的动态链接库,只要找到该路径就可以获取注入的消息钩子所调用的动态链接库,对该动态链接库进行判断就可以识别出该消息钩子注入是否属于受信任的消息钩子注入。在Window7系统,内核回调表中用于表示需要加载的动态链接库(DLL)路径的函数为fnINDEVICECHANG,其内核回调表索引为0x1c,该函数偏移处所加载的动态链接库即消息钩子所加载的动态链接库,查询该动态链接库是否是系统白名单中受信任的动态链接库。

系统白名单是预先设立的用于存储受信任动态链接库的名单,该名单至少包含系统应用需要正常调用的消息钩子,以及用户添加的可信任消息钩子,当然白名单还可以来源于云系统收集,在安全可靠的同时避免误识别。

经过比较,如果动态链接库属于系统白名单,则目前的消息钩子是受到系统信任的注入,则启动调用模块。调用模块,在所述第二参数偏移处所对应加载的动态链接库属于系统白名单时调用原有的用户回调函数。

当第二判断模块判断第二参数偏移处所对应加载的动态链接库属于系统白名单时,可以确定该消息钩子并非恶意注入,此时可以继续运行相关应用,系统调用原有的用户回调分配函数,从而继续调用原有的应用。

这个步骤可以通过UnHook KiUserCallbackDispatcher来实现,进程退出后,反初始化,进入正常调用KiUserCallbackDispatcher函数。

经过比较,若不属于系统白名单,则判断该消息钩子属于不受信任的注入,则调用返回模块。返回模块,用于在所述第二参数偏移处所对应加载的动态链接库不属于系统白名单时,返回系统内核。

当第二判断模块判断第二参数偏移处所对应加载的动态链接库不属于系统白名单时,则判断该消息钩子属于不受信任的注入,为了应用安全,此时不能执行相关应用,因此,应用直接返回系统内核,从而避免消息钩子被调用。

在具体的实施过程中,返回系统内核操作是通过调用ntCallback-Return函数来实现的,该函数直接调用KiUserCallbackDispatcher中的返回的函数,以执行返回系统内核的操作。该执行过程可以通过KiUserCallBackDispatcher中的ReturnStatus函数来触发。ReturnStatus是反映返回状态的函数,当其值为零时,会调用NtCallbackReturn函数,进而返回内核。如果当前消息钩子不属于白名单,则将KiUserCallBackDispatcher中的ReturnStatus的值变成0,接下来调用NtCallbackReturn,则直接返回系统内核,无论消息钩子指向和调用任何动态链接库,其都不会得到响应,相当于将该消息钩子隔离。

实施例4:

本发明涉及的装置可应用于客户端中,所述客户端可以是诸如台式机、笔记本电脑、移动终端(例如智能手机)、ipad等。

当然,装置也可应用于平台中。或者,所述装置或系统也可以软件的形式运行于终端(客户端)上。

图7示出了上述装置或系统或服务器的一种通用计算机系统结构。

上述计算机系统包括总线,处理器1、存储器2、通信接口3、输入设备4和输出设备5通过总线相互连接。其中,总线在计算机系统各个部件之间传送信息。

处理器1可以是通用处理器,例如通用中央处理器(CPU)、网络处理器(Network Processor,简称NP)、微处理器等,也可以是特定应用集成电路(application-specific integrated circuit,ASIW),或一个或多个用于控制本发明方案程序执行的集成电路。还可以是数字信号处理器(DSP)、专用集成电路(ASIC)、现成可编程门阵列(FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。

处理器1可包括主处理器,还可包括基带芯片、调制解调器等。存储器2中保存有执行本发明技术方案的程序,还可以保存有操作系统和其他关键业务。具体地,程序可以包括程序代码,程序代码包括计算机操作指令。更具体的,存储器2可以包括只读存储器(read-only memory,ROM)、可存储静态信息和指令的其他类型的静态存储设备、随机存取存储器(random access memory,RAM)、可存储信息和指令的其他类型的动态存储设备、磁盘存储器、flash等等。

输入设备4可包括接收用户输入的数据和信息的装置,例如键盘、鼠标、摄像头、扫描仪、光笔、语音输入装置、触摸屏、计步器或重力感应器等。

输出设备5可包括允许输出信息给用户的装置,例如显示屏、打印机、扬声器等。

通信接口3可包括使用任何收发器一类的装置,以便与其他设备或通信网络通信,如以太网,无线接入网(RAN),无线局域网(WLAN)等。

处理器1执行存储器2中所存放的程序、指令或者代码,以及调用其他设备,并与操作系统交互或者调用操作系统中的部分指令,用于实现本发明实施例的如下各个步骤:

加载用户回调分配函数的钩子函数;判断所述钩子函数返回的第一参数是否为预定数值;若否,调用原有的用户回调分配函数;若是,判断所述钩子函数返回的第二参数偏移处所对应加载的动态链接库是否属于系统白名单;若属于系统白名单,调用原有的用户回调分配函数;若不属于系统白名单,返回系统内核。

在一个具体的实施过程中,所述第一参数为用户回调分配函数返回的内核回调索引。

在一个具体的实施过程中,所述判断所述钩子函数返回的第一参数是否为预定数值步骤进一步包含如下子步骤:配置所述预定数值;判断所述第一参数是否等于所述预定数值。

在一个具体的实施过程中,所述配置预定数值包括根据系统版本确定对应的预置数值。

在一个具体的实施过程中,所述调用原有的用户回调分配函数步骤包括退出钩子函数、反初始化和重新加载用户回调分配函数。

在一个具体的实施过程中,所述第二参数指向应用需要加载的动态链接库路径。

在一个具体的实施过程中,所述返回系统内核包括跳过对第二参数偏移处所对应加载的动态链接库进行加载的步骤,直接返回系统内核。

专业人员还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本发明的范围。

结合本文中所公开的实施例描述的方法或算法的步骤可以直接用硬件、处理器执行的软件模块,或者二者的结合来实施。软件模块可以置于随机存储器(RAM)、内存、只读存储器(ROM)、电可编程ROM、电可擦除可编程ROM、寄存器、硬盘、可移动磁盘、WD-ROM、或技术领域内所公知的任意其它形式的存储介质中。

对所公开的实施例的上述说明,使本领域专业技术人员能够实现或使用本发明。对这些实施例的多种修改对本领域的专业技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1