算是对http://www.uninformed.org/?v=6&a=1&t=sumry 的一个中文摘要,理解还不一定全对
PG2一些改动:
cmp cs:KdDebuggerNotPresent, r12b
jnz short continue_initialization_1
infinite_loop_1:
jmp short infinite_loop_1
sti
更改KdDebuggerNotPresent比较容易,索性直接死循环掉
dr7清零
初始化完毕之后会把这些初始化代码清零
此外不变的是对于自己的数据还是使用了随即内存大小、pool tag,随即密钥等等加密。利用DPC来触发异常,不过可供选择的DPC增加到了十个。
方法一
1.patch guard2也是利用DPC执行一次检查,这些DPC routine都是正常dpc历程,但是传入的DPC context并不是一个有效指针。
所以会转到异常处理_C_specific_handler,patchguard检测函数将在这个异常里无限循环检测patch
bypass的话就可以hook _C_specific_handler这个导出函数
hook之后怎么正常返回到dpc routine的调用位置继续执行是个问题
x86的话会比较麻烦,利用X64的seh表是轻而易举的,调用RtlVirtualUnwind即可
2.这个hook只执行一次,定时器只触发一次,然后就走到异常处理之后无限循环检查
3.接下来的问题是如何过滤异常时有patchguard故意抛出的
内核代码经常会probe一些地址,这有可能引发常规的access violation,但一般probe的都是环3地址,PatchGuard则例外
PG则是引用了non-canonical addresses,处理器抛出这个异常的时候他的exception handler总是-1。
一些写的不规范的驱动可能也会出发这个异常,作者认为可以无视,我想判断也很容易吧,反正有上下文。
方法二
修改所有可能用到的DPC的异常处理注册函数
这需要定位是哪些DPC
DPC该有如下特征
1. Each DPC routine has one exception/unwind-marked registration
PG2一些改动:
cmp cs:KdDebuggerNotPresent, r12b
jnz short continue_initialization_1
infinite_loop_1:
jmp short infinite_loop_1
sti
更改KdDebuggerNotPresent比较容易,索性直接死循环掉
dr7清零
初始化完毕之后会把这些初始化代码清零
此外不变的是对于自己的数据还是使用了随即内存大小、pool tag,随即密钥等等加密。利用DPC来触发异常,不过可供选择的DPC增加到了十个。
方法一
1.patch guard2也是利用DPC执行一次检查,这些DPC routine都是正常dpc历程,但是传入的DPC context并不是一个有效指针。
所以会转到异常处理_C_specific_handler,patchguard检测函数将在这个异常里无限循环检测patch
bypass的话就可以hook _C_specific_handler这个导出函数
hook之后怎么正常返回到dpc routine的调用位置继续执行是个问题
x86的话会比较麻烦,利用X64的seh表是轻而易举的,调用RtlVirtualUnwind即可
2.这个hook只执行一次,定时器只触发一次,然后就走到异常处理之后无限循环检查
3.接下来的问题是如何过滤异常时有patchguard故意抛出的
内核代码经常会probe一些地址,这有可能引发常规的access violation,但一般probe的都是环3地址,PatchGuard则例外
PG则是引用了non-canonical addresses,处理器抛出这个异常的时候他的exception handler总是-1。
一些写的不规范的驱动可能也会出发这个异常,作者认为可以无视,我想判断也很容易吧,反正有上下文。
方法二
修改所有可能用到的DPC的异常处理注册函数
这需要定位是哪些DPC
DPC该有如下特征
1. Each DPC routine has one exception/unwind-marked registration