• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉(zhuǎn),開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            在內(nèi)核調(diào)試會話中設置用戶態(tài)斷點

            使用內(nèi)核調(diào)試會話也可以執(zhí)行一些用戶態(tài)調(diào)試任務,比如向位于用戶態(tài)的模塊設置斷點。但這樣做與使用用戶態(tài)調(diào)試器有什么不同呢?我們就以向NTDLL.dll模塊的ZwTerminateProcess函數(shù)(Stub)為例談談二者的區(qū)別。

            區(qū)別一、在內(nèi)核調(diào)試會話中設置這個斷點的“難度”略大些。這是因為NTDLL不屬于內(nèi)核態(tài)的模塊,所以內(nèi)核會話通常不會加載這個模塊(的符號),因此當執(zhí)行bp命令時很可能被自動蛻化為bu命令。

            0:?kd>?bp?ntdll!ZwTerminateProcess
            Bp?expression?'ntdll!ZwTerminateProcess'?could?not?be?resolved,?adding?deferred?bp

            恢復執(zhí)行后,一般的操作也不會觸發(fā)調(diào)試器來加載NTDLL模塊和解決這個未決的斷點。因此再中斷下來,重新加載符號也可能沒有用:

            2:?kd>?.reload
            Connected?to?Windows?Vista?6000?x86?compatible?target,?ptr64?FALSE
            Loading?Kernel?Symbols
            .............................................................................................................................
            Loading?User?Symbols

            Loading?unloaded?module?list
            ........
            2:?kd>?bl
            ?0?eu?????????????0001?(0001)?(ntdll!ZwTerminateProcess)

            使用.reload命令強制加載這個模塊也不那么容易:

            0:?kd>?.reload?/s?/f?ntdll.dll

            "ntdll.dll"?was?not?found?in?the?image?list.
            Debugger?will?attempt?to?load?"ntdll.dll"?at?given?base?00000000.

            Please?provide?the?full?image?name,?including?the?extension?(i.e.?kernel32.dll)
            for?more?reliable?results.Base?address?and?size?overrides?can?be?given?as
            .reload?<image.ext>=<base>,<size>.
            Unable?to?add?module?at?00000000

            那么該如何設置呢?方法一需要以下幾步:

            1.A?使用!process命令顯示當前進程:

            kd>?!process
            PROCESS?80af22a0??SessionId:?none??Cid:?0000????Peb:?00000000??ParentCid:?0000
            ????DirBase:?00039000??ObjectTable:?e1001e38??HandleCount:?240.
            ????Image:?Idle

            如果像上面這樣是IDLE進程或者是System這些沒有用戶態(tài)的進程,那么就需要執(zhí)行下面一步,否則跳到1.C。

            1.B?使用!process?0?0命令列出所有進程,然后選一個普通的Windows進程,并切換到這個進程:

            kd>?!process?0?0?
            ****?NT?ACTIVE?PROCESS?DUMP?****

            ...
            PROCESS?82748330??SessionId:?0??Cid:?0110????Peb:?7ffde000??ParentCid:?059c
            ????DirBase:?13076000??ObjectTable:?e1a55640??HandleCount:??72.
            ????Image:?notepad.exe

            kd>?.PROCESS?82748330
            Implicit?process?is?now?82748330
            WARNING:?.cache?forcedecodeuser?is?not?enabled

            1.C?執(zhí)行.reload或.reload?/user重新加載符號:

            kd>?.reload
            Connected?to?Windows?XP?2600?x86?compatible?target,?ptr64?FALSE
            Loading?Kernel?Symbols
            ................................................................................................
            Loading?User?Symbols
            ...............................
            Loading?unloaded?module?list
            ..............................
            kd>?lm?m?ntdll
            start????end????????module?name
            7c800000?7c8c3000???ntdll??????(pdb?symbols)??????????d:\symbols\ntdll.pdb\9A2A73EBE8194059A14361915257B0B01\ntdll.pdb

            第二種看起來可能更費事的方法就是在系統(tǒng)服務的內(nèi)核函數(shù)設置斷點,斷點命中后,執(zhí)行棧回溯這樣的命令,再執(zhí)行.reload(加/user會省些時間,不是必須)。例如:

            0:?kd>?bp?nt!NtTerminateProcess
            0:?kd>?g

            Breakpoint?2?hit
            nt!NtTerminateProcess:
            81a1b043?8bff????????????mov?????edi,edi
            0:?kd>?kv
            ChildEBP?RetAddr??Args?to?Child??????????????
            9f272d54?8188c96a?00000000?00000000?0021f998?nt!NtTerminateProcess
            9f272d54?77c20f34?00000000?00000000?0021f998?nt!KiFastCallEntry+0x12a?(FPO:?[0,3]?TrapFrame?@?9f272d64)
            WARNING:?Frame?IP?not?in?any?known?module.?Following?frames?may?be?wrong.
            0021f998?7682d873?00000000?77e8f3b0?ffffffff?0x77c20f34
            ...

            0:?kd>?.reload
            Connected?to?Windows?Vista?6000?x86?compatible?target,?ptr64?FALSE
            Loading?Kernel?Symbols
            ..............................................................................................................................
            Loading?User?Symbols
            ..................

            再執(zhí)行kv:
            0:?kd>?kv
            ChildEBP?RetAddr??Args?to?Child??????????????
            9f272d54?8188c96a?00000000?00000000?0021f998?nt!NtTerminateProcess
            9f272d54?77c20f34?00000000?00000000?0021f998?nt!KiFastCallEntry+0x12a?(FPO:?[0,3]?TrapFrame?@?9f272d64)
            0021f978?77c20580?77bfa35f?00000000?00000000?ntdll!KiFastSystemCallRet?(FPO:?[0,0,0])
            0021f97c?77bfa35f?00000000?00000000?00af0e70?ntdll!NtTerminateProcess+0xc?(FPO:?[2,0,0])
            0021f998?7682d872?00000000?77e8f3b0?ffffffff?ntdll!RtlExitUserProcess+0x39?(FPO:?[Non-Fpo])

            此時可以確信內(nèi)核調(diào)試會話已經(jīng)加載NTDLL的符號了,再顯示斷點:

            0:?kd>?bl
            ?0?e?77c20574?????0001?(0001)?ntdll!NtTerminateProcess
            ?2?e?81a1b043?????0001?(0001)?nt!NtTerminateProcess

            這個顯示表明內(nèi)核調(diào)試會話已經(jīng)落實了這個用戶態(tài)的斷點。

            如果是在加載NTDLL模塊后再執(zhí)行bp命令,恢復執(zhí)行后,KD會有一個提示告訴我們它成功的向斷點位置寫入了INT?3。

            0:?kd>?bp?ntdll!ZwTerminateProcess
            0:?kd>?bl
            ?0?e?77c20574??0001?(0001)?ntdll!NtTerminateProcess

            0:?kd>?g
            KD:?write?to?77c20574??ok

            相對而言,如果是在用戶態(tài)調(diào)試會話中,因為NTDLL會被映射到所有用戶態(tài)進程中,而且ZwTerminateProcess是導出的函數(shù),所以bp?ntdll!ZwTerminateProcess會非常順利的執(zhí)行。

            區(qū)別二、斷點的作用范圍不同,在內(nèi)核調(diào)試會話中設置的ntdll!NtTerminateProcess斷點會影響所有進程(可能有特例),而在用戶態(tài)調(diào)試中對這個位置設置的斷點只對當前進程有效。舉例來說,剛才在內(nèi)核調(diào)試會話中設置bp斷點時的當前進程是notepad,但是當我們關(guān)閉計算器進程時這個斷點也會命中。甚至當我們新啟動一個WinMine程序,然后關(guān)閉它時,斷點也會命中。

            相對而言,如果是在調(diào)試notepad進程的用戶態(tài)調(diào)試會話中對ntdll!NtTerminateProcess設置一個斷點,那么這絕不會影響其它進程。

            那么為什么有這個差異呢?

            首先解釋一下,為什么在內(nèi)核調(diào)試會話中設置的斷點會影響所有進程。還是通過試驗來說明,我們先想辦法觀察到我們設置的斷點所對應的INT?3指令。當KD落實我們的斷點后,將目標再中斷到調(diào)試器,這時無論是直接觀察線性地址還是物理地址,都看不到INT?3:

            1:?kd>?dd?77c20574
            77c20574??000152cc?0300ba00?12ff7ffe?900008c2
            77c20584??000153b8?0300ba00?12ff7ffe?900008c2
            77c20594??000154b8?0300ba00?12ff7ffe?00498dc3
            77c205a4??000155b8?0300ba00?12ff7ffe?00498dc3
            77c205b4??000156b8?0300ba00?12ff7ffe?00498dc3
            77c205c4??000157b8?0300ba00?12ff7ffe?900010c2
            77c205d4??000158b8?0300ba00?12ff7ffe?900018c2
            77c205e4??000159b8?0300ba00?12ff7ffe?900010c2

            0:?kd>?!pte?77c20574?????
            ???????????????VA?77c20574
            PDE?at?00000000C0601DF0????PTE?at?00000000C03BE100
            contains?000000001C9AC867??contains?000000001DDDD025
            pfn?1c9ac?---DA--UWEV????pfn?1dddd?----A--UREV

            0:?kd>?!dd?1dddd574?
            #1dddd574?000152b8?0300ba00?12ff7ffe?900008c2
            #1dddd584?000153b8?0300ba00?12ff7ffe?900008c2
            #1dddd594?000154b8?0300ba00?12ff7ffe?00498dc3
            #1dddd5a4?000155b8?0300ba00?12ff7ffe?00498dc3
            #1dddd5b4?000156b8?0300ba00?12ff7ffe?00498dc3
            #1dddd5c4?000157b8?0300ba00?12ff7ffe?900010c2
            #1dddd5d4?000158b8?0300ba00?12ff7ffe?900018c2
            #1dddd5e4?000159b8?0300ba00?12ff7ffe?900010c2

            這是因為調(diào)試器在將目標中斷到調(diào)試器之前會恢復已經(jīng)設置的斷點,按Ctrl+Alt+D啟用WinDBG與KD的通信過程后就可以看到這樣的信息:

            DbgKdRestoreBreakPoint(1)?returns?00000000

            當恢復執(zhí)行時,WinDBG會重新把斷點寫入:

            DbgKdWriteBreakPoint(77c20574)?returns?00000000,?1


            那么如何觀察到寫入的INT?3呢?一種很愜意的方法就是使用ITP這樣的硬件調(diào)試器,用了ITP,對付這樣的任務真是手到擒來(圖1)。

            http://advdbg.com/img/inset/bp_at_ntdll.bmp

            圖1?使用硬件調(diào)試器觀察斷點指令(0xCC)

            因為NTDLL是映射到所有進程中的,所以每個進程執(zhí)行NtTerminateProcess函數(shù)時都會撞見這個0xCC,于是乎這個斷點對所有進程都起作用也就在情理之中了。

            下面再說說另一種情況,也就是在用戶態(tài)調(diào)試器中對ntdll!NtTerminateProcess設置斷點,難道這時就沒有把0xCC寫在大家都會“撞見”的地方么?的確如此。

            我們在內(nèi)核調(diào)試會話中使用bc?*命令清除所有斷點,并恢復執(zhí)行一次,而且通過ITP觀察確保剛才的0xcc已經(jīng)不在。然后在目標系統(tǒng)中啟動系統(tǒng)中自帶的 NTSD來調(diào)試計算器程序,并使用bp?ntdll!NtTerminateProcess設置一個斷點。恢復執(zhí)行一次,以便讓調(diào)試器寫入這個斷點。然后退出計算器程序,這時計算器程序會中斷到NTSD,NTSD中不做分析,直接用g命令恢復執(zhí)行,這下,我們前面設置的nt! NtTerminateProcess斷點會命中,也就是中斷到內(nèi)核調(diào)試器中。

            在內(nèi)核調(diào)試器中,觀察nt!NtTerminateProcess所對應的線性地址:

            1:?kd>?dd?77c20574
            77c20574??000152cc?0300ba00?12ff7ffe?900008c2
            77c20584??000153b8?0300ba00?12ff7ffe?900008c2
            77c20594??000154b8?0300ba00?12ff7ffe?00498dc3
            77c205a4??000155b8?0300ba00?12ff7ffe?00498dc3
            77c205b4??000156b8?0300ba00?12ff7ffe?00498dc3
            77c205c4??000157b8?0300ba00?12ff7ffe?900010c2
            77c205d4??000158b8?0300ba00?12ff7ffe?900018c2
            77c205e4??000159b8?0300ba00?12ff7ffe?900010c2

            睜大眼睛看那個0xCC,對的,這里的確有0xCC。因為內(nèi)核斷點已經(jīng)取消了,這一定是用戶態(tài)調(diào)試器寫入的。

            接下來的問題是,既然這里有0xCC,那么為什么不影響其它進程呢?注意這個線性地址與前面的一模一樣。

            其中的奧妙在于這個線性地址已經(jīng)不再是前面那個物理地址了:

            1:?kd>?!pte?77c20574?
            ???????????????VA?77c20574
            PDE?at?00000000C0601DF0????PTE?at?00000000C03BE100
            contains?00000000012E0867??contains?00000000049BD025
            pfn?12e0?---DA--UWEV????pfn?49bd?----A--UREV

            雖然還同是一個線性地址,但是它現(xiàn)在對應的物理地址變成了49bd574。觀察這個物理地址,其內(nèi)容與剛才使用線性地址的得到的結(jié)果是一樣的:

            1:?kd>?!dd?49bd574?
            #?49bd574?000152cc?0300ba00?12ff7ffe?900008c2
            #?49bd584?000153b8?0300ba00?12ff7ffe?900008c2
            #?49bd594?000154b8?0300ba00?12ff7ffe?00498dc3
            #?49bd5a4?000155b8?0300ba00?12ff7ffe?00498dc3
            #?49bd5b4?000156b8?0300ba00?12ff7ffe?00498dc3
            #?49bd5c4?000157b8?0300ba00?12ff7ffe?900010c2
            #?49bd5d4?000158b8?0300ba00?12ff7ffe?900018c2
            #?49bd5e4?000159b8?0300ba00?12ff7ffe?900010c2

            而此時,物理地址1dddd574那里根本沒有0xCC。

            說到這里,謎團基本揭開了。事實上,?對于一個普通的進程,系統(tǒng)會把NTDLL的代碼映射給它,如果這個進程始終很普通,那么它便會永遠使用這份映射過來的代碼。但是當它要修改代碼時,系統(tǒng)會執(zhí)行所謂的Copy?on?Write動作,為其復制一份,讓它來寫。結(jié)合我們的情況,當在用戶態(tài)調(diào)試會話中向 NTDLL中設置斷點時,系統(tǒng)為其復制了一份代碼,讓它去寫,因此它寫入的斷點只有它自己“撞的到”,不會影響其它進程。但是當在內(nèi)核會話中寫入斷點時,因為是內(nèi)核調(diào)試引擎執(zhí)行的寫動作,所以沒有觸發(fā)Copy?on?Write,因此KD寫入的斷點寫在了公共的代碼上,會影響到使用這個公共代碼的所有進程。


            原文出處:http://advdbg.com/blogs/advdbg_syste...cles/1492.aspx

            《軟件調(diào)試》下載:http://bv.csdn.net/resource/rjts.pdf

            午夜精品久久久久久| 人妻无码久久精品| 久久精品国产99久久久| 99久久国语露脸精品国产| 伊人色综合久久天天网| 国产一区二区精品久久岳| 欧美黑人又粗又大久久久| 99久久精品免费看国产免费| 久久精品国产亚洲AV蜜臀色欲| 亚洲成色999久久网站| 狠狠色丁香久久婷婷综| 久久青青草原精品国产| 无码任你躁久久久久久| 爱做久久久久久| 国产精品久久久天天影视香蕉 | 久久久久国产精品| 久久亚洲AV成人无码电影| 久久久久亚洲精品无码蜜桃| 97久久天天综合色天天综合色hd| 91久久精品国产免费直播| 亚洲精品99久久久久中文字幕 | 伊人热人久久中文字幕| 久久精品国产只有精品2020| 九九久久精品国产| 久久精品国产欧美日韩99热| 天天做夜夜做久久做狠狠| yy6080久久| 久久精品亚洲福利| 亚洲欧美日韩久久精品| 丁香五月综合久久激情| 久久国产欧美日韩精品| 久久久网中文字幕| 久久精品国产亚洲欧美| 色狠狠久久AV五月综合| 97久久久久人妻精品专区| 久久人人添人人爽添人人片牛牛 | 亚洲伊人久久综合中文成人网| 久久精品国产AV一区二区三区| 久久久久久久国产免费看| 久久精品国产亚洲一区二区| 久久99精品国产自在现线小黄鸭 |