通过回调函数阻止进程创建(验证结束,方案完全可行)

(此方案完全可行,只是我忘掉了一步)

虽然Vista之后版本有进程创建回调函数的Ex版,而且Ex版可以拦截进程创建,

但是由于在Ex版回调函数内用第三个参数的最后一个元素来阻止进程创建的话,可能会出现弹框,所以不安全,所以这个方案可行性不高。

(这里说的不安全,是说可以被用户层看到这个弹框,可以被发现,处理麻烦,如果是用户自己设置的拦截,那么根本不需要通知用户,如果是我们自己做拦截,就不该让用户发现,

不管怎么说,这个弹框都是不应该出现的。)

所以,我想了这个方案,不知道是否可行,先纪录下这个方案。

步骤:

    1:注册进程创建回调,以及镜像加载回调,普通版本就可以了,不需要Ex版,这样从XP开始的所有版本就都兼容了。

    2:当一个进程被创建的时候,进程创建回调会被调用,而且create参数应该为 1,

      这时,纪录进程的全部信息,保存在安全的位置(设备扩展),由于进程可能很多,所以需要用链表

      要保存的信息包括,进程ID,进程文件路径,以及一个进程创建标志flage,可以设置为0

    3:进程创建回调被调用之后,紧接着被调用的就是镜像加载回调,而第一个被加载的镜像,就是那个可执行文件,

      也就是说,当镜像加载回调被触发的时候,根据进程ID,去设备扩展里面的链表中找到这个进程ID,判断它的flage是否为0

      如果为0的话,修改flage为1,标志已经被处理过了(安全起见也可以判断镜像名字)

      镜像加载回调的第三个参数可以得到镜像基址,根据基址,然后分析一下PE,得到OEP的RVA,加上基址,得到VA,

      这里是重点,把VA的第一个字节数据记录下来,保存在链表中,然后修改VA的第一个字节为 C3 ,也就是 retn

      这样,可以保证,进程的主线程刚刚启动,就返回了

      为什么要保存VA的数据,这就是下面说的

      (一般来说,其实可以用类似 0x00400000 这种默认的建议加载地址来做判断可执行文件的镜像基址的,

      但是这样做不安全,因为可执行文件也可以有重定向表,这样基址就是可变的了,所以还是需要用第一次加载的方式,来寻找可执行文件的镜像基址)

    4:由于执行进程创建回调、镜像加载回调的时候,镜像只是被映射到了内存,并不是被写入到内存中的,所以对内存的修改会直接影响到可执行文件

      这时,就要对原始文件做一个修复,

      修复的时机就是在进程退出的时候,也就是进程加载回调第二次被调用的时候,也就是create参数为0的时候,根据当前进程ID,去设备扩展里面寻找进程路径

      根据分析PE文件,得到OEP的RVA,然后找到它的位置,修改第一字节,第一字节是什么?前面已经记录下来了。

到此为止,一套使用进程回调来拦截进程的工作就完成了。

这只是个构想,不知道能否实现,准备验证一下。

原文地址:https://www.cnblogs.com/suanguade/p/4080621.html