版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1. 概述用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe、ntsd.exe、kd.exe和Windbg.exe。其中cdb.exe和ntsd.exe只能调试用户程序,Kd.exe主要用于内核调试,有时候也用于用户态调试,上述三者的一个共同特点是,都只有控制台界面,以命令行形式工作。Windbg.exe在用户态、内核态下都能够发挥调试功能,尤其重要的是,它不再是命令行格式而是采用了可视化的用户界面。所以绝大部分情况下,我们在谈及Windows调试工具的时候,都直接指向Windbg,而不大谈及前三者。Windbg在用户态和内核态下,都支持两种
2、调试模式,即“实时调试模式(Living)”和“事后调试模式(Postmortem)”。所谓实时模式,是被调试的目标对象(Target)当前正在运行当中,调试器可以实时分析、修改被调试目标的状态,如寄存器、内存、变量,调试exe可执行程序或双击双机实时调试都属于这种模式;所谓事后模式,是被调试的目标对象(Target)已经结束了,现在只是事后对它保留的快照进行分析,这个快照称为转储文件(Dump文件)。Windbg另一个重大优点,还在于它支持源码级的调试,就像VC自带的调试器一样。虽然提供了用户界面,但Windbg归根结底还是需要用户一个个地输入命令来指挥其行动。这就是他的Command窗口。
3、每个调试命令都各有使用范围,有些命令只能用于内核调试,有些命令只能用于用户调试,有些命令只能用于活动调试。但用户也不必记得这许多,一旦在某个环境下,使用了不被支持的命令,都会显示“No export XXX found”的字样。就拿!process命令来说吧,它显示进程信息,但只能用于内核调试中,如果在用户调试中使用,就是下面的情景:0:001 !processNo export process found1.1 寻求帮助我们首先来看如何在使用过程中获取有用的帮助。Windbg中的调试命令,分为三种:基本命令,元命令和扩展命令。基本命令和元命令是调试器自带的,元命令总是以“.”开头,而扩展命令
4、是外部加入的,总是以感叹号“!”开头。各种调试命令成千上万,我们首先要想办法把它们都列举出来,并取得使用方法。基本命令最少了,大概40个左右。列举所有的基本命令,使用如下命令: ?元命令有一百多个,使用下面命令列举所有元命令: .help /D如使用“/D”参数,命令列表将以DML格式显示。DML是一种类似于HTML的标识语言,下面会讲到。下图以DML格式显示所以有字母a开头的元命令:最后讲扩展命令。所谓扩展命令,顾名思义是可以“扩展”的。扩展命令从动态连接库中暴露出来,一般以DLL文件名来代表一类扩展命令集,首先我们要搜索出系统中有多少个这样的DLL文件,使用下面命令: .chain /D此
5、命令能够给出一个扩展命令集的链表。和.help命令一样,也可以使用/D参数以DML格式显示。如下所示:0:001 .chainExtension DLL search Path: C:Program Files (x86)Windows Kits8.0Debuggersx64WINXP;Extension DLL chain: dbghelp: image 6.2.9200.20512, API 6.2.6, built Fri Sep 07 13:45:49 2012 path: C:Program Files (x86)Windows Kits8.0Debuggersx64dbghelp.
6、dll ext: image 6.2.9200.16384, API 1.0.0, built Thu Jul 26 10:11:33 2012 path: C:Program Files (x86)Windows Kits8.0Debuggersx64winextext.dll exts: image 6.2.9200.16384, API 1.0.0, built Thu Jul 26 10:15:20 2012 path: C:Program Files (x86)Windows Kits8.0Debuggersx64WINXPexts.dll uext: image 6.2.9200.
7、16384, API 1.0.0, built Thu Jul 26 10:15:09 2012 path: C:Program Files (x86)Windows Kits8.0Debuggersx64winextuext.dll ntsdexts: image 6.2.9200.16384, API 1.0.0, built Thu Jul 26 10:16:01 2012 path: C:Program Files (x86)Windows Kits8.0Debuggersx64WINXPntsdexts.dll最上面两行显示了扩展模块的搜索路径。接下来共列出了六个Windbg自带的扩
8、展模块:wdfkd、dbghellp、ext、exts、uext和ntsdexts。可以查看到这些扩展模块的版本信息、镜像文件路径。如何列出某个扩展库中所包含的扩展命令列表呢?绝大部分扩展模块可使用如下命令: !模块名.help此外,扩展命令模块是可“扩展”的。如果读者从第三方处获取,或自己编写了一个扩展调试模块,则可通过.load/.unload命令动态加载/卸载。1.2 DML语言DML(Debugger Markup Language调试器标记语言)像HTML一样,可从一处链接到另一处。不同处在于,DML的链接内容需要用户点击后才会动态生成。一般用来以精简方式显示大量信息和扩展功能。DM
9、L有很多实用的功能,如果使用者一时不知道从何下手,最好就是输入.dml_start命令,开始DML之旅。DML链接以更加可视化的方式,引导用户查看调试信息,使得调试工具的使用相比纯指令格式而言,更为友好。DML如同是对原指令的一层轻微的包装一样,让生硬的指令更加温和了。所以建议读者总是把DML默认开启。 .prefer_dml 1开始DML。 .prefer_dml 0关闭DML。一旦开启DML后,像k等支持DML的调试命令,将默认以DML格式显示输出内容。DML还能以一种很特殊的方式为函数画流程图。它主要的原理是使用反汇编,类似于uf,但在逻辑分支处,它会停止反汇编并显示分支让用户选择。另外
10、,它能显示汇编代码对应的行号,这一点真的非常好。如果稍加精进,他就能画出非常漂亮的流程图了。他的一个特点是反汇编的顺序是从后往前推。只要细想一想,就会觉得很有道理。如果正推的话,分支太多;而反推则分支顺序在用户的参与下(即用户进行分支选择),是固定了的。 .dml_flow FindAllInfFilesA FindAllInfFilesA+30这是一个非常简单、实用的例子,对Kernel32库中的FindAllInfFilesA接口函数进行反汇编,效果类似uf命令却更强大。1.3 基本信息本节讲解和调试器软件本身相关的命令,比如:查看软件版本、启动参数,以及最基本的软件设置命令。首先看版本命
11、令: version此命令显示操作系统的版本信息以及Windbg本身的版本信息,Windbg的配置和操作系统密切相关,所以将操作系统的版本信息一并显示出来是很有必要的。在内核环境与用户环境下运行此命令,会得到不同的输出。下图为内核环境下输出结果:0:001 versionWindows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x64Product: WinNt, suite: SingleUserTSkernel32.dll version: 6.1.7601.18015 (win7sp1_gdr.121129-1432)Machin
12、e Name:Debug session time: Thu Aug 22 10:11:04.000 2013 (UTC + 8:00)System Uptime: 14 days 17:26:44.613Process Uptime: 14 days 17:14:25.000 Kernel time: 0 days 0:09:02.000 User time: 0 days 0:42:36.000Full memory user mini dump: C:UsersmozhangAppDataLocalTempdwm.DMPMicrosoft (R) Windows Debugger Ver
13、sion 6.2.9200.16384 AMD64Copyright (c) Microsoft Corporation. All rights reserved.除了Windbg版本信息,上面的输出中还包括目标系统信息。如果纯粹是为了查看目标系统的版本信息,可使用下面的vertarget命令: vertargetWindbg支持对多个调试系统中的多个调试目标同时进行调试。上面我们通过version或vertarget命令列出了当前调试系统的版本信息,还可以查看当前目标系统的状态: |如Windbg中同时打开多个调试对象,“|”命令将列出对象列表。笔者为了演示此种情况,先在Windbg中开启L
14、ocal Debug环境,然后两次调用.opendump命令打开两个DUMP文件,这样就同时拥有了三个被调试的目标对象。下图显示了这个情况: 上图中的活动对象是0号对象(可从数字0前面的小数点看出)。调试器需要在多个调试目标之间进行切换的话,使用“s”参数。如要切换到1号目标可使用下面的命令: | 1 s最后一个命令用来查看系统时间。这包括系统当前时间,以及系统正常运行持续时间;用户模式下还会显示当前进程的持续时间。命令格式如下: .time0:001 .timeDebug session time: Thu Aug 22 10:11:04.000 2013 (UTC + 8:00)Syste
15、m Uptime: 14 days 17:26:44.613 / 系统运行时间Process Uptime: 14 days 17:14:25.000/ 当前进程运行时间 Kernel time: 0 days 0:09:02.000 User time: 0 days 0:42:36.0001.4 基本设置首先看一个清屏命令: .cls当命令窗口中的内容太乱的时候,这个命令帮你快刀斩乱麻。下面看一个设置默认数字进制的命令: n 8|10|16软件默认是16进制,但有时候我们也需要把默认进制改成八进制或十进制的。下面尝试在八进制下面求数字11的值,如下:0:001 n 8base is 80:
16、001 ? 11Evaluate expression: 9 = 0000000000000009最后再来说一个处理器模式指令。关于处理器模式很值得一说,很重要。处理器模式的设置,反映了Windbg软件的强大。举例来说,主机为32位的系统,却可以同时调试X86、IA64、X64的目标系统前提是先将主机的处理器模式设置正确了。可用处理器模式值有:x86、adm64、ia64、ebc。 .effmach x86命令.effmach表示Effective Machine Type,即有效的机器类型。此命令将当前的处理器模式设置为x86模式。1.5 格式化显示将一个整数以各种格式显示,包括:16进制、
17、10进制、8进制、二进制、字符串、日期、浮点数等。是不是很方便?这个命令是: .formats 整数下面以0x123abc为例:0:001 .formats 0x123abcEvaluate expression: Hex: 0000000000123abc Decimal: 1194684 Octal: 0000000000000004435274 Binary: 00000000 00000000 00000000 00000000 00000000 00010010 00111010 10111100 Chars: .:. Time: Thu Jan 15 03:51:24 1970 F
18、loat: low 1.67411e-039 high 0 Double: 5.90252e-3181.6 开始调试现在领大家进入调试阶段。首先看看如何让调试器附载到一个已运行的进程中去?比如IE软件在运行过程中发生了崩溃,打开Windbg后如何调试呢?第一步就是把Windbg附载到发生崩溃的IE进程上。使用如下命令格式: .attach PID或者通过Windbg的启动参数进行挂载: Windbg p PID上面两个命令中,PID指定了进程ID。如果觉得指定PID不方便,也可以通过进程名进行挂载: Windbg -pn进程名比如挂载到记事本就可以这样:windbg pn notepad.ex
19、e上面的命令是把调试器挂载到已经存在的进程上,另外调试器可以创建新进程并对它进行调试,这二者使用了不同的侵入方法。使用下面的命令: .create程序启动命令行或者Windbg启动参数 Windbg程序启动命令行比如创建并调试一个记事本子进程,可用.create notepad或者windbg notepad命令。也可以打开Windbg后,在File菜单中选择“Open Executable”启动Notepad子进程,但这个选项只能被执行一次(之后会灰掉)。使用上述命令可将调试器连续附载到多个进程,也就是说,能够同时调试多个进程,这一点看上去很神奇哦。下例中,调试器先创建子程序IOCTL.ex
20、e,然后又调用.attach命令附加到记事本进程,使用命令“|”列出所有被调试进程。读者可能会奇怪,多个进程同时调试怎么兼顾呢?只要有一个切换指令就可以了,这样就能够切换到任意的进程(令其为当前进程)并对之进行调试。比如上图显示1号进程为当前进程(注意1前面的小点),如何将当前进程切换到0号进程呢?可以使用进程列表命令“|”轻松切换,比如: | 0 s此命令把当前调试环境切换到0号IOCTL.exe进程。另外需注意的是,多个用户进程调试目标都处于同一个调试会话中,使用“|”命令会看到,它们属于同一个 “Live user mode”调试会话。下面看dump文件调试,使用命令: .opendum
21、p文件名此命令打开一个dump文件,并建立一个DUMP调试会话。如何手动创建一个dump文件呢?比如在调试过程中,遇到了无法解决的问题,希望获得异地帮助,则把当前调试环境保存到Dump文件中发送给能提供帮助的人,不失为一种好办法。 .dump文件名Dump文件一般以.dmp为后缀,系统生成的Dump文件都默认以.dmp为后缀的,但使用.dump命令时,使用者可以设置任意后缀,甚至无后缀。下例中,首先为当前进程生成一个dump文件保存到a.txt中(即后缀名为.txt),然后将之打开并分析:0:001 .dump a.txtCreating a.txt - mini user dumpDump
22、successfully written0:001 .opendump a.txtLoading Dump File C:Program Files (x86)Windows Kits8.0Debuggersa.txtUser Mini Dump File: Only registers, stack and portions of memory are availableOpened a.txt / 打开成功上文讲到进程挂载命令,当需要解除挂载时,可使用解挂命令,如下: .detach此命令结束当前调试会话, Windbg解除和被调试进程之间的调试关系(不管是通过挂载,还是通过创建方式建立的
23、调试关系),解挂后,被调试进程能够独立运行;如果当前的调试会话是一个Dump文件,此命令直接结束对dump文件的调试,即结束调试会话。如果需要彻底结束调试,下面的命令更有用: q | qq | qdq是Quit的缩写。结束当前调试会话,并返回到最简单的工作空间,甚至把命令行界面也关闭掉。q和qq两个命令将结束(close)被调试的进程,qd不会关闭调试进程,而是进行解挂操作。双机调试的时候,如果你感觉调试已经陷入僵局,比如目标机Hang住了动都动不了,此时通过主机让目标机强制宕机或重启,不失为一个好主意。 .crash .rebootcrash命令能引发一个系统蓝屏,并生成dump文件;而.r
24、eboot使系统重启,不产生dump文件。2. 符号与源码符号与源码是调试过程中的重要因素,它们使得枯燥生硬的调试内容更容易地调试人员读懂。在可能的情况下,应该尽量地为模块加载符号和源码。大部分情况下源码难以得到,但符号却总能以符号文件的形式易于得到。什么是符号文件呢?编译器和链接器在创建二进制镜像文件(诸如exe、dll、sys)时,伴生的后缀名为.dbg、.sym或.pdb的包含镜像文件编译、链接过程中生成的符号信息的文件称为符号文件。具体来说,符号信息包括如下内容: 全局变量(类型、名称、地址); 局部变量(类型、名称、地址); 函数(名称、原型、地址); 变量、结构体类型定义;源文件路
25、径以及每个符号对应于源文件中的行号,这是进行源码级别调试的基础。有这么多的信息包含在符号文件中,使得符号文件通常要比二进制文件(PE格式文件)本身要大很多。调试过程中,符号之重要性不言而喻。只有正确设置了符号路径,使得调试器能够将调试目标、符号文件以及源码文件一一对应起来,才能够最好地发挥调试器的强大功用。符号信息隶属于指定的模块,所以只有调试器需要用到某个模块时,他的符号信息才有被加载和分析的必要。所以我们在讲符号内容之前,先讲和模块相关的命令。2.1 模块列表每个可执行程序都是由若干个模块构成,有些模块静态加载,有些模块以动态方式进行加载。所以对于有些模块,可能在A时刻运行时被加载,而在B
26、时刻运行时,自始至终都未被加载。调试过程中,调试器根据模块的加载情况加载符号。有几个命令可以用来列举模块列表,分别是:lm、!dlls、.reload /l、!imgreloc。下面分别来看。 lm 选项 a Address m Pattern | M Patternlm是list loaded modules的缩写,他还有一个DML版本: lmD 选项 a Address m Pattern | M Pattern使用/v选项能列出模块的详细信息,包括:模块名、模块地址、模块大小、镜像名、时间戳、以及对应的符号文件信息(包括类型、路径、类型、编译器、符号加载状态)。如使用参数a,后面跟地址(
27、address),则只有指定地址所在的模块能够被列出;如使用参数m,后面跟一个表示模块名的字符串通配符,如lmm*o*将显示所有名称中包含字母o的模块,下图所示:|0:0:001 lm m *o*start end module namef3380000 f3512000 dwmcore (private pdb symbols) f92d0000 f9327000 d3d10_1core (deferred) fa890000 fa9f1000 WindowsCodecs (deferred) faa50000 fac44000 comctl32 (deferred) fbf70000 fb
28、f7c000 version (deferred) fce20000 fce2f000 profapi (deferred) fd970000 fdb73000 ole32 (deferred) fee60000 fee7f000 sechost (deferred)下面介绍另一个命令: !dlls 选项 LoaderEntryAddress 首先看他的可选参数: -i/-l/-m:排序方式,分别按照初始化顺序、加载顺序、内存起始地址顺序排列。-a:列出镜像文件PE结构的文件头、Section头等详细信息,是分析PE结构的好帮手(更好的帮手是利用自如PEView或Stud_PE等UI工具)。
29、-c:指定函数所在的模块。这个选项非常实用,比如我想知道NtCreateFile函数是哪个模块暴露出来的接口,如下:0:000 !dlls -c ntcreatefileDump dll containing 0x7c92d0ae:0x00251f48: C:WINDOWSsystem32ntdll.dll Base 0x7c920000 EntryPoint 0x7c932c48 Size 0x00096000 Flags 0x00085004 LoadCount 0x0000ffff TlsIndex 0x00000000 LDRP_IMAGE_DLL LDRP_LOAD_IN_PROGR
30、ESS LDRP_ENTRY_PROCESSED LDRP_PROCESS_ATTACH_CALLED除了lm和!dlls外,下文将讲到的.reload命令在加入 /l选项后,也能列举模块,其命令格式如下: .reload /l最后再来看一个!imgreloc命令,它也能够列出模块列表并显示各模块地址。但其主要作用尚不在此,它用来判断各个模块是否处于preferred地址范围。所谓Preferred地址是这么一回事:二进制文件在编译的时候,编译器都会为其设置一个理想地址(Preferred Address),这样二进制文件被加载时,系统会尽可能将他映射到这个理想地址。当然,所谓“理想”往往是会
31、受到“现实”的挑战的,当存在地址竞争的时候,需要适当调整二进制文件的加载地址,选择另一个合适的地方加载之。!imgreloc命令就是用来查看这种情况的,命令如下: !imgreloc 模块地址命令!imgReloc是Image Relocate的缩写,字面已能够反映其含义:镜像文件重定位信息。下面是一个例子。 上例中,大部分系统模块(上图下部方框所示)其地址由于事先经过统筹分配,所以一般都能被加载到preferred地址处。只有少数模块(如最上面的Normaliz模块)由于地址冲突而受到了调整。2.2 模块信息 上一节我们了解了如何枚举模块列表,这一节我们研究针对单个模块,如何获取详细信息。有
32、多个命令可以查看指定模块的详细模块信息,这包括:lm、!dh、lmi等,下面来一一介绍。首先看lm,这个命令上面我们已经介绍过,现在利用它来获取指定模块信息。其命令格式如下: lm v a模块地址这里使用了v选项,以显示详细(verbose)信息;并使用a参数以指定模块地址。通过此命令显示的信息,和我们在explorer资源管理器中通过鼠标右键查看一个文件的属性所看到的信息差不多。请看下面的清单:0:000 lm v a 00400000start end module name00400000 00752000 UsbKitApp C (private pdb symbols) C:Trun
33、kCY001UsbKitAppDebugUsbKitApp.pdb Loaded symbol image file: UsbKitApp.exe Image path: UsbKitApp.exe Image name: UsbKitApp.exe Timestamp: Tue Mar 16 22:07:02 2010 (4B9F9086) CheckSum: 00000000 ImageSize: 00352000 File version: Product version: File flags: 1 (Mask 3F) Debug File OS: 4
34、Unknown Win32 File type: 1.0 App File date: 00000000.00000000 Translations: 0804.03a8 CompanyName: TODO: ProductName: TODO: InternalName: UsbKitApp.exe OriginalFilename: UsbKitApp.exe ProductVersion: FileVersion: FileDescription: TODO: LegalCopyright: TODO: (C) 。保留所有权利。 下面看!lmi命令,此命令
35、通过指定模块地址查找模块并获取其信息,其命令格式如下 !lmi模块地址此命令侧重获取对调试器有用的信息,请看下面的列表:0:000 !lmi 0x400000Loaded Module Info: 0x400000 Module: UsbKitApp Base Address: 00400000 Image Name: UsbKitApp.exe Machine Type: 332 (I386) Time Stamp: 4b9f9086 Tue Mar 16 22:07:02 2010 Size: 352000 CheckSum: 0Characteristics: 103Debug Data
36、 Dirs: Type Size VA PointerCODEVIEW - GUID: 5DB12DF1-71CA-43F7-AD85-0977FB3629A4 Age: 3, Pdb: C:TrunkCY001UsbKitAppDebugUsbKitApp.pdb Image Type: FILE - Image read successfully from debugger. UsbKitApp.exe Symbol Type: PDB - Symbols loaded successfully from image header. C:TrunkCY001UsbKitAppDebugUs
37、bKitApp.pdb Compiler: Resource - front end 0.0 bld 0 - back end 9.0 bld 21022 Load Report: private symbols & lines, not source indexed C:TrunkCY001UsbKitAppDebugUsbKitApp.pdb如果还要查看更详细、丰富的模块信息,可以使用!dh命令,命令格式如下: !dh 标志模块地址dh是display header的缩写,直译就是“显示文件头”的意思,它能够显示非常详细的PE头信息。下图截取了输出信息中的开头部分,其它详细内容,需要读者熟
38、悉微软的PE结构才能看懂:模块相关的知识点讲完了,下面讲符号有关命令。和符号相关的知识点包括:符号路径、符号服务器、符号缓存、符号加载以及符号的使用等。2.3 符号路径什么是符号路径呢?就是调试器寻找符号文件的方向,它可以是本地文件夹路径、可访问的UNC路径、或者是符号服务器路径。什么是符号服务器呢?如果调试过程中,需要涉及到成千上万个符号文件,以及同一个符号文件存在不同平台下的不同符号文件版本的时候,那么一一手动设置符号路径肯定是不现实的,于是引入符号服务器的概念。符号服务器有一套命名规则,使得调试软件能够正确找到需要的符号文件。一般来说,符号服务器比较大,都是共用的,放在远程主机上。为了降
39、低网络访问的成本,又引入了符号缓存的概念,即将从服务器上下载到的符号文件,保存在本地缓存中,以后调试器需要符号文件的时候,先从缓存中寻找,找不到的时候再到服务器上下载。下面分几部分一一来看。设置符号路径:设置符号路径的语法如下: .sympath + 路径如果不加入任何参数执行.sympath命令,将显示当前的路径设置: .sympath如要覆盖原来的路径设置,使用新路径即可: .sympath 要在原有路径的基础上添加一个新路径,可使用: .sympath+ 要注意的是,使用.sympath改变或新增符号路径后,符号文件并不会自动更新,应再执行.reload命令以更新之。这里要谈一谈延迟加载
40、的知识点。延迟加载使得模块的符号表,只在第一次真正使用的时候才被加载。这加快了程序启动,不用在一开始耗费大量时间加载全部的符号文件。使用.symopt +4和.symopt -4来开启或关闭延迟加载设置。在已经启动了延迟加载的情况下,如想临时改变策略,立刻将指定模块的符号加载到调试器中,可以使用ld或者.reload /f命令。符号服务器与符号缓存:设置符号服务器的基本语法是: SRV*符号缓存*服务器地址语法由SRV引导,符号缓存和服务器地址的前面各有一个星号引导。符号缓存一般也叫做下游符号库。如某公司有一台专门的符号服务器,地址为symsrvsymbols,则他们公司的所有开发人员都应该在
41、他们的调试器中使用类似下面的命令: .sympath+ srv*c:symbols*symsrvsymbols此外,我们总是应该把微软的公用符号库加入到我们的符号路径中: .sympath+ srv*这是一台微软对外公开的服务器,使用http地址访问,不是所有人都能牢记这个网址,所以最好的办法就是使用.symfix命令,语法如下: .symfix + 符号缓存地址这个命令等价于上面的.sympath命令,而不用输入长长的http地址。0:000 .symfix c:windowssymbols0:000 .sympathSymbol search path is: SRV*c:windowss
42、ymbols*符号选项:命令格式如下: 显示当前设置:.symopt 增加选项:.symopt+ Flags 删除选项:.symopt- Flags第一个命令没有任何参数,显示当前设置。后面两个,第二个命令含有“+”代表添加一个选项,第三个命令含有“-”代表去除一个选项。001 .symoptSymbol options are 0x30337: 0x00000001 - SYMOPT_CASE_INSENSITIVE 0x00000002 - SYMOPT_UNDNAME 0x00000004 - SYMOPT_DEFERRED_LOADS 0x00000010 - SYMOPT_LOAD_
43、LINES 0x00000020 - SYMOPT_OMAP_FIND_NEAREST 0x00000100 - SYMOPT_NO_UNQUALIFIED_LOADS 0x00000200 - SYMOPT_FAIL_CRITICAL_ERRORS 0x00010000 - SYMOPT_AUTO_PUBLICS 0x00020000 - SYMOPT_NO_IMAGE_SEARCH可用的符号选项请见下表:值可读名称描述01SYMOPT_CASE_INSENSITIVE符号名称不区分大小写02SYMOPT_UNDNAME符号名称未修饰04SYMOPT_DEFERRED_LOADS延迟加载08
44、SYMOPT_NO_CPP关闭C+转换,C+中的:符号将以_显示010SYMOPT_LOAD_LINES从源文件中加载行号020SYMOPT_OMAP_FIND_NEAREST如果由于编译器优化导致找不到对应的符号,就以最近的一个符号代替之040SYMOPT_LOAD_ANYTHING使得符号匹配的时候,匹配原则较松散,不那么严格。080SYMOPT_IGNORE_CVREC忽略镜像文件头中的CV记录0100SYMOPT_NO_UNQUALIFIED_LOADS只在已加载模块中搜索符号,如果搜索符号失败,不会自动加载新模块。0200SYMOPT_FAIL_CRITICAL_ERRORS不显示文
45、件访问错误对话框。0400SYMOPT_EXACT_SYMBOLS进行最严格的符号文件检查,只要有微小的差异,符号文件都不会被加载。0800SYMOPT_ALLOW_ABSOLUTE_SYMBOLS允许从内存的一个绝对地址处读取符号信息。01000SYMOPT_IGNORE_NT_SYMPATH忽视在环境变量中设置的符号路径,也忽视被调试进程的执行路径。也就是说,当搜索符号文件的时候,不会从这些路径中搜索。02000SYMOPT_INCLUDE_32BIT_MODULES让运行在安腾系统上的调试器,也枚举32位模块。04000SYMOPT_PUBLICS_ONLY仅搜索符号文件的公共(PUBL
46、IC)符号表,忽略私有符号表。08000SYMOPT_NO_PUBLICS不搜索符号文件的公共(PUBLIC)符号表010000SYMOPT_AUTO_PUBLICS先搜索pdb文件的私有符号表,如果在其中找到对应的符号,就不再搜索公共(PUBLIC)符号表,这可以加快搜索速度。020000SYMOPT_NO_IMAGE_SEARCH不搜索镜像拷贝040000SYMOPT_SECURE安全模式,让调试器尽量不影响到主机。080000SYMOPT_NO_PROMPTS不显示符号代理服务器的认证对话框,将导致某些时候无法访问符号服务器080000000SYMOPT_DEBUG显示符号搜索的详细过程
47、和信息表8-1 符号选项2.4 符号加载本节分下面几个子题目分别讲解。立刻加载:其命令格式如下: ld模块名/f符号文件名加载指定模块的符号。调试器默认采用延迟模式加载符号,也就是直到符号被使用的时候,才将符号文件加载到调试器中并进行解析。ld使得延迟模式被打破,让指定模块的符号文件立刻加载到调试器中。此指令可为模块的符号文件设置自定义的匹配名称,比如: ld 123 /f abc这样一来,abc.pdb将成为123.exe的符号文件。正常情况下,这是不可能的,只能是abc.pdb对应abc.exe。重新加载:如果对自己正在使用的符号文件感到疑惑,比如源代码和行号明显不匹配,最好的做法就是重新
48、加载一下符号文件。此命令语法如下: .reload /f /v 模块名.reload命令的作用是删除指定或所有已加载的符号文件,默认情况下,调试器不会立刻根据符号路径重新搜索并加载新的符号文件,而是推迟到调试器下一次使用到此文件时。使用/f参数(force),将迫使调试器立刻搜索并重新加载新的符号文件。其它参数解释如下: /v:将搜索过程中的详细信息都显示出来。 /i:不检查pdb文件的版本信息; /l:只显示模块信息,内核模式下,和“lm n t”命令类似,但显示内容比后者更多,因为包含了用户模块信息; /n:仅重载内核符号,不重载用户符号; /o:强制覆盖符号库中的符号文件,即使版本相同;
49、 /d:用户层模式下使用Windbg时的默认选项,重载调试器模块列表中的所有模块; /s:内核模式下使用Windbg时的默认选项,重载系统模块列表中的所有模块,另外,如果调试器在用户模式下运行,要加载内核模块,也必须使用/s选项,否则调试器将只会在调试器模块列表中搜索而导致找不到内核模块; /u:卸载指定模块。如发现当前符号版本不对,使用/u开关先卸载之再重新加载。符号验证:上面讲到.reload的时候,我们说过,符号文件会出现不匹配的情况。这是很有可能的,程序员在后期测试的时候可能会将工程多次编译,为了维护多个版本而使得自己也被搞混。可以使用下面的命令验证一个模块的符号文件: !chksym
50、 符号名加载选项:!sym有两类符号加载选项。第一类是Noisy/Quiet,Noisy选项将打印符号加载的详细信息,Quiet选项则忽略这些信息。第二类是Prompts/Prompts off,即是否允许执行提示(Prompts)对话框。一般都是在调用.reload 命令之前,执行加载选项命令,以见立竿见影之效。所谓Noisy是吵闹的意思,调试器在搜索、加载符号的时候,会显示更多与搜索有关的信息。而安静模式下,则不会显示这些信息。不管吵闹与否,都不会影响到最终的搜索、加载结果。当从网络上下载符号文件的时候,可能会碰到网络服务器要求客户进行安全认证的情况,如果开启Prompts选项,则弹出认证
51、对话框,让用户输入认证信息;否则,不弹出对话框,并且不会下载符号文件。不加任何参数的情况下,显示当前加载选项设置,下面的清单表明当前的设置为Quite及Prompts模式:lkd !sym!sym - quiet mode - symbol prompts on2.5 符号搜索符号搜索包括全局搜索和就近搜索两种。全局搜索:命令“x”被用来进行符号的全局搜索,你可以把它直接就理解为search。格式如下: x 参数 模块!符号如果什么参数都没有的话,它将列出当前调试环境下的所有局部变量,前提是要在有局部变量存在的情况下,显示局部变量的另一个命令是dv,后文也会讲到。 x kernel32!a*,
52、上面命令搜索并打印出kernel32模块中所有a开头的符号。x命令支持DML,使用/D选项即以DML格式显示。如果你不知道ntcreatefile这个函数是在哪个模块中定义的,可以试着使用下面的命令: x *!*NtCreateFile* (注:亦请参照!dlls c命令)同名函数在多个系统模块中并定义,这可能出乎你的意料,但却给你带来真正的知识。此外,x命令有多个可选参数。建议总是带上/t和/v,可显示更多符号、类型信息。 /f:将只显示函数符号;并且会显示函数的详细定义。 /d:显示更多的变量类型相关信息。就近搜索如果知道了符号的大概地址,但不能确定确切的符号名称,该怎么处理呢?就近查找命
53、令ln能发挥作用,ln是List Nearest的缩写。它的作用是:(根据给定的地址)列出附近一定范围内的所有符号。下表中,指定地址0x7c8179f0的前后各有一个符号被找到:0:000 ln 7c8179f0(7c8179c3) kernel32!NlsServerInitialize+0x29 | (7c8179fe) kernel32!AllocTables2.6 源码命令如果含有源码信息,可使得调试过程能够以源码模式逐行进行。和源码相关的命令包括下面几个:源码路径:和符号路径类似,要设置源码路径,使用如下语法格式: .srcpath+ 路径1;路径2不含任何参数的情况下,显示当前设置的源码路径。下面命令将覆盖原设置,设置新的源码搜索路径: .srcpath 使用“+”可以将新的路径添加到原设置中,而不会把原设置覆盖掉:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2026学年关节对齐说课稿语言
- 2025-2026学年三年级写小狗的说课稿
- 2025-2026学年大海龟儿歌说课稿
- 2025-2026学年光影手指精灵说课稿
- 2025-2026学年工作写法说课稿
- 2026下半年初中化学教资面试元素专项题库及解析
- 2025-2026学年二十二课诗二首的说课稿
- 个人所得税六项专项附加扣除
- 2026-2027学年人教版九年级英语上册状语从句专项练习(Unit1-8含答案)
- 2025-2026学年三年级上册司马光说课稿
- 2025年中级安全工程师《化工安全》考试真题及答案解析
- 《长颈鹿与小鸟》教学设计-北师大版小学二年级数学上册第九单元第一课时
- 风电工程安全技术规程
- 2.5 跨学科实践:制作隔音房间模型 课件(内嵌视频)2025-2026学年人教版物理八年级上册
- 《濒危野生动植物种国际贸易公约》附录中文版2026
- 秦始皇陵课件
- 船舶维修作业安全管理规范
- 女童保护课件
- 宠物超声教学课件
- DB14∕T 3151-2024 公路钢波纹管涵洞施工技术规程
- 人工智能导论知到智慧树章节测试课后答案2024年秋天津大学
评论
0/150
提交评论