通过回调函数阻止进程创建(验证结束,方案完全可行)
2014-11-07 10:33
274 查看
(此方案完全可行,只是我忘掉了一步)
虽然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,然后找到它的位置,修改第一字节,第一字节是什么?前面已经记录下来了。
到此为止,一套使用进程回调来拦截进程的工作就完成了。
这只是个构想,不知道能否实现,准备验证一下。
虽然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,然后找到它的位置,修改第一字节,第一字节是什么?前面已经记录下来了。
到此为止,一套使用进程回调来拦截进程的工作就完成了。
这只是个构想,不知道能否实现,准备验证一下。
相关文章推荐
- 通过fork函数创建进程的跟踪,分析linux内核进程的创建
- 演示等待通过CreateProcess创建的进程结束
- 通过fork函数创建进程的跟踪,分析linux内核进程的创建
- 通过CreateToolhelp32Snapshot函数获得系统中当前运行的进程信息2
- linux下通过dup2标准输出重定向查看系统进程方法(也是popen函数实现的方法)
- 多进程程序设计(进程的创建与结束)
- 定时计划任务方案比较以及通过脚本创建计划任务(SchTasks命令)
- 通过结束进程来关闭程序
- 通过HOOK控制进程的创建
- VC 创建和结束进程
- VC 创建和结束进程
- 通过CreateToolhelp32Snapshot函数获得系统中当前运行的进程信息
- 多进程程序设计(进程的创建与结束)
- Delphi写的等待进程运行结束函数
- VC++创建和结束进程
- 进程创建函数fork()、vfork() ,以及excel()函数
- 挂接CreateProcessW实现对进程创建的完全控制
- 挂接CreateProcessW实现对进程创建的完全控制
- 个人学习代码保存:例10.通过模板创建静态页面的操作文件的一个自定函数
- 通过Vista系统自带命令提示符结束恶意进程