- · 《农业工程技术》栏目设[05/19]
- · 《农业工程技术》收稿方[05/19]
- · 《农业工程技术》投稿方[05/19]
- · 《农业工程技术》征稿要[05/19]
- · 《农业工程技术》刊物宗[05/19]
隔壁工程师都馋哭了我的逆向工程IDA,说要给我
作者:网站采编关键词:
摘要:针对进程行为的监控需求,以往很多安全软件都是采用的Hook技术拦截关键的系统调用,来实现对恶意软件进程创建的拦截。但在x64架构下,系统内核做了很多安全检测措施,特别是类似
针对进程行为的监控需求,以往很多安全软件都是采用的Hook技术拦截关键的系统调用,来实现对恶意软件进程创建的拦截。但在x64架构下,系统内核做了很多安全检测措施,特别是类似于KDP这样的技术,使得Hook方法不再有效。为此OS推出了基于回调实现的行为监控方案。本文借助IDA逆向分析该技术的实现原理并给出了关键数据结构及调用链,通过双机内核调试验证了该数据结构以及调用链的正确性。
近年来,各种恶意软件新变种层出不穷,攻击方法、手段多种多样,造成了巨大的经济损失。作为防守的第一个环节就是能够识别出恶意进程创建的动作,而进程创建监控技术是为了能够让安全软件有机会拦截到此动作的技术。安全软件根据匹配算法判断是否准许该进程创建,以此达到保护用户数据安全的目的。
本文基于逆向工程及内核调试技术,分析了该技术的具体实现及系统额外增加的数据检测机制。借助逆向工具IDA静态逆向分析了系统关键API的内部动作及具体的实现,相关的数据结构,得到该技术实际触发的调用源以及整个调用链。借助VMWare搭建双机调试环境,利用Windbg动态调试系统内核,查看系统中所涉及到的关键数据,并与PCHunter给出的数据做对比分析,验证了分析结论的正确性。此外还通过对调用链中的关键函数下断点,通过栈回溯技术,动态观察了整个调用链及触发时间。分析得到的关键数据结构和系统对数据做的检测校验算法可用于检测病毒木马等软件恶意构造的表项。
根据微软官方技术文档MSDN上的说明,通过PsSetCreateProcessNotifyRoutine、PsSetCreateProcessNotifyRoutineEx和PsSetCreateProcessNotifyRoutineEx2这三API来安装一个进程创建、退出通知回调例程,当有进程创建或者退出时,系统会回调参数中指定的函数。以PsSetCreateProcessNotifyRoutine为例子,基于IDA逆向分析该API的具体实现。如图1所示,由图可知,该API内部仅仅是简单的调用另一个函数,其自身仅仅是一个stub,具体的实现在PspSetCreateProcessNotifyRoutine中,此函数的安装回调例程的关键实现如图所示。
调用ExAllocateCallBack,创建出了一个回调对象,并将pNotifyRoutine和bRemovel作为参数传入,以初始化该回调对象,代码如图所示;其中pNotifyRoutine即是需要被回调的函数例程,此处的bRemovel为false,表示当前是安装回调例程。
紧接着调用ExCompareExchangeCallBack将初始化好的CallBack对象添加到PspCreateProcessNotifyRoutine所维护的全局数组中。值得注意的是,ExCompareExchangeCallBack中在安装回调例程时,对回调例程有一个特殊的操作如图所示。
与0x0F做了或操作,等价于将低4位全部置1;若ExCompareExchangeCallBack执行失败,则接着下一轮循环继续执行。由图2中第66行代码可知,循环的最大次数是0x40次。如果一直失败,可调用ExFreePoolWithTag释放掉pCallBack所占用的内存,且返回0xC000000D错误码。
然后根据v3的值判断是通过上述三个API中的哪个安装的回调,来更新相应的全局变量。 其中PspCreateProcessNotifyRoutineExCount和PspCreateProcessNotifyRoutineCount分别记录当前通过PsSetCreateProcessNotifyRoutineEx和PsSetCreateProcessNotifyRoutine安装回调例程的个数。
PspNotifyEnableMask用以表征当前数组中是否安装了回调例程,该值在系统遍历回调数组执行回调例程时,用以判断数组是否为空,加快程序的执行效率。
通过一个while循环遍历PspCreateProcessNotifyRoutine数组,调用ExReferenceCallBackBlock取出数组中的每一项,该API内部会做一些检验动作且对返回的数据也做了特殊处理,如图所示。图6中*pCallBackObj即是取出回调对象中的回调例程的函数地址,通过判断其低4位是否为1来做一些数据的校验,如17行所示。
系统做这个处理也是起到保护作用,防止恶意构造数据填入表中,劫持正常的系统调用流程。此外,图中第33行处的代码,在将回调例程返回给父调用时,也将回调例程的低4位全部清零,否则返回的地址是错误的,调用立马触发CPU异常。
ExReferenceCallBackBlock成功返回后,调用ExGetCallBackBlockRoutine从返回的回调对象中取出回调例程,并判断取出的是否为当前指定需要卸载的项,如果是则调用ExDereferenceCallBackBlock递减引用计数,接着调用ExFreePoolWithTag释放掉Callback所占用的内存。期间也会更新PspCreateProcessNotifyRoutineExCount或PspCreateProcessNotifyRoutineCount的值。根据源码还可以得知,该数组总计64项,也即只能安装64个回调例程。如果遍历完数组的64项依旧没有找到,则返回0xC000007A错误码。
文章来源:《农业工程技术》 网址: http://www.gcjszzs.cn/zonghexinwen/2021/0712/2046.html