文件加载执行控制是程序白名单安全系统的技术基础,即在可执行文件(exe),库文件(dll)加载入内存前的一种监控机制,为安全软件提供了一种对系统允许加载运行的程序进行白名单定制的机会。在windows平台下,该方案可以实现在应用层,也可以以设备驱动的形式实现在内核层。若实现在应用层,则需要对explorer.exe和cmd.exe两个系统进程进行运行时代码注入,以分别监控由图形界面和命令行启动的程序进行拦截。由于这两个程序的内在运行逻辑未知,无法确定其创建新进程的行为的hook点,因此实现难度大,部署在应用层的监控模块安全性也无法得到保证。
因此选择在内核层完成对系统的进程创建和dll文件加载事件进行监控。对于xp和32位win7系统,这主要是通过对系统服务描述符表(SSDT)进行hook来实现。SSDT 的全称是 System Services Descriptor Table,系统服务描述符表。这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来。SSDT 并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基地址、服务函数个数等。通过修改此表的函数地址可以对常用Windows 函数及 API 进行 Hook,从而实现对一些关心的系统动作进行过滤、监控的目的。一些 HIPS、防毒软件、系统监控、注册表监控软件往往会采用此接口来实现自己的监控模块。
windows平台下,进程创建和dll加载都要调用NtCreateSection函数,该函数在目标进程地址空间内部为指定文件(exe,dll,bat)创建一个内存映射对象,功能类似于Linux下的mmap系统调用。因此该函数可作为标识进程创建和dll加载的入口点。我们需要hook SSDT中该函数的调用地址。
Windows API OpenProcess是从Kernel32导出的,所以调用首先转到了Kernel32的CreateSection函数。在CreateSection中又调用了ntdll!NtCreateSection函数。然后通过快速系统调用进入内核,根据传进来的索引在SSDT中得到函数的地址,然后调用函数。在 NT 4.0 以上的 Windows 操作系统中,默认就存在两个系统服