• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Error

            C++博客 首頁 新隨筆 聯系 聚合 管理
              217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks

            // 本質上來說就是自己設置了UnhandleExceptionFilter后,C運行庫或者其他什么別的函數也調用了,所以自己設置的就無效了,解決方案就是HOOK SET函數,讓別人無法取代自己

            很多 C/C++ 程序會設置自己的 Unhandled Exception Filter 用于捕獲 Unhandled exceptions 并輸出一些信息(例如,創建 mini-dump 或者輸出調用棧到日志文件中)。

            從 VC++2005 開始出于安全因素微軟改變了 CRT 的行為。在以下情況下 CRT 不會通知被注冊的 Unhandled Exception Filter:

            1. 調用了 abort() 并且設置 abort 的行為為 _CALL_REPORTFAULT(Release 版本默認使用此設置)
            2. Security Checks 失敗時,具體來說就是檢查到一些會引發安全問題的堆棧溢出時不會通知被注冊的 Unhandled Exception Filter,會引發安全問題的堆棧溢出包括:覆蓋了函數的返回值,覆蓋了 Exception handler 的地址,覆蓋了某些類型的參數。關于編譯器的 Security Checks 的內容,詳細參考:http://msdn.microsoft.com/en-us/library/Aa290051(注意,此文章談到的是 Visual Studio .NET 2003,其中 _set_security_error_handler 函數在 VC++2005 以及以上版本已經無法使用)
            3. 如果沒有調用 _set_invalid_parameter_handler 設置 Invalid parameter handler 時,檢查到了非法的參數

            CRT 是通過何種方式使得我們注冊的 Unhandled Exception Filter 不被調用的?答案在 CRT 的代碼中:

            1. /* 代碼來源于 gs_report.c */
            2. /* Make sure any filter already in place is deleted. */
            3. SetUnhandledExceptionFilter(NULL);
            4. UnhandledExceptionFilter(&ExceptionPointers);

            CRT 通過調用 SetUnhandledExceptionFilter 并傳遞參數 NULL 來清除用戶注冊的 Unhandled Exception Filter。如果期望用戶注冊的 Unhandled Exception Filter 總是被調用那么應該避免 CRT 中相關的清理代碼。做法之一就是修改 CRT 代碼并且編譯為靜態庫(微軟的 VC++ Libraries 開發 Lead Martyn Lovell 在 https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=101337&SiteID=210 談到過有關的問題),這里并不建議使用此做法。另外一種做法則是改變 SetUnhandledExceptionFilter 的行為,使得 CRT 對 SetUnhandledExceptionFilter 的調用不起任何作用(更加詳細的論述可以參考《Windows 核心編程》相關章節)。

            1. // 無法得知此代碼來源于
            2. #ifndef _M_IX86
            3. #error "The following code only works for x86!"
            4. #endif
            5.  
            6. // 此函數一旦成功調用,之后對 SetUnhandledExceptionFilter 的調用將無效
            7. void DisableSetUnhandledExceptionFilter()
            8. {
            9. void* addr = (void*)GetProcAddress(LoadLibrary("kernel32.dll"),
            10. "SetUnhandledExceptionFilter");
            11.  
            12. if (addr)
            13. {
            14. unsigned char code[16];
            15. int size = 0;
            16.  
            17. code[size++] = 0x33;
            18. code[size++] = 0xC0;
            19. code[size++] = 0xC2;
            20. code[size++] = 0x04;
            21. code[size++] = 0x00;
            22.  
            23. DWORD dwOldFlag, dwTempFlag;
            24. VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);
            25. WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
            26. VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);
            27. }
            28. }

            只需要在注冊 Unhandled Exception Filter 之后調用 DisableSetUnhandledExceptionFilter() 函數,那么之后所有對 SetUnhandledExceptionFilter 的調用都將無效,自然 CRT 也無法通過調用 SetUnhandledExceptionFilter 來清除用戶注冊的 Unhandled Exception Filter。

            posted on 2015-05-15 02:17 Enic 閱讀(2643) 評論(0)  編輯 收藏 引用 所屬分類: 從零開始寫棋牌游戲平臺
            九九久久自然熟的香蕉图片| 久久激情亚洲精品无码?V| 久久久久青草线蕉综合超碰| 中文精品久久久久人妻不卡| 69SEX久久精品国产麻豆| 7国产欧美日韩综合天堂中文久久久久 | 亚洲欧美日韩精品久久亚洲区 | 久久笫一福利免费导航 | 无码人妻久久一区二区三区蜜桃| 波多野结衣久久精品| 久久99热精品| 亚洲精品蜜桃久久久久久| 亚洲午夜久久影院| 久久久久se色偷偷亚洲精品av| 久久99国产综合精品免费| 99久久免费国产精品| 久久精品日日躁夜夜躁欧美| 亚洲国产精品人久久| 亚洲AV日韩AV天堂久久| 久久久久人妻一区精品果冻| 久久国产乱子伦免费精品| 久久久精品国产Sm最大网站| 99麻豆久久久国产精品免费| 色8激情欧美成人久久综合电| 久久久久亚洲av无码专区| 一级女性全黄久久生活片免费| 国产亚洲欧美成人久久片| 少妇高潮惨叫久久久久久| 亚洲欧美一级久久精品| 18岁日韩内射颜射午夜久久成人| 精品国产VA久久久久久久冰| 亚洲综合熟女久久久30p| 一本久久a久久精品综合香蕉| 久久精品无码一区二区三区日韩| 久久精品无码一区二区三区| 69久久夜色精品国产69| 97久久久久人妻精品专区| 欧美黑人又粗又大久久久| 午夜久久久久久禁播电影| 午夜天堂av天堂久久久| 久久大香香蕉国产|