patchless amsi学习(下)

发布时间:2023年12月19日

patchless amsi

代码参考:https://gist.github.com/CCob/fe3b63d80890fafeca982f76c8a3efdf

解读代码可以从函数入口开始

setupAMSIBypass这个函数前面主要是获取amsiScanBuffer的地址,随即注册了一个veh异常。

然后通过调用GetThreadContext获取到了当前线程的context,这里作者用了一个小技巧:用(HANDLE)-2代替了GetCurrentThread()

然后调用enableBreakpoint下了一个硬件断点,这里我们先跟进这个函数。

这个函数最后一个参数实际上就是选择用哪个调试寄存器(DR0-3)做断点

setBits可以设置Dr7的一些位数控制Dr0-3的属性。

比如这里是将DR0-DR3的触发条件为执行,并且将DRx的触发设置为当前模式,也就是仅对当前线程有效。

enableBreakpoint(threadCtx, g_amsiScanBufferPtr, 0);

enableBreakpoint传递的参数是amsiScanBuffer的地址,当前线程和DR0,那么当执行amsiScanBuffer函数时,就会触发硬件断点。产生一个EXCEPTION_SINGLE_STEP异常。

我们注册的veh函数将会第一个进行处理

首先确定了是该异常,并且该异常产生的地址为amsiScanBuffer的地址。

returnAddress首先是拿到了amsiScanBuffer执行结束后的返回地址,也就是触发断点时刻的rsp。

scanResult是对amsiScanBuffer的第六个参数进行赋值。

Syntax

通过x64调用约定来看result此时应该在栈中的rsp+0x30的位置,他这里getArg的index参数传的5,是一样的

然后将此值清0。

然后将rip直接指回了返回地址,此时若是继续执行相当于直接跳过了amsiScanBuffer,但是这里堆栈肯定是不平衡的,由于是call进去的,所以这里相当于要pop一下,堆栈下移,rsp+8,这时adjustStackPointer函数做的事情。

堆栈也平衡了,将rax(返回值)也改为0

总结

此方式通过进程执行amsiScanBuffer的时候,动态更改amsiScanBuffer的返回结果和第六个参数来控制返回结果。

文章来源:https://blog.csdn.net/2301_80520893/article/details/134944315
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。