假設我想調試使用WinDbg的,國開行,或NTSD調試此程序爲Windows:在WinDbg命令中,如何引用與全局變量同名的寄存器?
/* test.c */
#include <stdio.h>
int rip = 42;
int main(void)
{
puts("Hello world!");
return (0);
}
我編譯AMD64程序和WinDbg的下運行它。我在main()處設置了一個斷點,並且當斷點遇到時,我想檢查RIP寄存器(程序計數器)處的值,以及該值作爲指針處理時的值。
我可以看到寄存器的值直接與r rip
,但是當我嘗試看看該地址周圍的內存,WinDbg中顯示我不同的地址!讀過test.pdb中的符號後,WinDbg發現rip
是一個在C代碼中聲明的全局變量,它顯示了&rip
左右的內存。
0:000> bu test!main
0:000> g
Breakpoint 0 hit
test!main:
00007ff6`de1868d0 4883ec28 sub rsp,28h
0:000> r rip
rip=00007ff6de1868d0
0:000> db rip
00007ff6`de1f2000 2a 00 00 00 ff ff ff ff-01 00 00 00 00 00 00 00 *...............
00007ff6`de1f2010 01 00 00 00 02 00 00 00-ff ff ff ff ff ff ff ff ................
00007ff6`de1f2020 00 00 00 00 00 00 00 00-43 46 92 e5 1b df 00 00 ........CF......
00007ff6`de1f2030 bc b9 6d 1a e4 20 ff ff-00 00 00 00 00 00 00 00 ..m.. ..........
00007ff6`de1f2040 00 01 00 00 00 00 00 00-ca b0 1e de f6 7f 00 00 ................
00007ff6`de1f2050 00 00 00 00 00 80 00 00-00 00 00 00 00 80 00 00 ................
00007ff6`de1f2060 d0 66 fc c2 f2 01 03 00-ab 90 ec 5e 22 c0 b2 44 .f.........^"..D
00007ff6`de1f2070 a5 dd fd 71 6a 22 2a 15-00 00 00 00 00 00 00 00 ...qj"*.........
0:000> ? rip
Evaluate expression: 140698265264128 = 00007ff6`de1f2000
0:000> ? dwo(rip)
Evaluate expression: 42 = 00000000`0000002a
這真的很煩人,但只要我意識到這一點,當手動讀取這樣的數據時,這不是問題。但是,如果我想使用寄存器的值,例如在腳本調試器,那麼有沒有簡單的解決方法:
0:000> bu test!main ".if (dwo(rip) == 0n42) { .echo Whoops! I don't want to get here! }"
0:000> g
Whoops! I don't want to get here!
test!main:
00007ff6`de1868d0 4883ec28 sub rsp,28h
這個問題,即在程序中隱藏寄存器名稱符號,使事情真的很難我。一個實際的情況:
- 我想在CreateFileW()上設置一個斷點,這是一個非常常用的Windows API函數。
- 由於我只關心一個特定的文件,我想檢查在RCX寄存器中傳遞的文件名,並繼續經過斷點,除非文件名與我想要的文件匹配。
- 但是我不能寫這個條件,因爲程序中的另一個模塊定義了一個符號
foobar!rcx
,並且我在命令中指定的所有對rcx
的引用都指向該全局變量!
那麼我該如何告訴WinDbg:是的,我真的想讀取寄存器?如果我想寫這個寄存器呢?我在這裏必須有一件簡單的事情。
if dwo(@rip)== xx做一些其他的事情如果qwo(@rcx)!= foobar!rcx做一些其他的事情.else gotosleep()@rcx = register rcx whereeas foobar!rcx或簡單的rcx是一個全球性的 – blabb