首页 技术 正文
技术 2022年11月20日
0 收藏 589 点赞 3,460 浏览 4540 个字

Dump 分析模式之 INCORRECT STACK TRACEdump 分析模式之 INCORRECT STACK TRACE 翻译自 MDA-Anthology Page288 

初学者常犯的错误是认为 WinDbg 的 !analyze 和 kv 给出的信息是准确的. 

WinDbg 只是一个工具, 有时候会缺少一些必要的信息来得到正确的栈信息, 因此我们需要自己明辨正确的与错误的栈信息. 我称之为 Incorrect Stack Trace, 它通常有以下特征:

  • WinDbg给出警告: “Following frames may be wrong”
  • 栈底函数不是 kernel32!BaseThreadStart (用户模式)
  • 无意义的函数调用
  • 反汇编后的函数的代码很奇怪, 或不像编译器生成的代码
  • ChildEBP 和 RetAddr 的地址没有意义

考虑以下栈信息:

0:011> k 

ChildEBP RetAddr 

WARNING: Frame IP not in any known module. Following frames may be wrong. 

0184e434 7c830b10 0×184e5bf 

0184e51c 7c81f832 ntdll!RtlGetFullPathName_Ustr+0×15b 

0184e5f8 7c83b1dd ntdll!RtlpLowFragHeapAlloc+0xc6a 

00099d30 00000000 ntdll!RtlpLowFragHeapFree+0xa7

以上栈信息基本具备了错误栈信息的所有性质. 初看像是堆破坏, 因为运行时的堆分配与释放函数出现在了栈中. 但如果我们再想想就会发现 HeapFree 函数不应调用 HeapAlloc 函数, 而接下来更不应该调用 GetFullPathName. 所以这个栈信息是无意义的. 

那我们能怎样呢? 检视 raw 栈信息并构造出真正的栈. 我们可以轻松地从 BaseThreadStart+0×34 开始遍历所有帧直到没有任何函数调用了或都已到栈顶. 当一个函数被调用的时候 EBP 会像下图那样连起来 (如果没有被优化掉, 对于大多数编译成立). 

0:011> !teb 

TEB at 7ffd8000 

ExceptionList: 0184ebdc 

StackBase: 01850000 

StackLimit: 01841000 

… 

0:011> dds 01841000 01850000 

01841000 00000000 

… 

… 

… 

0184eef0 0184ef0c0184eef4 7615dff2 localspl!SplDriverEvent+0×21 

0184eef8 00bc3e08 

… 

0184ef0c 0184ef300184ef10 7615f9d0 

localspl!PrinterDriverEvent+0×46 

0184ef14 00bc3e08 

0184ef18 00000003 

… 

0184ef2c 00bafcc0 

0184ef30 0184f3f80184ef34 7614a9b4 localspl!SplAddPrinter+0×5f3 

0184ef38 00c3ec58 

… 

0184ff30 0184ff840184ff34 77c75286 RPCRT4!LRPC_ADDRESS::ReceiveLotsaCalls+0×3a 

0184ff38 0184ff4c 

0184ff3c 77c75296 RPCRT4!LRPC_ADDRESS::ReceiveLotsaCalls+0×4a 

0184ff40 7c82f2fc ntdll!RtlLeaveCriticalSection 

… 

0184ff84 0184ff8c0184ff88 77c5778f RPCRT4!RecvLotsaCallsWrapper+0xd 

0184ff8c 0184ffac0184ff90 77c5f7dd RPCRT4!BaseCachedThreadRoutine+0×9d 

… 

0184ffac 0184ffb80184ffb0 77c5de88 RPCRT4!ThreadStartRoutine+0×1b 

0184ffb4 00088258 

0184ffb8 0184ffec 

0184ffbc 77e6608b kernel32!BaseThreadStart+0×34

接下来我们需要用指定了基址的 k 命令来显示栈信息. 在本例中最后的有效 EBP 地址是 0184eef0.

0:011> k L=0184eef0 

ChildEBP RetAddr WARNING: Frame IP not in any known module. Following frames may be wrong. 

0184eef0 7615dff2 0×184e5bf 0184ef0c 7615f9d0 localspl!SplDriverEvent+0×21 

0184ef30 7614a9b4 localspl!PrinterDriverEvent+0×46 

0184f3f8 761482de localspl!SplAddPrinter+0×5f3 

0184f424 74067c8f localspl!LocalAddPrinterEx+0×2e 

0184f874 74067b76 SPOOLSS!AddPrinterExW+0×151 

0184f890 01007e29 SPOOLSS!AddPrinterW+0×17 

0184f8ac 01006ec3 spoolsv!YAddPrinter+0×75 

0184f8d0 77c70f3b spoolsv!RpcAddPrinter+0×37 

0184f8f8 77ce23f7 RPCRT4!Invoke+0×30 

0184fcf8 77ce26ed RPCRT4!NdrStubCall2+0×299 

0184fd14 77c709be RPCRT4!NdrServerCall2+0×19 

0184fd48 77c7093f RPCRT4!DispatchToStubInCNoAvrf+0×38 

0184fd9c 77c70865 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0×117 

0184fdc0 77c734b1 RPCRT4!RPC_INTERFACE::DispatchToStub+0xa3 

0184fdfc 77c71bb3 RPCRT4!LRPC_SCALL::DealWithRequestMessage+0×42c 

0184fe20 77c75458 RPCRT4!LRPC_ADDRESS::DealWithLRPCRequest+0×127 

0184ff84 77c5778f RPCRT4!LRPC_ADDRESS::ReceiveLotsaCalls+0×430 

0184ff8c 77c5f7dd RPCRT4!RecvLotsaCallsWrapper+0xd

栈信息现在看起来有意义多了, 但我们仍然没有看到 BaseThreadStart+0×34. 默认情况下 WinDbg 只显示一定数量的栈帧. 所以我们需要指定栈帧的数量, 比如 100:

0:011> k L=0184eef0 100 

ChildEBP RetAddr WARNING: Frame IP not in any known module. Following frames may be wrong. 

0184eef0 7615dff2 0×184e5bf 

0184ef0c 7615f9d0 localspl!SplDriverEvent+0×21 

0184ef30 7614a9b4 localspl!PrinterDriverEvent+0×46 

… 

0184ffac 77c5de88 RPCRT4!BaseCachedThreadRoutine+0×9d 

0184ffb8 77e6608b RPCRT4!ThreadStartRoutine+0×1b 

0184ffec 00000000 kernel32!BaseThreadStart+0×34

现在我们的栈信息看起来更好了. 还有一个完整的示例在 Manual Stack Track Reconstruction, 本书第 157 页. 

此外, incorrect stack trace 也会发生在没有符号信息的时候. 这种情况下, 通常栈帧之间会有找不到符号的警告:

STACK_TEXT: 

WARNING: Stack unwind information not available. Following frames may be wrong. 

00b2f42c 091607aa mydll!foo+0×8338 

00b2f4cc 7c83ab9e mydll!foo+0×8fe3 

00b2f4ec 7c832d06 ntdll!RtlFindNextActivationContextSection+0×46 

00b2f538 001a5574 ntdll!RtlFindActivationContextSectionString+0xe1 

00b2f554 7c8302b3 0×1a5574 

00b2f560 7c82f9c1 ntdll!RtlpFreeToHeapLookaside+0×22 

00b2f640 7c832b7f ntdll!RtlFreeHeap+0×20e 

001dd000 00080040 ntdll!LdrUnlockLoaderLock+0xad 

001dd00c 0052005c 0×80040 

001dd010 00470045 0×52005c 

0052005c 00000000 0×470045

  1. dump 分析模式之 INCORRECT STACK TRACE – djm2005dy的专栏 – 博客频道 – CSDN.NET 18
    AUG 2012
  2.  0 热度 #未分类#WINDBG

使用 dpu 检视 dump 中的字符串.翻译自 MDA-Anthology1 page167, WINDBG TIPS AND TRICKS. 

WinDbg中有一些很好的命令像dpu (检视unicode字符串)和dpa (检视ASCII字符串)以及其它 d 开头的命令如dpp. 我们可以使用这些命令来看看栈上是否有指针指向了字符串. 

例如: 

0:143> !teb

TEB at 7ff2b000 

... 

StackBase: 05e90000 

StackLimit: 05e89000 

... 

... 

...

0:143> dpu 05e89000 05e90000

05e8f58c 00120010 ""

...

...

...

05e8f590 77e7723c "Debugger"

05e8f594 00000000

05e8f598 08dc0154

05e8f59c 01000040

05e8f5a0 05e8f5dc "G:\WINDOWS\system32\faultrep.dll"

05e8f5a4 0633adf0 ""

05e8f5a8 00000000

05e8f5ac 00000001

05e8f5b0 00000012

...

05e8f5d4 0633adfc "drwtsn32 -p %ld -e %ld -g"

...

...

...

当然这些命令不仅能对栈地址空间起作用, 也能用在普通的内存段上.

  1. dump 分析模式之 INCORRECT STACK TRACE – djm2005dy的专栏 – 博客频道 – CSDN.NET 18TH
    AUG 2012
  2.  0 热度 #未分类#WINDBG

来自为知笔记(Wiz)

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,077
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,552
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,401
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,813
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,897