Windows编程调试技术内幕
第 一部分 背景
第 1章 Windows软件开发 3
1.1 Windows发展过程 3
1.1.1 Windows版本历史 3
1.1.2 支持的CPU架构 4
1.1.3 Windows版本特性 5
1.1.4 Windows服务术语 5
1.2 Windows架构 6
1.2.1 内核态与用户态 6
1.2.2 用户态系统进程 7
查看完整
第 1章 Windows软件开发 3
1.1 Windows发展过程 3
1.1.1 Windows版本历史 3
1.1.2 支持的CPU架构 4
1.1.3 Windows版本特性 5
1.1.4 Windows服务术语 5
1.2 Windows架构 6
1.2.1 内核态与用户态 6
1.2.2 用户态系统进程 7
查看完整
塔里克·索拉米(Tarik Soulami)是Windows基础团队首席开发主管,曾在微软从事过10余年的系统级软件设计和开发工作。加入Windows基础团队之前,他曾在通用语言运行平台(CLR)团队工作,参与了微软.NET框架早期版本的开发。
这是一本介绍 Windows 编程调试技术的书。本书简述了 Windows 开发框架和操作系统中的层。在用调试和跟踪工具发现数据意义时,这些基础知识非常重要。本书还谈到了“调试的乐趣和好处”,描述了 Windows 操作系统中调试器的架构,并介绍了一些可扩展的策略,以帮助你充分利用 Windows 的调试器。本书还展示了 WinDbg 调试器的用法,通过分析代码和操作系统之间的重要相互作用来帮助你更好地了解系统内核。*后,本书就“观察和分析软件的行为”展开讨论,介绍了 Windows 事件跟踪(ETW)技术,并说明了在调试和分析调查中利用 ETW 技术的方法。
本书适合程序员、安全人员、软件测试人员阅读,也可以作为大专院校相关专业的教学用书和机构的培训用书。
本书适合程序员、安全人员、软件测试人员阅读,也可以作为大专院校相关专业的教学用书和机构的培训用书。
第 一部分 背景
第 1章 Windows软件开发 3
1.1 Windows发展过程 3
1.1.1 Windows版本历史 3
1.1.2 支持的CPU架构 4
1.1.3 Windows版本特性 5
1.1.4 Windows服务术语 5
1.2 Windows架构 6
1.2.1 内核态与用户态 6
1.2.2 用户态系统进程 7
1.2.3 用户态应用进程 8
1.2.4 低级别的Windows通信机制 11
1.3 Windows开发人员接口 13
1.3.1 开发人员文档资源 13
1.3.2 WDM、KMDF和 UMDF 14
1.3.3 NTDLL和USER32层 14
1.3.4 Win32 API层 15
1.3.5 COM层 15
1.3.6 CLR(.NET)层 20
1.4 微软开发工具 22
1.4.1 Windows驱动程序开发工具包(WDK) 23
1.4.2 Windows软件开发工具包 23
1.5 小结 23
第二部分 调试的乐趣和好处
第 2章 入门 27
2.1 调试工具介绍 27
2.1.1 获取Windows调试器软件包 27
2.1.2 获取Visual Studio调试器 31
2.1.3 WinDbg和Visual Studio调试器对比 31
2.2 用户态调试 32
2.2.1 使用WinDbg调试你的第 一个程序 32
2.2.2 列举局部变量和函数参数值 39
2.2.3 WinDbg中的源码级调试 43
2.2.4 符号文件、服务器和本地缓存 44
2.2.5 WinDbg符号离线缓存 45
2.2.6 WinDbg中符号解析问题的故障排除 46
2.2.7 名称修饰注意事项 46
2.2.8 获取WinDbg命令的帮助 48
2.3 内核态调试 49
2.3.1 你的第 一个(实时)内核态调试会话 50
2.3.2 使用物理机建立一个内核态调试环境 55
2.3.3 使用虚拟机设置内核态调试环境 60
2.3.4 诊断主机/目标机通信问题 62
2.3.5 理解KD中断序列 63
2.3.6 在内核态调试器中控制目标机 64
2.3.7 在内核态调试器中设置代码断点 66
2.3.8 获取WinDbg内核态调试命令的帮助 68
2.4 小结 68
第3章 Windows调试器是如何工作的 70
3.1 用户态调试 70
3.1.1 架构概述 70
3.1.2 Win32调试API 71
3.1.3 调试事件和异常 72
3.1.4 中断序列 75
3.1.5 设置代码断点 76
3.1.6 观察WinDbg中的代码断点插入 77
3.2 内核态调试 81
3.2.1 架构概述 81
3.2.2 设置代码断点 82
3.2.3 单步执行目标 82
3.2.4 切换当前进程上下文 83
3.3 托管代码调试 84
3.3.1 架构概述 85
3.3.2 SOS Windows调试器扩展 87
3.4 脚本调试 92
3.4.1 架构概述 92
3.4.2 在Visual Studio中调试脚本 93
3.5 远程调试 95
3.5.1 架构概述 95
3.5.2 WinDbg中的远程调试 96
3.5.3 Visual Studio中的远程调试 99
3.6 小结 101
第4章 事后调试 102
4.1 实时调试 102
4.1.1 你的第 一个实时调试实验 102
4.1.2 实时调试是如何工作的 105
4.1.3 使用Visual Studio作为实时调试器 108
4.1.4 运行时断言和实时调试 113
4.1.5 会话0中实时调试 113
4.2 转储调试 114
4.2.1 用户态转储文件自动生成 114
4.2.2 使用WinDbg调试器分析崩溃转储文件 117
4.2.3 使用Visual Studio分析崩溃转储文件 123
4.2.4 手动生成转储文件 124
4.2.5 “时间旅行”调试 125
4.2.6 内核态事后调试 126
4.3 小结 128
第5章 基础扩展 130
5.1 非侵入式调试 130
5.2 数据断点 132
5.2.1 深度分析用户态和内核态数据断点 133
5.2.2 清除内核态数据断点 135
5.2.3 执行数据断点与代码断点 136
5.2.4 用户态调试器数据断点操作:C++全局对象和C运行时库 137
5.2.5 内核态调试器数据断点操作:等待进程退出 139
5.2.6 高级例子:谁在修改注册表值 141
5.3 调试器脚本 145
5.3.1 使用调试器脚本重放命令 145
5.3.2 调试器伪寄存器 146
5.3.3 在调试器脚本中解析C++模板名称 148
5.3.4 脚本实践:在内核调试器中列举Windows服务进程 149
5.4 WOW64调试 150
5.4.1 WOW64环境 150
5.4.2 WOW64进程调试 151
5.5 Windows调试钩子(GFLAGS) 154
5.5.1 系统级与进程相关的NT全局标志 154
5.5.2 GFLAGS工具 155
5.5.3 调试器扩展命令!gflag 157
5.5.4 用户态调试器对NT全局标志值的影响 159
5.5.5 映像文件执行选项钩子 159
5.6 小结 159
第6章 代码分析工具 161
6.1 静态代码分析 161
6.1.1 使用VC++静态代码分析捕获你的第 一个崩溃错误 161
6.1.2 SAL注释 164
6.1.3 其他静态分析工具 167
6.2 运行时代码分析 169
6.2.1 使用应用程序验证器工具捕获你的第 一个错误 170
6.2.2 幕后花絮:操作系统中支持的校验器 172
6.2.3 调试扩展命令!avrf 176
6.2.4 应用程序校验器作为质量保证工具 179
6.3 小结 179
第7章 专家调试技巧 181
7.1 基本技巧 181
7.1.1 等待一个调试器附加到目标 182
7.1.2 加载DLL时中断 184
7.1.3 调试进程启动 188
7.1.4 调试子进程 194
7.2 更多有用的技巧 203
7.2.1 调试错误代码故障 203
7.2.2 在第 一次异常通知时中断 209
7.2.3 冻结线程 210
7.3 内核态调试技巧 212
7.3.1 在用户态进程创建时中断 212
7.3.2 调试用户态进程启动 215
7.3.3 加载DLL时中断 216
7.3.4 未处理SEH异常时中断 217
7.3.5 冻结线程 218
7.4 小结 220
第8章 常见调试场景·第 1部分 222
8.1 调试非法访问 222
8.1.1 理解内存非法访问 222
8.1.2 调试扩展命令!analyze 223
8.2 调试堆破坏 225
8.2.1 调试本地堆破坏 225
8.2.2 调试托管(GC)堆破坏 233
8.3 调试栈破坏 241
8.3.1 基于栈的缓冲区溢出 242
8.3.2 在栈破坏分析中使用数据断点 243
8.3.3 重构损坏栈的调用帧 244
8.4 调试栈溢出 246
8.4.1 理解栈溢出 246
8.4.2 调试命令kf 247
8.5 调试句柄泄露 248
8.5.1 句柄泄露例子 249
8.5.2 调试扩展命令!htrace 250
8.6 调试用户态内存泄露 254
8.6.1 使用应用程序验证器工具检测资源泄露 254
8.6.2 使用UMDH工具分析内存泄露 257
8.6.3 扩展策略:栈跟踪数据库的自定义引用 260
8.7 调试内核态内存泄露 262
8.7.1 内核内存基础知识 262
8.7.2 使用Pool Tagging调查内核态泄露 263
8.8 小结 266
第9章 常见调试场景·第 2部分 268
9.1 调试资源竞争 268
9.1.1 共享状态一致性错误 269
9.1.2 共享状态生命周期管理错误 273
9.1.3 DLL模块生命周期管理错误 281
9.2 调试死锁 284
9.2.1 (锁顺序)Lock-Ordering死锁 285
9.2.2 逻辑死锁 288
9.3 调试访问检查问题 292
9.3.1 基本的NT安全模型 292
9.3.2 Windows Vista的改进 297
9.3.3 结束 300
9.4 小结 301
第 10章 调试系统内部机制 302
10.1 Windows控制台子系统 302
10.1.1 printf背后的魔力 302
10.1.2 Windows UI事件的处理 309
10.1.3 Ctrl+C信号的处理 309
10.2 系统调用剖析 314
10.2.1 用户态一侧的系统调用 315
10.2.2 转换到内核态 317
10.2.3 内核态一侧的系统调用 318
10.3 小结 319
第三部分 观察和分析软件的行为
第 11章 Xperf介绍 323
11.1 获取Xperf 323
11.2 你的第 一个Xperf调查 327
11.2.1 制定一个调查策略 328
11.2.2 收集场景的ETW跟踪 328
11.2.3 分析收集到的ETW跟踪 329
11.3 Xperf的优点和局限性 339
11.4 小结 339
第 12章 ETW内幕 341
12.1 ETW架构 341
12.1.1 ETW设计原则 342
12.1.2 ETW组件 342
12.1.3 特殊的NT内核日志记录会话 343
12.1.4 使用Xperf 配置ETW会话 344
12.2 Windows系统现有的ETW检测 347
12.2.1 Windows内核中的检测 347
12.2.2 其他Windows组件中的检测 350
12.3 理解ETW的Stack-Walk事件 355
12.3.1 启用和查看内核提供者事件的栈跟踪 355
12.3.2 启用和查看用户提供者事件的栈跟踪 358
12.3.3 诊断ETW栈跟踪问题 359
12.4 在你的代码中添加ETW记录 363
12.4.1 ETW事件剖析 364
12.4.2 使用ETW Win32 API记录事件 367
12.5 在ETW中跟踪引导过程 370
12.5.1 在引导过程中记录内核提供者事件 371
12.5.2 在引导过程中记录用户提供者事件 373
12.6 小结 375
第 13章 常见的跟踪场景 376
13.1 分析阻塞时间 376
13.1.1 ETW的CSwitch和ReadyThread事件 377
13.1.2 使用Visual Studio 2010实施等待分析 379
13.1.3 使用Xperf实施等待分析 384
13.2 分析内存使用 389
13.2.1 分析目标进程中高级别的内存使用 390
13.2.2 分析NT堆内存使用 391
13.2.3 分析GC堆(.NET)内存使用 395
13.3 跟踪作为一个调试辅助 403
13.3.1 跟踪错误代码失败 403
13.3.2 跟踪系统内部机制 407
13.4 小结 413
附录A WinDbg用户态调试快速启动 415
附录B Windows内核态调试快速启动 428
^ 收 起
第 1章 Windows软件开发 3
1.1 Windows发展过程 3
1.1.1 Windows版本历史 3
1.1.2 支持的CPU架构 4
1.1.3 Windows版本特性 5
1.1.4 Windows服务术语 5
1.2 Windows架构 6
1.2.1 内核态与用户态 6
1.2.2 用户态系统进程 7
1.2.3 用户态应用进程 8
1.2.4 低级别的Windows通信机制 11
1.3 Windows开发人员接口 13
1.3.1 开发人员文档资源 13
1.3.2 WDM、KMDF和 UMDF 14
1.3.3 NTDLL和USER32层 14
1.3.4 Win32 API层 15
1.3.5 COM层 15
1.3.6 CLR(.NET)层 20
1.4 微软开发工具 22
1.4.1 Windows驱动程序开发工具包(WDK) 23
1.4.2 Windows软件开发工具包 23
1.5 小结 23
第二部分 调试的乐趣和好处
第 2章 入门 27
2.1 调试工具介绍 27
2.1.1 获取Windows调试器软件包 27
2.1.2 获取Visual Studio调试器 31
2.1.3 WinDbg和Visual Studio调试器对比 31
2.2 用户态调试 32
2.2.1 使用WinDbg调试你的第 一个程序 32
2.2.2 列举局部变量和函数参数值 39
2.2.3 WinDbg中的源码级调试 43
2.2.4 符号文件、服务器和本地缓存 44
2.2.5 WinDbg符号离线缓存 45
2.2.6 WinDbg中符号解析问题的故障排除 46
2.2.7 名称修饰注意事项 46
2.2.8 获取WinDbg命令的帮助 48
2.3 内核态调试 49
2.3.1 你的第 一个(实时)内核态调试会话 50
2.3.2 使用物理机建立一个内核态调试环境 55
2.3.3 使用虚拟机设置内核态调试环境 60
2.3.4 诊断主机/目标机通信问题 62
2.3.5 理解KD中断序列 63
2.3.6 在内核态调试器中控制目标机 64
2.3.7 在内核态调试器中设置代码断点 66
2.3.8 获取WinDbg内核态调试命令的帮助 68
2.4 小结 68
第3章 Windows调试器是如何工作的 70
3.1 用户态调试 70
3.1.1 架构概述 70
3.1.2 Win32调试API 71
3.1.3 调试事件和异常 72
3.1.4 中断序列 75
3.1.5 设置代码断点 76
3.1.6 观察WinDbg中的代码断点插入 77
3.2 内核态调试 81
3.2.1 架构概述 81
3.2.2 设置代码断点 82
3.2.3 单步执行目标 82
3.2.4 切换当前进程上下文 83
3.3 托管代码调试 84
3.3.1 架构概述 85
3.3.2 SOS Windows调试器扩展 87
3.4 脚本调试 92
3.4.1 架构概述 92
3.4.2 在Visual Studio中调试脚本 93
3.5 远程调试 95
3.5.1 架构概述 95
3.5.2 WinDbg中的远程调试 96
3.5.3 Visual Studio中的远程调试 99
3.6 小结 101
第4章 事后调试 102
4.1 实时调试 102
4.1.1 你的第 一个实时调试实验 102
4.1.2 实时调试是如何工作的 105
4.1.3 使用Visual Studio作为实时调试器 108
4.1.4 运行时断言和实时调试 113
4.1.5 会话0中实时调试 113
4.2 转储调试 114
4.2.1 用户态转储文件自动生成 114
4.2.2 使用WinDbg调试器分析崩溃转储文件 117
4.2.3 使用Visual Studio分析崩溃转储文件 123
4.2.4 手动生成转储文件 124
4.2.5 “时间旅行”调试 125
4.2.6 内核态事后调试 126
4.3 小结 128
第5章 基础扩展 130
5.1 非侵入式调试 130
5.2 数据断点 132
5.2.1 深度分析用户态和内核态数据断点 133
5.2.2 清除内核态数据断点 135
5.2.3 执行数据断点与代码断点 136
5.2.4 用户态调试器数据断点操作:C++全局对象和C运行时库 137
5.2.5 内核态调试器数据断点操作:等待进程退出 139
5.2.6 高级例子:谁在修改注册表值 141
5.3 调试器脚本 145
5.3.1 使用调试器脚本重放命令 145
5.3.2 调试器伪寄存器 146
5.3.3 在调试器脚本中解析C++模板名称 148
5.3.4 脚本实践:在内核调试器中列举Windows服务进程 149
5.4 WOW64调试 150
5.4.1 WOW64环境 150
5.4.2 WOW64进程调试 151
5.5 Windows调试钩子(GFLAGS) 154
5.5.1 系统级与进程相关的NT全局标志 154
5.5.2 GFLAGS工具 155
5.5.3 调试器扩展命令!gflag 157
5.5.4 用户态调试器对NT全局标志值的影响 159
5.5.5 映像文件执行选项钩子 159
5.6 小结 159
第6章 代码分析工具 161
6.1 静态代码分析 161
6.1.1 使用VC++静态代码分析捕获你的第 一个崩溃错误 161
6.1.2 SAL注释 164
6.1.3 其他静态分析工具 167
6.2 运行时代码分析 169
6.2.1 使用应用程序验证器工具捕获你的第 一个错误 170
6.2.2 幕后花絮:操作系统中支持的校验器 172
6.2.3 调试扩展命令!avrf 176
6.2.4 应用程序校验器作为质量保证工具 179
6.3 小结 179
第7章 专家调试技巧 181
7.1 基本技巧 181
7.1.1 等待一个调试器附加到目标 182
7.1.2 加载DLL时中断 184
7.1.3 调试进程启动 188
7.1.4 调试子进程 194
7.2 更多有用的技巧 203
7.2.1 调试错误代码故障 203
7.2.2 在第 一次异常通知时中断 209
7.2.3 冻结线程 210
7.3 内核态调试技巧 212
7.3.1 在用户态进程创建时中断 212
7.3.2 调试用户态进程启动 215
7.3.3 加载DLL时中断 216
7.3.4 未处理SEH异常时中断 217
7.3.5 冻结线程 218
7.4 小结 220
第8章 常见调试场景·第 1部分 222
8.1 调试非法访问 222
8.1.1 理解内存非法访问 222
8.1.2 调试扩展命令!analyze 223
8.2 调试堆破坏 225
8.2.1 调试本地堆破坏 225
8.2.2 调试托管(GC)堆破坏 233
8.3 调试栈破坏 241
8.3.1 基于栈的缓冲区溢出 242
8.3.2 在栈破坏分析中使用数据断点 243
8.3.3 重构损坏栈的调用帧 244
8.4 调试栈溢出 246
8.4.1 理解栈溢出 246
8.4.2 调试命令kf 247
8.5 调试句柄泄露 248
8.5.1 句柄泄露例子 249
8.5.2 调试扩展命令!htrace 250
8.6 调试用户态内存泄露 254
8.6.1 使用应用程序验证器工具检测资源泄露 254
8.6.2 使用UMDH工具分析内存泄露 257
8.6.3 扩展策略:栈跟踪数据库的自定义引用 260
8.7 调试内核态内存泄露 262
8.7.1 内核内存基础知识 262
8.7.2 使用Pool Tagging调查内核态泄露 263
8.8 小结 266
第9章 常见调试场景·第 2部分 268
9.1 调试资源竞争 268
9.1.1 共享状态一致性错误 269
9.1.2 共享状态生命周期管理错误 273
9.1.3 DLL模块生命周期管理错误 281
9.2 调试死锁 284
9.2.1 (锁顺序)Lock-Ordering死锁 285
9.2.2 逻辑死锁 288
9.3 调试访问检查问题 292
9.3.1 基本的NT安全模型 292
9.3.2 Windows Vista的改进 297
9.3.3 结束 300
9.4 小结 301
第 10章 调试系统内部机制 302
10.1 Windows控制台子系统 302
10.1.1 printf背后的魔力 302
10.1.2 Windows UI事件的处理 309
10.1.3 Ctrl+C信号的处理 309
10.2 系统调用剖析 314
10.2.1 用户态一侧的系统调用 315
10.2.2 转换到内核态 317
10.2.3 内核态一侧的系统调用 318
10.3 小结 319
第三部分 观察和分析软件的行为
第 11章 Xperf介绍 323
11.1 获取Xperf 323
11.2 你的第 一个Xperf调查 327
11.2.1 制定一个调查策略 328
11.2.2 收集场景的ETW跟踪 328
11.2.3 分析收集到的ETW跟踪 329
11.3 Xperf的优点和局限性 339
11.4 小结 339
第 12章 ETW内幕 341
12.1 ETW架构 341
12.1.1 ETW设计原则 342
12.1.2 ETW组件 342
12.1.3 特殊的NT内核日志记录会话 343
12.1.4 使用Xperf 配置ETW会话 344
12.2 Windows系统现有的ETW检测 347
12.2.1 Windows内核中的检测 347
12.2.2 其他Windows组件中的检测 350
12.3 理解ETW的Stack-Walk事件 355
12.3.1 启用和查看内核提供者事件的栈跟踪 355
12.3.2 启用和查看用户提供者事件的栈跟踪 358
12.3.3 诊断ETW栈跟踪问题 359
12.4 在你的代码中添加ETW记录 363
12.4.1 ETW事件剖析 364
12.4.2 使用ETW Win32 API记录事件 367
12.5 在ETW中跟踪引导过程 370
12.5.1 在引导过程中记录内核提供者事件 371
12.5.2 在引导过程中记录用户提供者事件 373
12.6 小结 375
第 13章 常见的跟踪场景 376
13.1 分析阻塞时间 376
13.1.1 ETW的CSwitch和ReadyThread事件 377
13.1.2 使用Visual Studio 2010实施等待分析 379
13.1.3 使用Xperf实施等待分析 384
13.2 分析内存使用 389
13.2.1 分析目标进程中高级别的内存使用 390
13.2.2 分析NT堆内存使用 391
13.2.3 分析GC堆(.NET)内存使用 395
13.3 跟踪作为一个调试辅助 403
13.3.1 跟踪错误代码失败 403
13.3.2 跟踪系统内部机制 407
13.4 小结 413
附录A WinDbg用户态调试快速启动 415
附录B Windows内核态调试快速启动 428
^ 收 起
塔里克·索拉米(Tarik Soulami)是Windows基础团队首席开发主管,曾在微软从事过10余年的系统级软件设计和开发工作。加入Windows基础团队之前,他曾在通用语言运行平台(CLR)团队工作,参与了微软.NET框架早期版本的开发。
这是一本介绍 Windows 编程调试技术的书。本书简述了 Windows 开发框架和操作系统中的层。在用调试和跟踪工具发现数据意义时,这些基础知识非常重要。本书还谈到了“调试的乐趣和好处”,描述了 Windows 操作系统中调试器的架构,并介绍了一些可扩展的策略,以帮助你充分利用 Windows 的调试器。本书还展示了 WinDbg 调试器的用法,通过分析代码和操作系统之间的重要相互作用来帮助你更好地了解系统内核。*后,本书就“观察和分析软件的行为”展开讨论,介绍了 Windows 事件跟踪(ETW)技术,并说明了在调试和分析调查中利用 ETW 技术的方法。
本书适合程序员、安全人员、软件测试人员阅读,也可以作为大专院校相关专业的教学用书和机构的培训用书。
本书适合程序员、安全人员、软件测试人员阅读,也可以作为大专院校相关专业的教学用书和机构的培训用书。
比价列表