日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

CFG——ControlFlowGuard 控制流保护

發布時間:2024/1/3 综合教程 46 生活家
生活随笔 收集整理的這篇文章主要介紹了 CFG——ControlFlowGuard 控制流保护 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CFG防護機制的簡要分析 - 先知社區 (aliyun.com)

Exploring Control Flow Guard in Windows 10 (trendmicro.com)

本文主要來自上面兩篇文章,自己做一個記錄罷了。

CFG 通過在間接跳轉(Indirect Call)前插入校驗代碼(比如 call dword ptr ss:[ebp-8] 等等 ),檢查目標地址的有效性,進而可以阻止執行流跳轉到預期之外的地點, 最終及時并有效的進行異常處理,避免引發相關的安全問題。

CFG 的實現需要聯合編譯器、操作系統用戶層庫和內核模塊,它是一個匯編層面的保護。

首先,一個正常的函數地址(x86)的前24位會被取出,作為一個偏移值(OFFSET)。CFGBitMapBase + OFFSET*4 地址中存儲著一個計算值(每4字節作為) ,_guard_check_icall_fptr 函數會對傳入的參數進行計算,然后與存儲著的計算值進行比較:

① 最后一字節的最后4位全為0,則取最后一字節的前5位作為一個偏移值,若對應的存儲值(從0開始數)的對應位是1,則函數地址有效。

② (windows 10 pro 2018年)最后一字節的最后4位不全為0,則取最后一字節的前5位作為一個偏移值。若對應的存儲值(從0開始數)的對應位是1,則函數地址有效并返回;

Win 10 1909(OS內部版本18363.1198) 中,最后一字節的最后4位不全為0,則取最后一字節的前5位并將這5位的最后一位置0,再作為一個偏移值。若對應的存儲值(從0開始數)的對應位是1,則執行下一步

③ 若前兩個都不滿足,或第二個滿足,則將前5位的最后一位置1,作為一個偏移值。若對應的存儲值(從0開始數)的對應的位是1,則函數地址有效。否則判定無效,并進行異常處理。

借助上面提到的文章,自己添加了一些函數進去,對編譯的程序進行調試:

因為是用 C++ 寫的,使用的是 __cdecl (C 規范的) 調用約定,參數從右到左入棧,由調用者負責清除棧。

可以看到 _guard_check_icall_fptr 程序實際調用了 ValidateUserCallTarget 函數

系統:Windows 10 1909   編譯器:VS 2019 win32 release版

mov edx,dword ptr ds:[77D112F8] // 獲得 CFGBitMapBase 地址 mov eax,ecx              // ecx = 要調用的函數地址 shr eax,8               // 取函數地址的前24位作為 OFFSET mov edx,dword ptr ds:[edx+eax*4] // 到 CFGBitMapBase+OFFSET*4 取值 mov eax,ecx              shr eax,3               // eax 右移三位 test cl,F               // 函數地址的最后4位是否全為0
jne ntdll.77C79DBE         // 不全為0則跳轉到后面執行 bt edx,eax              // Bit Test 指令,第一個操作數(edx)是寄存器且
                    // eax > 32時,將會對 eax = eax mod 32 (AX 時模數是16)
                    // 然后再取 edx 相對應的位的值放入 CF 中
                    // 因為右移了3位,最后一字節前5位能表示的最大值是31,
                    // 因此其實取余后的值也還是由最后一字節的前5位表示

jae ntdll.77C79DC7         // 若edx對應的位是0,則跳轉,否則正常返回 ret
77C79DBE
btr eax,0               // 取 eax 最后一位,放入 CF 并將 eax 最后一位置 0 bt edx,eax              // 取 edx 對應的位放入 CF,與前面原理相同 jae ntdll.77C79DD0         // 若 CF == 0,則進入異常處理
77C79DC7
or eax,1               // 將 eax 最后一位置 1 bt edx,eax              // 取對應位 jae ntdll.77C79DD0 ret

77C79DD0:              // 異常處理 push ecx lea esp,dword ptr ss:[esp-80] movups xmmword ptr ss:[esp],xmm0 movups xmmword ptr ss:[esp+10],xmm1 movups xmmword ptr ss:[esp+20],xmm2 movups xmmword ptr ss:[esp+30],xmm3 movups xmmword ptr ss:[esp+40],xmm4 movups xmmword ptr ss:[esp+50],xmm5 movups xmmword ptr ss:[esp+60],xmm6 movups xmmword ptr ss:[esp+70],xmm7 call <ntdll.@RtlpHandleInvalidUserCallTarget@4> movups xmm0,xmmword ptr ss:[esp] movups xmm1,xmmword ptr ss:[esp+10] movups xmm2,xmmword ptr ss:[esp+20] movups xmm3,xmmword ptr ss:[esp+30] movups xmm4,xmmword ptr ss:[esp+40] movups xmm5,xmmword ptr ss:[esp+50] movups xmm6,xmmword ptr ss:[esp+60] movups xmm7,xmmword ptr ss:[esp+70] lea esp,dword ptr ss:[esp+80] pop ecx ret

同時,若在編譯過程中不開啟 ASLR ,則自己編寫的函數的 CFGBitMap 值會是 FFFFFFFF,而系統函數的值則不會是

使用不同的運行庫也會導致某些函數的 CFGBitMap 值為 FFFFFFFF,猜測如下:如果代碼寫死在程序中,不需要調用外部 DLL 庫中的文件,則值為 FFFFFFFF,如果需要調用外部 DLL 庫中的文件,則值不為全 F。

總結

以上是生活随笔為你收集整理的CFG——ControlFlowGuard 控制流保护的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。