windbg查阅资料(持续更新)

打开dump文件,选择“file->Open Crash Dump… ” 打开dump文件。
.lastevent 命令显示最近一次发生的异常或事件。

异常错误码查询

异常 描述
EXCEPTION_ACCESS_VIOLATION 0xC0000005 程序企图读写一个不可访问的地址时引发的异常。例如企图读取0地址处的内存。
EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008C 数组访问越界时引发的异常。
EXCEPTION_BREAKPOINT 0x80000003 触发断点时引发的异常。
EXCEPTION_DATATYPE_MISALIGNMENT 0x80000002 程序读取一个未经对齐的数据时引发的异常。
EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008D 如果浮点数操作的操作数是非正常的,则引发该异常。所谓非正常,即它的值太小以至于不能用标准格式表示出来。
EXCEPTION_FLT_DIVIDE_BY_ZERO 0xC000008E 浮点数除法的除数是0时引发该异常。
EXCEPTION_FLT_INEXACT_RESULT 0xC000008F 浮点数操作的结果不能精确表示成小数时引发该异常。
EXCEPTION_FLT_INVALID_OPERATION 0xC0000090 该异常表示不包括在这个表内的其它浮点数异常。
EXCEPTION_FLT_OVERFLOW 0xC0000091 浮点数的指数超过所能表示的最大值时引发该异常。
EXCEPTION_FLT_STACK_CHECK 0xC0000092 进行浮点数运算时栈发生溢出或下溢时引发该异常。
EXCEPTION_FLT_UNDERFLOW 0xC0000093 浮点数的指数小于所能表示的最小值时引发该异常。
EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001D 程序企图执行一个无效的指令时引发该异常。
EXCEPTION_IN_PAGE_ERROR 0xC0000006 程序要访问的内存页不在物理内存中时引发的异常。
EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094 整数除法的除数是0时引发该异常。
EXCEPTION_INT_OVERFLOW 0xC0000095 整数操作的结果溢出时引发该异常。

如果蓝屏的话,可以输入!anaylze -v 命令。来获取当前异常的详细信息。

k 显示给定线程的调用堆栈,以及其他相关信息
~0 k 表示打印0号线程的调用堆栈,直接用k表示打印当前线程的调用堆栈

u命令 显示指定的内存中的程序代码的反汇编。如果存在符号文件,可以直接加函数名。函数只支持全名。
u user32!SendMessagew

ub 指示要反汇编的区域是向后计算的。反汇编区域是以address结束的8或9条指令
ub address L length

uf命令显示内存中指定函数的反汇编代码。

x命令显示所有上下文中匹配指定模板的符号。可用字符通配符。在函数断下来后输入x,会自动打印当前的局部变量,可以配合frame使用。

一个井号(#)匹配零个或多个前一个字符,一个加号(+)匹配一个或多个前一个字符

如果使用#、?、[,] 、*、+字符本身,必须在这些字符前面加一个反斜杠()。

/v 命令可以帮助更好理解二进制文件的内容,它将按照对象或函数所占的字节数以升序来列出序号的类型和大小

.cls 清屏

? 列举所有基本命令

.help [/D] 列举所有原命令

!模块名.help 列举指定扩展模块的所有扩展命令

.chain[/D] 给出扩展命令集的链表。前两行显示扩展模块的搜索路径,后面列出自带的扩展模块。

.load/.unload 动态加载/卸载第三方扩展调试模块

u [地址] 进行反汇编

ub [地址] 倒着反汇编

uf [函数地址]: 对nt模块的函数进行反汇编

uf[模块名!函数地址]:反汇编函数

uf /i [函数地址/模块名!函数地址]:反汇编并显示共有多少条指令

ln 地址 搜索距离指定地址最近的符号

.dml_flow 地址A 地址B 从地址A到地址B进行反汇编,能画出流程图

!dml_proc [进程号|进程地址] 内核模式下用于查看指定进程信息,用户模式下只能查看被调试进程信息

version 查看软件版本呢、启动参数、软件设置命令

vertarget 列出当前调试系统的版本系统

.time 查看系统时间,以及系统正常运行持续时间,用户模式下还会显示当前进程的持续时间

n [8|10|16] 查看当前数字进制/修改数字显示为8/10/16进制

.effmach[x86/amd64/ia64/ebc] 查看当前处理器模式/修改处理器模式为x86/amd64/ia64/ebc

在Processes and Threads工作窗口下可以查看系统序号、进程序号、线程序号
切换当前调试系统:
||s
切换当前调试进程:
|s
切换当前调试线程:
~s

x64切换到x86模式下:
.load wow64exts
!sw
再切换回x64模式下:
!ws

.formats 整数
将一个整数以各种模式显示,包括:16进制、10进制、8进制、二进制、字符串、日期、浮点数等

将windbg调试器附加到进程上:
.attach PID
windbg -p PID
windbg -pn 进程名

用windbg调试器启动进程调试:
.create 程序启动命令行
windbg 程序启动命令行

.dump 文件名
保存到dump文件

.dump /ma “d:\mydumpfile.dmp”
将当前调试进程输出到dump文件

.opendump 文件名
打开dump文件

.detach
结束当前调试会话,解挂后,被调试进程能够独立运行

qd
结束当前调试会话,解挂后,被调试进程能够独立运行

q|qq
结束调试,windbg和被调试进程一起关闭

.crash
内核调试时引发一个系统蓝屏,并生成dump文件

.reboot
内核调试时使系统重启,不产生dump文件

查看当前堆栈:
1.kv
提示FPO信息,ChildEBP、retaddr、前三个参数
2.kb
ChildEBP、retaddr、前三个参数
3.kp
全参数(需要所有符号)

e命令修改内存:
eb/ed/eq [地址]数值
ea [地址] 数值 ASCII字符串
eu [地址] 数值 UNICODE字符串

Im/lmD:
lm [选项] [a Address] [m Pattern |M Pattern]
lmD [选项] [a Address] [m Pattern | M Pattern]
(1)/v选项能列出模块的详细信息
(2)参数[a Address]只有指定地址所在的模块能够被列出
(3)参数[m Pattern | M Pattern]通过模块名称通配符列出模块

demo:
lm m o 将显示所有名称中包含字母o的模块
lmva 00400000 显示地址00400000所在模块的详细信息
lmvm nt 显示名字中包含nt的模块的详细信息(注意exe、dll等都不要带后缀名)
lmf 显示所有模块的信息(包含模块的文件路径)
!lmi uxtheme uxtheme.dll的详细调试文件(PDB)信息
lmv 列出所有模块(加载和未加载)对应的符号信息

!dlls [选项][LoaderEntryAddress]
选项:
-i/-l/-m:排序方式,分别按照初始化顺序、加载顺序、内存起始地址顺序排列
-a: 列出镜像文件PE结构的文件头、Section头等详细信息
-c LoaderEntryAddress:指定函数所在的模块

.reload /l 列出模块

!imgreloc 列出模块列表并显示模块是否处于preferred地址范围内

!lmi 地址 获取地址所在的模块对调试器有用的信息

!dh 模块地址 显示模块的PE头信息

!dh -a 模块地址 显示模块的PE结构详细信息,包括导入导出表内的函数

.sympath 显示当前符号路径

.syspath [路径] 设置符号路径

.syspath+[路径] 增加新的符号路径
注:使用.sympath改变符号路径之后,需要用.reload更新已加载的符号文件
.sympath+ SRVD:\symbols\currentsymbolshttp://msdl.miscrosoft.com/downloads/symbols

.symopt 查看当前符号选项

.symopt +/-Flags 开启/关闭符号选项

ld 模块名[/f 符号文件名]
调试器默认采用延迟模式加载符号,ld使得延迟模式被打破,让指定模块的符号文件立刻加载到调试器中。/f表示即使符号不匹配也要强制加载。此指令可为模块的符号文件设置自定义的匹配名称。
ld 123 /f abc
强制将abc.pdb作为123.exe的符号文件
ld kernel32
强制加载kernel32模块的符号文件

.reload 为所有已加载模块载入符号信息

.reload命令的作用是删除指定或所有已加载的符号文件,默认情况下,调试器不会立刻根据符号路径重新搜索并加载新的符号文件,而是推迟到调试器下一次使用到此文件时

.reload [参数][模块名]
参数:
/u:卸载符号
/f:迫使调试器立刻搜索并重新加载新的符号文件
/v:将搜索过程中的详细信息都显示出来
/i:不检查pdb文件的版本信息
/l:只显示模块信息
/n:仅重载内核符号,不重载用户符号
/o:强制覆盖符号库中的符号文件,即使版本相同
/d:用户层模式下使用windbg时的默认选项,重载调试模块列表中的所有模块;
/s: 内核模式下使用windbg时的默认选项,重载系统模块列表中的所有模块,另外,如果调试器再用户模式下运行,要加载内核模式,也必须使用/s选项,否则调试器将只会在调试器模块列表中搜索而导致找不到内核模块
/u:卸载指定模块。如发现当前符号版本不对,使用.u开关先卸载之再重新加载

.reload /f 用户/内核模式下强制重新加载符号文件
.reload /f /user 内核模式下强制重新加载用户层程序的符号文件
.reload /u 卸载所有符号
.reload /i 重新加载不匹配符号的模块(dmp文件没有对应的pdb时使用)
.reload /i 重新加载不匹配符号的模块(dmp文件没有对应的pdb时使用)
.reload /i Game.exe 重新加载不匹配符号的TGame.exe
.reload /f @"c:\windows\System32\verifier.dll"为指定模块加载符号信息
.reload /f TGame.exe为TGame.exe加载符号信息

!chksym <模块名>[符号名] 验证一个模块的符号文件

符号全局搜索:
x[选项] 模块名!符号名
选项:
/D:以DML格式显示
/f:将只显示函数符号,并且会显示函数的详细定义
/d:显示更多的变量类型相关信息
/t:显示符号的数据类型
/v:显示符号的类型和大小

控制显示结果的排列顺序:/a和/A分别按地址的升序和降序,/n和/N分别按名称的升序和降序,/z和/Z分别按符号大小的升序和降序

模块名和符号名动可以包含通配符。*代表0或任意多个字符,?代表任一单一字符,#代表前面的一个字符可以出现任意次,如果中间允许多个字符重复,用方括号。

x kernel32!a*
x /D !NtCreateFile
x MyModule!GlobalVariableName 查看模块MyModule中名为GlobalVariableName的全局变量
x !列出所有模块对应的符号信息
x ConsoleTest!
列出Console Test模块中的所有符号
x ConsoleTest!add
列出ConsoleTest模块中的所有add开头的符号
x /t /v ConsoleTest!* 带数据类型、符号类型和大小信息,列出ConsoleTest模块中的所有符号
x kernel32! LoadLib 列出kernel32模块中所有含LoadLib字样的符号

.srcpath 显示当前源码路径

.srcpath <路径信息>
设置源码路径

.srcpath+/- <路径信息>
添加/删除源码路径

.srcnoisy[1|0]
显示/开启/关闭"嘈杂的源码"(在调试时会显示很多信息)

代码行选项:
l+[选项] 打开
l-[选项] 关闭
l+t 源代码模式
l-t 汇编模式
l+* 打开所有行选项(效果会很不错)

查看进程简略信息:
.tlist [选项][进程名]
显示当前系统中的进程列表/显示指定进程名的进程信息,内核模式和用户模式都可使用
.tlist -v 显示进程详细信息
.tlist -c 只显示当前进程信息

内核模式下查看进程详细信息
!process 显示进程信息
!process PID 获取进程号为PID的进程信息
!process -1 0 获取当前进程的简略信息
!process 0 0 SoftMgr.exe获取进程名为SoftMgr.exe的信息
!process 0 7 查看所有进程的详细信息
!process ERPOCESS地址 查看进程信息
!process ERPOCESS地址 0 获取进程简略信息
!process ERPOCESS地址 7 查看进程详细信息

查看进程环境块:
!peb 用户模式下显示当前进程的PEB信息
!peb [peb地址] /dt nt!_peb [PEB地址]
内核模式下显示环境块详细信息(内核模式下可通过!process命令获取PEB地址)

内核模式下进程切换
.process 显示当前进程EPROCESS地址

.process [EPROCESS地址] 切换进程

.context 显示当前页目录地址

.context [页目录地址]
切换页目录地址,页目录地址就是!process命令中显示的DirBase值

内核模式下线程切换
.thread [ETHREAD地址]

~ 列出当前被调试进程的所有线程
~2 查看2号线程信息
~2s 切换到2号线程
~~[11a0]s 切换到线程ID为11a0的线程

~2f 将2号线程冻住(freeze)
~2u 将2号线程解冻(unfress)
~2n 增加2号线程的挂起技术(suspend)
~2m 减少2号线程的挂起计数(resume)

!teb[TEB地址] 查看线程环境块信息

~k 显示当前线程的线程栈信息
~2k 显示2号线程的线程栈信息
~*k 显示所有线程栈信息

~r 显示当前线程的寄存器信息
~2r 显示2号线程的寄存器信息
~*r 显示所有线程的寄存器信息

~*e 对每个线程执行指定命令
~*e k;r 对每个线程中,分别执行k指令(栈指令)和r指令(寄存器指令)

显示线程运行时间,显示当前线程的创建日期、用户模式时间、内核模式时间
.ttime

!runaway 7 显示所有线程的用户模式时间、内核模式时间、总运行时间

sx 列出针对当前调试目标的异常或非异常事件的处理

sxr 恢复到对调试事件的默认设置

.lastevent 显示最近发生的一次调试事件

sx{e|d|n|i}[-c “Cmd1”][-c2 “Cm2”][-h]{Exception|Event|*}
(1)没有-h开关,就是设置中断状态,其中e|d|n|i分别对应着Enabled|Disabled|Output|Ignore

Enabled:第一轮和第二轮都中断给用户
Disabled:第一轮不中断,第二轮中断
Output:输出信息通知用户,不中断
Ignore:忽略事件,不中断
如果有-h开关,就是设置处理状态,sxe命令设置的处理状态是Handled,其他sxd|sxn|sxi都是设置为Not Handled

(2)-c和-c2分别用来定义第一轮处理和第二轮处理的关联命令

(3)Exception|Event|*用来指定命令所针对的是异常或者事件

加载内核模块时下断
sxe Id:MyDriver 驱动加载前下断
sxn ld:MyDriver 驱动加载时不会中断,但会显示一条相关信息
sxi ld:MyDriver 取消对加载时的设置

卸载驱动时下断
sxe ud:MyDriver 驱动卸载前下断
sxn ud:MyDriver 驱动卸载时不会中断,但会显示一条相关信息
sxi ud:MyDriver 取消对MyDriver卸载时的设置

当调试器因异常而中断时,可以返回与设置不同的状态:
gh 异常已经处理(Handled)
gn 异常没有处理(Not Handled)\

.bugcheck 内核模式下显示当前bug check的详细信息

!analysis -v 显示最近异常事件的详细信息

!analysis -hang 分析死锁。另一个分析死锁的命令是!locks
内核模式下,分析内核锁和DPC栈
用户模式下,分析线程的调用栈

!analysis -show bug_check-代码[参数]
内核模式下显示指定bug check的详细信息

!error 查看错误码
获取错误码为2的win32错误信息,可用:!errror 2
获取错误码为2的NTSTATUS错误信息,可用:!error 2 1

!gle 针对当前线程调用win32接口函数GetLastError()取得线程的错误值,并打印分析结果

!gle -all 用户模式下针对所有线程,内核模式下针对所有用户线程,执行GetLastError()

源码调试下获取局部变量:
x和dv都可以直接列出当前局部变量的简略信息
dv[选项][局部变量名]
/v 显示虚拟地址
/i 显示变量详细信息
/t 显示变量类型,如int、char等
/f 指定进行分析的函数

bp /p ERPOCESS地址 地址
内核模式下对EPROCESS进程的用户空间的地址下断

bp /t ETHREAD地址 地址
内核模式下对ETHREAD线程的用户空间的地址下断

bm /a ntdll!NtCreate*File 批量设置代码断点

be Access Size Address 下硬件断点

Access可以是r/w/e/i
Size在x86系统可选值为1/2/4,x64系统可选值为1/2/4/8
Address值必须是Size的整数倍

bl 列出断点
bd 禁止断点
be 恢复断点
bc 清楚短点

d[类型] [地址范围]
基本类型:
dw 双字节WORD
dd 4字节DWORD
dq 8字节
df 4字节单精度浮点数
dD 8字节双精度浮点数
dp 指针大小格式,32位下4字节,64位下8字节

字符串:
da ASCII字符串
du UNICODE字符串
db 字节+ASCII字符串
dW 双字节WORD+ASCII字符串
dc 4字节DWORD+ASCII字符串
ds ANSI_STRING格式
dS UNICODE_STRING格式

数组:
dd*/dq*/dp*4字节/8字节/指针长度的数组
dda、ddp、ddu、dds、dqa、dqu、dqs、dpp、dpu、dps
链表(LIST_ENTRY/SINGLE_LIST_ENTRY):
dl 开始地址 从头到尾遍历链表
dl b尾地址 从尾到头遍历链表
其他:
/p 内核模式下此选项用来显示物理内存信息,不使用此选项将显示虚拟内存信息

!address 显示进程或系统的内存状态与信息
用户模式下列出0x0-0x80000000的全部地址空间信息
内核模式下列出地址0x80000000-0xFFFFFFFF的全部地址空间信息
!address [地址]
显示此地址所在内存块的信息
!address -summary 显示内存信息概览

!address -f:MEM_COMMIT -c “s -a % 1 %2 " asdfasdfasdf”;s -u %1 %2 “asdfasdfasdf”
在所有MEM_COMMIT的内存中搜索字符串"asdfasdfasdf",包括宽字符串和多字节字符串

!address -? 显示指令帮助

!vport [地址] 用户模式显示指定内存块信息,侧重于内存保护信息

!vadump [-v] 用户模式显示整个内存空间信息,使用-v选项将显示详细信息

!memusage 从物理内存角度显示内存统计信息

!vm 从虚拟内存角度显示内存统计信息,不仅能从全局角度显示虚拟内存的使用,还能以进程为单位显示内存使用情况

!fileache 内核模式下显示文件缓存和页表状态

!heap -a 用户模式下查看堆信息,显示每个堆的地址范围以及被申请提交的大小

!heap -p -a 00530B98 查看地址00530B98在哪个堆分配空间中

!heap -a 00530000 查看堆分配空间00530000的堆块信息

将windbg中命令的输出保存到文本文件中:

  1. .logopen d:/dump.txt 将显示结果放到文件中
  2. 运行想要输出到文本中的命令
  3. .logclose d:/dump.txt 关闭文件
  4. .logfile 查看是否还有打开的日志记录

在查看ssdt表和shadowssdt表之前一定要加载好符号
查看ssdt和shadowssdt:
1.x nt!kesdestable*:得到ssdt和shadowssdt的地址
2.dd地址:查看表数据
3.dds地址:查看符号表

蓝屏分析:
1.打开虚拟机的dump功能
右键"我的电脑"->属性->高级系统设置->启动和故障恢复 设置->写入调试信息 核心内存转储->确定->退出
2.这时,如果电脑蓝屏,会转储核心内存为C:\Windows\MEMORY.DMP文件,在蓝屏的最后一行显示转储进度(Dumping physical memory to disk :80),并在重启后可以发现该文件。
如果sys文件在系统开机时启动,为防止蓝屏,可以开机时,按f8,进入安全模式,然后查看C:\Windows\MEMORY.DMP文件
3.将dmp文件拷贝到实机
4.打开windbg,菜单栏File->Open Crash Dump…,选择dmp文件
5.设置windbg的符号链接
6.在windbg命令中输入!analyze -v,即可分析出问题的原因
7.在windbg命令行中输入.open -a自己的引发错误的模块名!引发错误的函数+偏移,即可定位到引起错误的源代码位置
例如:open -a MyModel!OpenUnicodeStr+0x2a .open -a DriverToDump!DriverEnTRY+2b
8.kv/kp/kb

R0与R3联调
1.!process 0 0 获取用户空间进程块地址或者!process 0 0 SoftMgr.exe就可以直接得到进程SoftMgr.exe的信息
2.输入.process /p + EProcess地址 切换应用程序的地址空间
3.如果时x64的系统上调试x86的程序,则输入.effmach x86 切换到x86模式,也可以.effmach amd64切换回x64模式。直接输入.effmach可以查看当前模式
4.在符号链接中添加user程序的PDB文件,但不要点击重新加载选择框,然后在命令行输入.reload /f /user,就算没有符号表,也要输入.reload来加载和同步当前用户层内容
5.在windbg打开应用层源文件
6.下应用层断点,打开R3程序的源代码,按F9下断点

单步步入t指令
tc 继续运行知道call指令停止
tt 继续运行直到ret指令停止
tct 就绪运行知道call或者ret指令停止
th 继续运行直到跳转指令停止,跳转指令包括call ret 有条件无条件跳转等
ta [地址] 继续运行程序直到指定地址到达为止
t 单步步入

单步步过p指令
pc 继续运行直到call指令停止
pt 继续运行直到ret指令停止
pct 继续运行直到call或着ret指令停止
ph 继续运行直到跳转指令停止,跳转指令包括call ret有条件无条件跳转等
pa [地址] 继续运行程序直到指定地址到达为止
p 单步步过

1.ta [r][=StartAddress] StopAddress
从StartAddress开始执行,到StopAddress为止执行的指令就像单步按t一样显示出来,如果是tar则不显示寄存器值

2.pa [r][=StartAddress] StopAddress [“Command”]
从StartAddress开始,到StopAddress为止执行过的指令就像单步按p一样显示出来,如果par则不显示寄存器值
demo:
pa 0x401890
从当前地址开始执行,执行到0x401890之前的所有指令都打印出来
par = 0x00401124 0小01890
立刻从地址0x00401124开始执行,到0x401890地址期间执行过的所有指令都会打印处理啊,并且不显示寄存器值

最好的使用方法是:
在StartAddress和StopAddress处下断点,StartAddress处断下时,执行par stopAddress,执行完后,StopAddress处断下

无符号驱动模块360FsFlt的入口点中断:
1.sxe ld:360FsFlt
在加载360FsFlt模块的时候会在DebugService函数里中断下来
2.lm m 360FsFlt 查看360FsFlt的起始地址
3.!dh -a 360FsFlt的PE文件,在address of entry point处会显示入口点地址偏移(该入口点并不是DriverEntry,是导出的Start)
如果分析失败,则通过ida调整基地址后获取需要下断点的地址并直接用bp下断即可
4.bp 360FsFlt的起始地址+入口地址偏移
在360FsFlt的入口点处下断点

查找字符传:
s -[type] range pattern
(1)type可以是 b w d a u,默认为b
(2)range表示范围,有两种方式表示,一是起始地址+空格+终止地址,二是起始地址+空格+L+长度,如果搜索长度超过256MB,则用起始地址+空格+L?+长度
(3)pattern用于指定要搜索的内容,可以用空格分隔要搜索的数值
demo:

  1. s-sa
    s-sa 00000000`01360000 L00000000`0007b000
    显示000000000`1360000 开始的长度为00000000`0007b000

s-sa 00000000`01360000 00000000`013db000 显示00000000`01360000为起点00000000`0007b000为终点的内存范围内所有的ASCII字符串

2.s-su
s-su 00000000`01360000 L00000000`0007b000 显示00000000`01360000开始的长度为00000000`0007b000的内存范围内所有的UNICODE字符串

s-su 00000000`01360000 00000000`013db000 显示00000000`01360000为起点00000000`0007b000为终点的内存范围内所有的UNICODE字符串

3.s -a
s -a 00000000`01360000 L00000000`0007b000 “Windows” 在00000000`01360000开始的长度为00000000`0007b000的内存范围内搜索ASCII字符串"Windows"的地址

s -a 00000000`01360000 00000000`013db000 “Windows” 显示00000000`01360000为起点00000000`0007b000为终点的内存范围内搜索ASCII字符串"Windows"的地址

4.s -u
s -u 00000000`01360000 L00000000`0007b000 “Windows” 在00000000`01360000开始的长度为00000000`0007b000的内存范围内搜索UNICODE字符串"Windows"的地址

s -u 00000000`01360000 00000000`013db000 “Windows” 显示00000000`01360000为起点00000000`0007b000为终点的内存范围内搜索UNICODE字符串"Windows"的地址

6.s -a 0x0 L?0x7fffffff mytest 在目标空间为2G的user mode内核空间中搜索ASCii字符串"mytest"

.readmem [文件路径][地址范围]
将文件内容拷贝到被调试目标内存
.writemem [文件路径][地址范围]
从被调试目标内存拷贝到文件

显示指定进程块fffffa8003cdeb00的安全描述符信息
(1)dt_OBJECT_HEADER SecurityDescriptor fffffa8003cdeb00 显示安全描述符地址0xfffff8a00000463b
(2)!sd 0xfffff8a000004630
显示安全描述符详细信息

(1)!process 0 1 进程名 显示出Token的地址
(2)!token Token地址 显示Token详细信息

!exchain 显示当前的异常处理程序链

!cs 列出CriticalSection的详细信息

!idt 查看中断向量表内容

!handle 查看所有句柄的ID
!handle 000007f8 1 查看ID为000007f8的句柄的类型
!handle 000007f8 4 查看ID为000007f8的句柄的名称
!handle 0 5 查看所有句柄的类型和名称

.frame 显示当前栈帧
.frame n 设置编号n的栈帧为当前栈帧
.frame /r n 设置编号n的栈帧为当前栈帧 并显示寄存器变量
!unigstack 显示所有线程的调用堆栈

1.获取\driver\acpi驱动对象的新戏
demo: !object \driver\acpi

2.查看对象OBJECT_HEADER信息
demo:dt nt!_OBJECT_HEADER 0x963dcbf0

3.dt nt!_object_header_name_info 0x863dcbf0-0x10
查看对象名

4.查看对象体信息
dt nt!_DRIVER_OBJECT 0x863dcbf0+0x18

5.直接查看驱动对象的信息
!drvobj 0x863dcbf0 +0x18

6.查看Driver类型对象信息
dt nt!_OBJECT_TYPE 0x86409838

页堆
1.开启页堆,开启该机制,堆溢出时就立刻出发异常
!gflag+hpa
!gflag -i app.exe + hpa
2.关闭页堆
!gflag -hpa
!gflag -i app.exe -hpa
3.查看是否gflag开启了哪些调试选项
!gflag

设置windows虚拟机的调试端口
1.设置虚拟机的调试端口为\.\pipe\com_1
2.管理员权限打开windows虚拟机的cmd
3.在cmd中输入命令
bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200
4.重启计算机

调试模式下运行虚拟机时让windbg不再显示无用信息:
每次调试模式打开虚拟机时,在第一个断点处输入
ed nt!Kd_SXS_Mask 0
ed nt!Kd_FUSION_Mask 0 #这条可有可无,就是没理解清楚

x86调用约定:
__stdcall:参数从右到左压入堆栈,被调用函数自身修改堆栈
__cdecl:参数从右到左压入堆栈,调用函数自身修改堆栈,所以可以支持变参函数
fastcall:第一个参数和第二个参数通过ecx和edx传递,剩余参数从右到左压入堆栈,被调用者还原堆栈
thiscall:如果参申诉个数确定,C++类成员缺省约定,参数从右到左压入堆栈,this指针通过ecx传递,被调用者清理堆栈;如果参数个数不确定,this指针在所有参数压栈后被压入堆栈,调用者清理堆栈。

x64调用约定:
前四个参数存放到rcx、rdx、r8、r9上,但在栈上也会预留4个参数空间。
参数入栈会对齐到8个字节。
调用者负责平衡堆栈。

无中断:
PASSIVE_LEVEL->常规线程执行
软中断:
APC_LEVEL->异或过程调用执行
DISPATCH_LEVEL->线程调度
硬中断:
DIRQL->设备中断
PROFILE_LEVEL
CLOCK2_LEVEL
SYNCH_LEVEL
IPI_LEVEL
POWER_LEVEL

DriverEntry、DriverUnload->Passive级
各种分发函数->Passive级
完成函数->Dispatch级
各种NDIS回调函数->Dispatch级

部分常用机器码:
eb->short jump e9->near ea->far jump
je/jz->74
jne/jnz->75
nop->90
int 3->cc
ret ->c3

kb 显示 cakk stack内容
kv.bugcheck 可以显示出错的代码

lmf 列出当前进程中加载的所有dll文件和对应的路径

本地内核调试(lkd)
管理员权限启动windbg,ctrl+k->local

!handle 查看句柄

r tr 查看当前任务门

!idt -a 查看中断描述表

kv 查看栈回溯

ln 可以查看最后跳转

!uniqstack 扩展命令显示当前就能成中所有线程的调用堆栈,除开重复的那些。

!teb 扩展以格式化后的形式显示线程环境块(TEB)的信息。

.kframes 命令设置堆栈回溯显示的默认长度。默认20

.heap 查看出错的堆地址。

!for_each_frame dv/t 打印出错函数的局部变量。

!runaway 显示所有线程的CPU小号

!cs 临界对象

!addresss 显示整个地址空间和使用摘要的信息

dd 按字节查看

dt 查看结构

!devnode 0 1 查看即插即用设备树中的所有设备结点。

!devnode 0 9 查看设备结点及其硬件资源。

!devnoide 0 1 disk 查看具有磁盘服务名称的设备节点

~*kb 显示所有线程调用堆栈。

adplus是一个vb script文件,运行CDB(命令行下的WINDBG),负责监视系统中将要发生的异常。使用windbg目录下(C:\Program Files\Debugging Tooks for Windows(x86))的adplus.vbs来抓取dump file。

adplus -hang -p 2960 //当进程2960失去相应时生成dumo
adplus -crash -pn w3wp.exe //在w3wp.exe中止或被回收时生成dump
adplus -crash -pn w3wp.exe -NoDumpOnFirst //不对first chance exceptions生成dump

参数设置
-hang 进程运行时,随时可以使用-hang参数得到一个Dump文件,而不需要考虑线程是否真的处于死锁,用于诊断高内存使用率,高CPU使用率。
在hang模式下,dump file说以非侵入方式被抓取的,并没有中断线程,因此不需要跟启动进程有相同的身份,在客户段调试服务器时,hang模式抓取dump file很有用。

-crash 在进程异常终止时抓取dump file。
进程异常终止有3种情况:
1.unhandled的exception
2.asp.net进程由于iis reset或recycle而终止
3.出现heap毁坏,栈溢出,内存不足等错误,进程必须退出

-pn 指定要分析的进程名。使用多个"-pn process name"开关来指定多个进程。

-o dump file的存储路径,缺省位adplus所在路径

-FullOnFirst create full dumps on first chance exceptions

-NoDumpOnFirst 如果exception被try -catch block处理,使用这个参数就不会生成dump file

-quiet No dialog boxes will be displayed

当程序抛出异常(.net或native exception),此时这个exception为 1st chance exception,吐过这个exception没有被try-catch block处理,这个exception就会成为2nd chance exception(unhandled exception)当前进程随后终止。

user-mode Mini Dump,保存了进程crash时virtual memory的部分内容。有些SOS的命令在Mini Dump上不能工作。Mini Dumpe的内容和大小和被dump的程序有关。Mini Dump所包含的信息并不一定比Full Dump少。

ADPlus_report.txt 记录adplus Attach到进程以后的信息

!devobj 地址 查看设备对象信息
!drvobj 查看驱动对象信息
!devstack 查看设备栈
!devnode 0 1 系统设备树

你可能感兴趣的:(windbg,内核,windows)