您现在的位置是:首页 > 编程 > 

CFG防护机制简单实践与介绍

2025-07-28 02:44:43
CFG防护机制简单实践与介绍 简介Control Flow Guard(CFG)是较新的windows漏洞利用缓解措施,旨在解决内存损坏漏洞。 针对的是间接跳转的保护,比如call eax,jmp eax等。 CFG扩展了先前的漏洞缓解技术,例如GS,DEP和ASLR。这个保护措施从Microsoft Visual Studio 2015及以上开始支持。系统的话是从windows 8.1开始吧简单

CFG防护机制简单实践与介绍

简介

Control Flow Guard(CFG)是较新的windows漏洞利用缓解措施,旨在解决内存损坏漏洞。 针对的是间接跳转的保护,比如call eax,jmp eax等。 CFG扩展了先前的漏洞缓解技术,例如GS,DEP和ASLR。

这个保护措施从Microsoft Visual Studio 2015及以上开始支持。

系统的话是从windows 8.1开始吧

简单来说就是在call eax等间接跳转之前加个验证。

实践

使用的示例代码

代码语言:javascript代码运行次数:0运行复制
typedef int(*fun_t)(int);

int foo(int a)
{
    printf("hellow world %d\n",a);
    return a;
}
class CTargetObject
{
public:
    fun_t fun;
};
int main()
{
    int i = 0;
    CTargetObject *o_array = new CTargetObject[5];
    for (i = 0; i < 5 ; i++)
        o_array[i].fun = foo;
    o_array[0].fun(1);  
    return 0;
}

修改编译选项

上面改了可能报错:

命令行 error D8016: “/ZI”和“/guard:cf”命令行选项不兼容

就是CFG与这个ZI不兼容,所以我们得关闭ZI

编译完成我们可以使用winchecksec工具查看是否开启了CFG

或者使用VS自带的工具,命令如下:

代码语言:javascript代码运行次数:0运行复制
 /headers /loadconfig E:\VS2017\learnCFG\Debug\

开启了CFG,OPTIOAL HEADER VALUES里面应该有Control Flow Guard

Section contains the following load config那里有“CF Instrumented”和“FID table present”等

我们看看开了CFG和没有开的区别

首先是没开的

接下来是开了的

双击跟过去那个检查函数是没有代码的,这应该是运行程序的时候再填充了

运行时,实际调用的是下面的ntdll!LdrpValidateUserCallTarget

原理分析

首先说说CFGBitmap

pCFG检查基于CFGBitmap,它表示在进程空间内所有函数的起始位置。在进程空间内每8个字节的状态对应CFGBitmap中的一位。如果函数的地址是合法有效的,那么这个函数对应在CFGbitmap的位置会被设置位1,否则是0。 p p一个Bitmap的大小是4字节

下面以地址0x00b0100为例(这是先知参考文章的例子)

具体调试结果跟解析如下了:

代码语言:javascript代码运行次数:0运行复制
ntdll!LdrpValidateUserCallTarget:
77408be0 8b15f8124a77    mov     edx,dword ptr [ntdll!LdrSystemDllInitBlock+0xb0 (774a12f8)] ds:002b:774a12f8=0070000
;获取CFGBitmap基址
77408be6 8bc1            mov     eax,ecx    ;ecx为要检验的函数地址,给到eax (ecx=00711a0)
77408be8 c1e808          shr     eax,8      ;取地址的高个字节 (eax = 0000711)
ntdll!LdrpValidateUserCallTargetBitMapCheck:
77408beb 8b1482          mov     edx,dword ptr [edx+eax*4] ds:002b:0074c44c=10100444 ;获取该地址对应的bitmap 
77408bee 8bc1            mov     eax,ecx
77408bf0 c1e80          shr     eax,                          ;舍弃最低个bit
77408bf f6c10f          test    cl,0Fh                         ;判断目标地址是否以0x10对齐,跟0xf与运算,判断是否等于 0
77408bf6 7506            jne     ntdll!LdrpValidateUserCallTargetBitMapRet+0x1 (77408bfe)   ;不等于0则跳转到77408bfe
; bt系列指令它们的结果影响CF标志位
;BT:把指定位传送给CF;
;BTC:把指定位传送给CF后还使该位变反;
;BTR:把指定位传送给CF后还使该位变为0;
;BTS:把指定位传送给CF后还使该位变为1;
77408bf8 0fac2          bt      edx,eax                        ;将edx的第eax位,给到CF(其实bt指令最多取eax的低5个bit)
;假如bt的第二个参数很大,2位取低bit,64位取低5bit,参考.htm的Description的第二段
;edx为00010000 00010000 00000100 01000100,eax的最低5bit为10100,即20,可以看到索引20位置为1,置CF为1,所以是有效的
77408bfb 70a            jae     ntdll!LdrpValidateUserCallTargetBitMapRet+0xa (77408c07) ;CF等于0才跳
ntdll!LdrpValidateUserCallTargetBitMapRet:
77408bfd c              ret                             ;正常情况下在这就返回执行正常代码了
77408bfe 0fbaf000        btr     eax,0                          ;跟0x10不对齐跳到这,将eax的最低bit给到CF,之后将最低bit置0
77408c02 0fac2          bt      edx,eax                        ;跟上面的一样,取低5bit作为edx的bit的索引,给到CF
77408c05 709            jae     ntdll!LdrpValidateUserCallTargetBitMapRet+0x1 (77408c10) ;这就跳到失败的流程了
77408c07 8c801          or      eax,1                          ;上面77408bfb判断无效后,来到这将eax最低位置1后再判断
77408c0a 0fac2          bt      edx,eax
77408c0d 701            jae     ntdll!LdrpValidateUserCallTargetBitMapRet+0x1 (77408c10) ;这就跳到失败的流程了
77408c0f c              ret
77408c10 51              push    ecx
77408c11 8d642480        lea     esp,[esp-80h]
77408c15 0f110424        movups  xmmword ptr [esp],xmm0
77408c19 0f114c2410      movups  xmmword ptr [esp+10h],xmm1
77408c1e 0f11542420      movups  xmmword ptr [esp+20h],xmm2
77408c2 0f115c240      movups  xmmword ptr [esp+0h],xmm
77408c28 0f11642440      movups  xmmword ptr [esp+40h],xmm4
77408c2d 0f116c2450      movups  xmmword ptr [esp+50h],xmm5
77408c2 0f11742460      movups  xmmword ptr [esp+60h],xmm6
77408c7 0f117c2470      movups  xmmword ptr [esp+70h],xmm7
77408cc e8e7460500      call    ntdll!RtlpHandleInvalidUserCallTarget (7745d28)
77408c41 0f100424        movups  xmm0,xmmword ptr [esp]
77408c45 0f104c2410      movups  xmm1,xmmword ptr [esp+10h]
77408c4a 0f10542420      movups  xmm2,xmmword ptr [esp+20h]
77408c4f 0f105c240      movups  xmm,xmmword ptr [esp+0h]
77408c54 0f10642440      movups  xmm4,xmmword ptr [esp+40h]
77408c59 0f106c2450      movups  xmm5,xmmword ptr [esp+50h]
77408c5e 0f10742460      movups  xmm6,xmmword ptr [esp+60h]
77408c6 0f107c2470      movups  xmm7,xmmword ptr [esp+70h]
77408c68 8da42480000000  lea     esp,[esp+80h]
77408c6f 59              pop     ecx
77408c70 c              ret

那么最终假如校验失败,那就会跳到

代码语言:javascript代码运行次数:0运行复制
77408cc e8e7460500      call    ntdll!RtlpHandleInvalidUserCallTarget (7745d28)

最终int 0x29抛出异常

参考

/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2019-10-28,如有侵权请联系 cloudcommunity@tencent 删除漏洞命令行实践索引函数

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1207297.html

相关标签:无
上传时间: 2025-07-24 13:14:15
留言与评论(共有 15 条评论)
本站网友 成都到上海
5分钟前 发表
参考.htm的Description的第二段 ;edx为00010000 00010000 00000100 01000100
本站网友 自动识别
5分钟前 发表
77408be0 8b15f8124a77 mov edx
本站网友 怎样快速去除眼袋
27分钟前 发表
这个保护措施从Microsoft Visual Studio 2015及以上开始支持
本站网友 泡脚的好处
27分钟前 发表
把指定位传送给CF后还使该位变为0; ;BTS
本站网友 黄小玲
13分钟前 发表
xmmword ptr [esp+70h] 77408c68 8da42480000000 lea esp
本站网友 中兴校招
12分钟前 发表
774a12f8=0070000 ;获取CFGBitmap基址 77408be6 8bc1 mov eax
本站网友 爱搞机
10分钟前 发表
比如call eax
本站网友 精神分裂症治疗
4分钟前 发表
xmmword ptr [esp] 77408c45 0f104c2410 movups xmm1
本站网友 吉林省工程技术学校
26分钟前 发表
CFG防护机制简单实践与介绍 简介Control Flow Guard(CFG)是较新的windows漏洞利用缓解措施
本站网友 徐东二手房网
17分钟前 发表
xmm1 77408c1e 0f11542420 movups xmmword ptr [esp+20h]
本站网友 电波除皱
21分钟前 发表
xmmword ptr [esp+20h] 77408c4f 0f105c240 movups xmm
本站网友 秀水街营业时间
16分钟前 发表
如有侵权请联系 cloudcommunity@tencent 删除前往查看漏洞命令行实践索引函数
本站网友 转向
20分钟前 发表
002b
本站网友 onmouseover
12分钟前 发表
eax的最低5bit为10100