gflags调试访问越界
2011-9-27
燭秋
?
昨天、今天調dump,對windbg相當的不熟悉,但也慢慢的知道了一些常用的命令,幾周前聽說到有gflags這樣個工具,今天正好測試下。
?
gflags.exe是<Debugging Tools for Windows>中的一個小工具。
安裝下載鏈接:http://msdn.microsoft.com/en-us/windows/hardware/gg463016
?
安裝好之后,把gflags所在文件夾(這里邊還有很多好東西)設置到環境變量的path中,方便命令行使用。(我的電腦-->右鍵-->屬性-->高級-->環境變量-->系統變量-->path)
?
在命令行cmd里輸入:cdb -iae 。
設置cdb為默認JIT(just in time) debugger,這樣在命令行執行遇到崩潰的時候就會停下來。
?
(本文最后的學習資料相當好)
?
?
測試程序:///int main(){char *p = new char[10];for(int i = 0; i != 11; ++i) p[i] = i;return 0;}///?
?這是一個非常簡單的越界程序,當i = 10時,訪問越界了。但是如果不采用測試工具,這里是不會發生崩潰的。一般情況下,程序獲取的空間是16字節對齊的,所以p[10]訪問到的是對齊之后增加的空間,不會導致越界崩潰。但這是隱患,為了使隱患盡早被發現,使用工具是很好的選擇。
gflags用來跟蹤這個程序的執行,可以設置每一次new分配的堆空間都單獨的占有一塊空間,并且這個空間相鄰的位置被設置為不可訪問的,一旦訪問越界立即觸發訪問無效錯誤,盡早的觸發崩潰。
測試過程如下:
1、用vc編譯出release版本的可執行文件:test.exe。(注意:不是debug版本)
2、用gflag注冊需要監控的可執行文件test.exe。
在cmd下,輸入命令如下:gflags /p /enable test.exe /full /unaligned。
回車,顯示如下信息:
*************************************************************************************
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
??test.exe: page heap enabled。
*************************************************************************************
這個時候,已經把要監控的test.exe注冊上了。
?
/p /enable是必備的。
/full說明分配的空間是獨占的,并且相鄰的是不可訪問的空間。
/unaligned說明分配空間時不對齊,保證一旦越界立即發現,不會因為內存對齊而隱藏起來。
3、接著雙擊執行test.exe,這個時候,會中斷下來:
*************************************************************************************
(17f8.5d0): Access violation - code c0000005 (!!! second chance !!!)
eax=0161eff6 ebx=7c80ac61 ecx=0000000a edx=015c5000 esi=00000002 edi=00000a28
eip=00401010 esp=0012ff74 ebp=0012ffc0 iopl=0 ? ? ? ? nv up ei ng nz ac pe cy
cs=001b ?ss=0023 ?ds=0023 ?es=0023 ?fs=003b ?gs=0000 ? ? ? ? ? ? efl=00000297
WindbgTest!main+0x10:
00401010 880c01 ? ? ? ? ?mov ? ? byte ptr [ecx+eax],cl ? ? ?ds:0023:0161f000=??
*************************************************************************************
如果把exe放到windbg里執行,用命令:!address,可以發現eax是可以讀寫的,
eax+ecx是不可訪問的:
*************************************************************************************
0:000>?!address eax
?? ?015c0000 : 0161e000 - 00001000
?? ?Type ? ? 00020000 MEM_PRIVATE
?? ?Protect ?00000004 PAGE_READWRITE
?? ?State ? ?00001000 MEM_COMMIT
?? ?Usage ? ?RegionUsagePageHeap
?? ?Handle ? 015c1000
0:000>?!address eax+ecx
?? ?015c0000 : 0161f000 - 000a1000
?? ?Type ? ? 00020000 MEM_PRIVATE
?? ?Protect ?00000001 PAGE_NOACCESS
?? ?State ? ?00001000 MEM_COMMIT
?? ?Usage ? ?RegionUsagePageHeap
?? ?Handle ? 015c1000
*************************************************************************************
4、取消跟蹤:
通過/p命令可以看到當前跟蹤的程序有哪些:
*************************************************************************************
C:\Documents and Settings\cs_wuyg>gflags /p
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
?? ?player.exe: page heap enabled with flags (full traces )
?? ?program: page heap enabled with flags (full unaligned traces )
?? ?test.exe: page heap enabled with flags (full unaligned traces )
?? ?windbgtest.exe: page heap enabled with flags (full unaligned traces )
*************************************************************************************
通過/p /disble取消跟蹤:情況如下:
*************************************************************************************
C:\Documents and Settings\cs_wuyg>gflags /p /disable player.exe
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
?? ?player.exe: page heap disabled
?
C:\Documents and Settings\cs_wuyg>gflags /p
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
?? ?program: page heap enabled with flags (full unaligned traces )
?? ?test.exe: page heap enabled with flags (full unaligned traces )
?? ?windbgtest.exe: page heap enabled with flags (full unaligned traces )
*************************************************************************************
?? 發現program是無法取消的,很奇怪。另外,發現注冊表里相應的項目在disable之后,仍然存在,只不過一些鍵值被刪除掉了。
?? 同事跟我說,不使用gflags的時候,最好把注冊表里的項目刪除,gflags對機器性能的影響很大。
?? 注冊表的位置是:HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/WindowsNT/Image File Execution Options
?
5、注意事項
一、gflags要跟蹤的程序,是把這個程序的名稱記錄到了注冊表中,在設置的時候不需要可執行文件的路徑名,只需要文件名稱。
二、可以使用命令行,也可以使用GUI界面。GUI界面中的前兩個TAB頁面是對所有的可執行程序都有效的。第三個才是設置想要跟蹤的程序。
三、還有其它更強大的工具。
6、總結
通過這個工具的簡單使用,就可以很快發現代碼中有訪問越界。
??在大工程下,是否也非常有用,現在還沒實踐過。
使用gflags,并且在VS下調試,有源代碼更方便。
?
?
?
?
?
?
?
?
?
7、附今天用上的幾個windbg命令:
1\ !analyze -v
2\ kv ? kf ? ?kb
3\ ~*k
4\ .ecxr
5\ lmvm xxx.exe?? ? ? ??
?
分析dump的時候,看調用堆棧是從下往上看的。
調用堆棧前部分的數值一部分是參數,一部分是無用的信息。
設置好source file path之后,.ecxr命令可以看到當前的寄存器信息,還可以看到源代碼。
?
發現很多的崩潰是由于空指針、野指針導致的。而空指針、野指針是由于多線程導致卸載、裝載重疊導致的。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
學習資料:
http://www.cppblog.com/sandy/archive/2007/03/13/19723.html
http://blog.csdn.net/ayw_hehe/article/details/6796333
http://www.cppblog.com/sandy/archive/2008/09/27/62877.html
http://www.cnblogs.com/awpatp/archive/2011/01/01/1923913.html
http://blog.sina.com.cn/s/blog_484f16880100jrwj.html
?
總結
以上是生活随笔為你收集整理的gflags调试访问越界的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软考(5)--软件工程
- 下一篇: Processing--鼠标响应(1)