2012年7月5日星期四

windbg常见用法

本文主要搜集windbg的用法。

本文不写debug.exe,是因为windbg都支持这些命令的用法。

made by correy

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

设置windbg为默认的调试器的命令为 windbg -I
找遍windbg的安装目录没有找到卸载的文件,后来发现是个快捷方式,
快捷方式是个命令:C:\WINDOWS\system32\msiexec.exe /x {D09605BE-5587-4B0C-86C8-69B5092CB80F}。
修复的命令是:MsiExec.exe /I{D09605BE-5587-4B0C-86C8-69B5092CB80F} //在注册表中查到的。

对应的注册表位置是:HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug
(注:64位windows的上的路径不同,在HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Microsoft/Windows NT/CurrentVersion/AeDebug/Debugger? )
Auto = 0 的时候,系统会弹出一个对话框,让你在几个调试器中选择(如果你的系统安装了多个调试器的话)= 1 的时候,系统会自动调用默认调试器
Debugger默认调试器的路径。比如windows自带的Dr.Watson : DRWTSN32 -p %ld -e %ld -g或者是WinDBG: windbg.exe" -p %ld -e %ld -g

设置(下载)符号路径:srv*D:\symbols*http://msdl.microsoft.com/download/symbols

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

搜索内存的命令(s)的用法:
搜索整个用户空间的ASCII字符“made by correy”的用法:s -a 0 l?7fffffff "made by correy"
搜索整个用户空间的UNICODE字符“made by correy”的用法:s -u 0 L?80000000 "made by correy"
搜索汉字的用法:s -u 0 l?ffffffff "乐观园" 或者 s -u 0 l?100000000 "乐观园" 或者 s -u 0 l?1000000000 "乐观园"
搜索十六进制:s 0 L?ffffffff 0x99 0x99 0x99 0x99
搜索结构(类)等办法的以后补充。
当然搜索整个4G的空间也可以的。
说明:
去年会用这个命令,过后又忘了。
今天又找回来了。
去年不知道为何要加?
今天知道了:Specifies the memory area to search through. This range cannot be more than 256 MB long unless you use the L?syntax.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

像OD一样显示堆栈窗口的一个办法:
打开一个内存窗口,虚拟地址写为:esp,显示的格式设置为:Pointer and Symbol,再调整到适合的宽度,就ok了。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

看到ollydbg的双击一行指令,然后可以修改指令的功能,用windbg如何实现呢?
最原始的是a:
输入 a 0xxxxxxxxx
然后输入命令
最后不要忘了退出,
退出的办法不是e也不是q
更不是exit和quit.
是再输入一个回车(空格不行的)
一些简单的可以直接修改内存(如:90或者0xcc),复杂的还得用汇编命令,不然就麻烦了,还得计算等。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

如果是驱动文件包含在可执行文件里面,释放后再调试这个驱动文件,可能会加载不了这个驱动的符号文件,这时候,可以这么做:
一种解决方法是使用.reload /i命令来加载不完全匹配的符号文件。为了便于发现问题,最好先使用!sym noisy命令开启加载符号的'吵杂'模式.
如:.reload /i test.sys 或者 .reload /i test 或者 .reload /i 加载所有的.
第二种解决办法是除了使用带有/i开关的.reload命令,也可以通过设置符号选项SYMOPT_LOAD_ ANYTHING(0x40)来让调试器加载不严格匹配的符号文件。
0:000> .symopt+0x40

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

如何: 查找问题异常堆栈,在收到 UnhandledExceptionFilter 调用堆栈跟踪中
摘自:http://support.microsoft.com/kb/313109/zh-cn
整理如下:
1.在命令提示符下键入~ * kb列出所有进程中的线程及堆栈。
2.在堆栈中找到KERNEL32!UnhandledExceptionFilter的线程.有可能还有KERNELBASE!等.
   09a8f644 77ea7e7a 09a8f66c 77e861ae 09a8f674 KERNEL32!UnhandledExceptionFilter+0x2b5 
3.切换到该线程 (在此示例中,该线程是"~ 120s")。
4.UnhandledExceptionFilter函数只有一个参数,即EXCEPTION_POINTERS结构的地址.结构定义如下:
  typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord; 
    PCONTEXT ContextRecord;
  } EXCEPTION_POINTERS,  *PEXCEPTION_POINTERS;
  在32位系统中可以用如下命令查看.建议用dt.
  0:120> dd 09a8f66c 
  09a8f66c  09a8f738 09a8f754 09a8f698 77f8f45c 
  在64位系统中要用dq,且要注意参数的传递及栈的存储位置.
5.第一个 DWORD 表示异常记录。若要获取有关异常的类型的信息,请在命令提示符处运行以下命令:
   0:120> .exr 09a8f738 
6.第二个 dword 值是(发生问题时的)上下文记录。要获取的上下文信息,请在命令提示符处运行以下命令:
   0:120> .cxr 09a8f754 
7.运行kv命令以获取实际的异常的调用堆栈。这有助于您识别可能不能正确处理过程中的实际问题。
   0:120> kv

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

定位内核出问题的指令.

很多时候,我们在调试器看到的不是发生问题时的状态,大多是发生问题时过一段时间的处理状态.
所以要定位发生问题时的状态很重要.
这里有一个小经验,大多情况下适用.

1.执行KV命令.
  看看这个(其实是所有)CPU或者线程的堆栈有没有TrapFrame @ ,注意:如果有多个,以上面的也就是最后的调用的为准.
  记住TrapFrame @ 后面的数字.
2..trap XXXXXXXX.注释:XXXXXXXX就是你上面记住的数字.
3.看调用堆栈信息吧!记住!这个办法很准的.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

定位内存被非法篡改等的超级大法:ba命令.
注意内存的地址的对其数和要监控的大小.
数量有限,珍惜使用.
还可以监视IO操作.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

显示一个进程或者系统的模块的完整路径:
1.按照地址排列:lm f
2.按照字母顺序:lm sm f 
3.显示所有的详细信息:lm v
4.显示某个的详细信息:lm v m kernel32
注意:模块后面不要加文件名的后缀,如:.dll or .sys.
这个命令和很有用,也常用.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Physical Address Extension (PAE) 
http://technet.microsoft.com/en-us/library/cc784574(v=ws.10).aspx
http://technet.microsoft.com/en-us/library/cc736309(WS.10).aspx
http://technet.microsoft.com/en-us/library/cc783646(v=ws.10).aspx
大多在X86上使用。

在调试中查看的办法是:
kd> .formats @cr4
Evaluate expression:
  Hex:     00000000`000406f8
  Decimal: 263928
  Octal:   0000000000000001003370
  Binary:  00000000 00000000 00000000 00000000 00000000 00000100 00000110 11111000
  Chars:   ........
  Time:    Sun Jan 04 09:18:48 1970
  Float:   low 3.69842e-040 high 0
  Double:  1.30398e-318
http://blogs.msdn.com/b/ntdebugging/archive/2010/06/22/part-3-understanding-pte-non-pae-and-x64.aspx
注意:如果最低位算是第0位,那就是第五位。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Controlling the Target
http://msdn.microsoft.com/en-us/library/windows/hardware/ff539293(v=vs.85).aspx

开始时认为:只要会G,P,T,BP命令就可以调试所有的东西了。
其实经过实战之后发现,这很低效。
要高效还得用额外的命令(条件断点),脚本甚至是插件。
这里只说有用的指令。


gc (Go from Conditional Breakpoint)      Resumes execution after a conditional breakpoint.
gh (Go with Exception Handled)           Same as g (Go), except that the current exception is treated as handled.
gn (Go with Exception Not Handled)       Same as g (Go), except that the current exception is treated as unhandled.
gu (Go Up)                               Target executes until the current function is complete.
这个主要是处理异常的,别的无用。


pa (Step to Address)                     Target executes until it reaches the specified address. All steps in this function are displayed (but steps in called functions are not).
pc (Step to Next Call)                   Target executes until the next call instruction.
                                         If the current instruction is a call instruction, this call is executed completely and execution continues until the next call.
pct (Step to Next Call or Return)        Target executes until it reaches a call instruction or a return instruction.
ph (Step to Next Branching Instruction)  Target executes until it reaches any kind of branching instruction, including conditional or unconditional branches, calls, returns, and system calls.
pt (Step to Next Return)                 Target executes until it reaches a return instruction.
这个主要是处理函数的,建议常用pct和ph.
注意:执行此命令的时候要进入这个函数,而不是在没有进入函数之前执行。


ta (Trace to Address)                    Target executes until it reaches the specified address. All steps in this function and called functions are displayed.
tb (Trace to Next Branch)                (All modes, except kernel mode, only on x86-based systems) Target executes until it reaches the next branch instruction.
tc (Trace to Next Call)                  Target executes until the next call instruction. 
                                         If the current instruction is a call instruction, the instruction is traced into until a new call is reached.
tct (Trace to Next Call or Return)       Target executes until it reaches a call instruction or return instruction. 
                                         If the current instruction is a call instruction or return instruction, the instruction is traced into until a new call or return is reached.
th (Trace to Next Branching Instruction) Target executes until it reaches any kind of branching instruction, including conditional or unconditional branches, calls, returns, and system calls. 
                                         If the current instruction is a branching instruction, the instruction is traced into until a new branching instruction is reached.
tt (Trace to Next Return)                Target executes until it reaches a return instruction.
                                         If the current instruction is a return instruction, the instruction is traced into until a new return is reached.
建议同上,不过这个很少用。


wt (Trace and Watch Data)                Target executes until the completion of the whole specified function. Statistics are then displayed.
这个函数很有用。
不过Kernel mode: x86-based only.
参数可以不考虑。
注意用的时机:在一个函数的执行之前,函数执行完毕后自动会断下来,即使你没有下断点。
显示的内容,自己分析,这里有不说了。
有了这个分析函数,前面的都显得弱小了。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
界面配置信息:
1.打印时显示时间信息的配置。
  VIEW->EVENT TIMESTAMPS 
2.去掉一不小心加上的配置:调试的时候总是加载没有加载的符号文件,这主要是非微软的文件。
  DEBUG->Resolve Unqualified Symbols
3.输入的命名高亮显示,并且配置颜色的设置。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WINDBG在调试汇编函数时,第一个指令停止在函数上,单步会跳过第一个指令。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

没有评论:

发表评论