- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 C# 应用程序中的 MS Word 进行一些 Office 自动化,但我发现 Word 有时会挂起。我无法在开发人员环境中重现挂起,所以我希望我可以通过获取核心转储然后使用 WinDbg 分析它来准确诊断 Word 挂起的原因。
如果我运行 kb,我会得到这个堆栈跟踪(在警告之后我已经放弃了所有内容,因为它可能无关紧要):
ChildEBP RetAddr Args to Child
003bc94c 762ed846 00037b72 00000008 00000000 user32!NtUserWaitMessage+0x15
003bc988 762eda5c 00047b12 00037b72 00000008 user32!DialogBox2+0x222
003bc9b4 762ed98a 59870000 0089aa30 00037b72 user32!InternalDialogBox+0xe5
003bc9d4 762ed70e 59870000 0089aa30 00037b72 user32!DialogBoxIndirectParamAorW+0x37
003bc9f4 59acdf5e 59870000 0089aa30 00037b72 user32!DialogBoxIndirectParamW+0x1b
WARNING: Stack unwind information not available. Following frames may be wrong.
所以这似乎表明 Word 正在挂起,因为它正在显示一个对话框。 如何获取该对话框的内容?
如果我查看地址 0089aa30 的内存,我会看到:
........................3....
.M.i.c.r.o.s.o.f.t. .W.o.r.d.
........T.a.h.o.m.a..........
....P#.!.*...........O.K.....
...........PW.!.*...........&
.H.e.l.p..................P..
.............................
....P+...r.......M.S.O.U.N.I.
S.T.A.T...W.o.r.d. .c.a.n.n.o
.t. .o.p.e.n. .t.h.e. .e.x.i.
s.t.i.n.g. .f.i.l.e..... .(.N
.o.r.m.a.l.)................@
..+.........M.S.O.U.N.I.S.T.A
.T...2.0.0.5.2.1.............
所以对我来说,这表明对话框中的消息是“Word 无法打开现有文件(普通)”。
我在正确的轨道上吗?我在看正确的内存吗?
有什么方法可以得到消息的确切内存地址吗? (我觉得我在猜测,因为上面的消息恰好在内存中靠近 DialogBoxIndirectParam 的参数。)我查看了 MSDN 文档中的 DialogBoxIndirectParam。 ,希望弄清楚我应该在内存中的确切位置看到对话框的消息,但并没有走得太远。
编辑:在看到 blabb(绝对令人难以置信)的答案后,我尝试在 WinDbg 中为我的 MS Word 核心转储执行相同的步骤。这是输出:
0:000> ub 762ed98a
user32!DialogBoxIndirectParamAorW+0x1f:
762ed972 83c801 or eax,1
762ed975 50 push eax
762ed976 ff7518 push dword ptr [ebp+18h]
762ed979 ff7514 push dword ptr [ebp+14h]
762ed97c ff7510 push dword ptr [ebp+10h]
762ed97f ff750c push dword ptr [ebp+0Ch]
762ed982 ff7508 push dword ptr [ebp+8]
762ed985 e809000000 call user32!InternalDialogBox (762ed993)
0:000> .frame /r 2
02 003bc9b4 762ed98a user32!InternalDialogBox+0xe5
eax=00000000 ebx=00037b72 ecx=00000000 edx=00000000 esi=003bc97c edi=003bc918
eip=762eda5c esp=003bc990 ebp=003bc9b4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
user32!InternalDialogBox+0xe5:
762eda5c 5f pop edi
0:000> dc /c 1 003bc990 l8
003bc990 00047b12 .{..
003bc994 00037b72 r{..
003bc998 00000008 ....
003bc99c 00000000 ....
003bc9a0 00000000 ....
003bc9a4 00037b72 r{..
003bc9a8 003bcb98 ..;.
003bc9ac 00000000 ....
我知道我正在查看错误的内存位(即我传递给 dc 的地址不正确),但我不知道为什么。我用“.frame/r 2”来获取esp的地址,我做错了什么?
最佳答案
InternalDialogBox API 有六个参数
C:\>cdb -c ".fnent user32!InternalDialogbox;q" cdb | grep Params
Params: 0n6 (0x18 bytes)
您可以尝试通过对堆栈上的返回地址进行反向反汇编来解密此调用
0:000> kb 1
# ChildEBP RetAddr Args to Child
00 0017fad8 778be0d5 77860000 001ec4f0 00000000 USER32!InternalDialogBox
0:000> ub @$ra
USER32!SoftModalMessageBox+0x66d:
778be0b8 e87c48fdff call USER32!MessageBeep (77892939)
778be0bd 56 push esi
778be0be 53 push ebx
778be0bf 6848d68b77 push offset USER32!MB_DlgProc (778bd648)
778be0c4 ff75ac push dword ptr [ebp-54h]
778be0c7 ff75e4 push dword ptr [ebp-1Ch]
778be0ca ff35d0908c77 push dword ptr [USER32!hmodUser (778c90d0)]
778be0d0 e8a059fdff call USER32!InternalDialogBox (77893a75)
在故障转储中,您可以替换地址而不是寄存器,或者您可以执行 .frame/r {frame number} 获取 esp 的地址
0:000> dc /c 1 @esp l8
0017fadc 778be0d5 ...w
0017fae0 77860000 ...w
0017fae4 001ec4f0 ....
0017fae8 00000000 ....
0017faec 778bd648 H..w
0017faf0 0017fcd8 ....
0017faf4 00000000 ....
0017faf8 00000001 ....
1) 第一个参数是 hModUser 一个全局变量2)第四个参数是一个 DialogProc 回调,记录在案3) 第 3 和第 6 个参数为 NULL
第二个参数包含 DLGTEMPLATE 的数组紧随其后的是 DLGITEMTEMPLATE结构读取文档以获取此可变大小数组的格式
第五个参数是MSGBOXPARAMS结构
一个示例转储并破译可变大小数组的转储,如下所示
0:000> db 1ec4f0 l f8
001ec4f0 c5 01 c8 80 00 00 00 00-02 00 1a 01 9b 00 a7 00 ................
001ec500 3e 00 00 00 00 00 54 00-68 00 69 00 73 00 20 00 >.....T.h.i.s. .
001ec510 69 00 73 00 20 00 4d 00-79 00 20 00 43 00 61 00 i.s. .M.y. .C.a.
001ec520 70 00 74 00 69 00 6f 00-6e 00 20 00 46 00 6f 00 p.t.i.o.n. .F.o.
001ec530 72 00 20 00 32 00 30 00-31 00 35 00 20 00 43 00 r. .2.0.1.5. .C.
001ec540 6f 00 6d 00 6d 00 75 00-6e 00 69 00 74 00 79 00 o.m.m.u.n.i.t.y.
001ec550 20 00 76 00 73 00 00 00-ff 7f 00 00 01 00 03 50 .v.s..........P
001ec560 00 00 00 00 71 00 2a 00-32 00 0e 00 01 00 ff ff ....q.*.2.......
001ec570 80 00 4f 00 4b 00 00 00-00 00 00 00 80 20 02 50 ..O.K........ .P
001ec580 00 00 00 00 07 00 0e 00-8c 00 09 00 ff ff ff ff ................
001ec590 82 00 54 00 68 00 69 00-73 00 20 00 69 00 73 00 ..T.h.i.s. .i.s.
001ec5a0 20 00 6d 00 79 00 20 00-66 00 69 00 72 00 73 00 .m.y. .f.i.r.s.
001ec5b0 74 00 20 00 54 00 65 00-73 00 74 00 20 00 77 00 t. .T.e.s.t. .w.
001ec5c0 69 00 74 00 68 00 20 00-32 00 30 00 31 00 35 00 i.t.h. .2.0.1.5.
001ec5d0 20 00 63 00 6f 00 6d 00-6d 00 75 00 6e 00 69 00 .c.o.m.m.u.n.i.
001ec5e0 74 00 79 00 00 00 00 00 t.y.....
0:000> dt ConsoleApplication1!DLGTEMPLATE 1ec4f0
+0x000 style : 0x80c801c5
+0x004 dwExtendedStyle : 0
+0x008 cdit : 2
+0x00a x : 0x11a
+0x00c y : 0x9b
+0x00e cx : 0xa7
+0x010 cy : 0x3e
0:000> du 1ec504
001ec504 ""
0:000> du 1ec506
001ec506 "This is My Caption For 2015 Comm"
001ec546 "unity vs"
0:000> dt ConsoleApplication1!DLGITEMTEMPLATE 1ec55c
+0x000 style : 0x50030001
+0x004 dwExtendedStyle : 0
+0x008 x : 0x71
+0x00a y : 0x2a
+0x00c cx : 0x32
+0x00e cy : 0xe
+0x010 id : 1
0:000> $$ 80 is a predfined button and the text is OK
0:000> dt ConsoleApplication1!DLGITEMTEMPLATE 1ec57c
+0x000 style : 0x50022080
+0x004 dwExtendedStyle : 0
+0x008 x : 7
+0x00a y : 0xe
+0x00c cx : 0x8c
+0x00e cy : 9
+0x010 id : 0xffff
0:000> $$ 82 is a predfined static text and the text is
0:000> du 1ec592
001ec592 "This is my first Test with 2015 "
001ec5d2 "community"
这是一个 MSGBOXPARAMSW 转储
0:000> dt ConsoleApplication1!MSGBOXPARAMSW 0017fcd8
+0x000 cbSize : 0x28
+0x004 hwndOwner : (null)
+0x008 hInstance : (null)
+0x00c lpszText : 0x01172150 "This is my first Test with 2015 community"
+0x010 lpszCaption : 0x011720f8 "This is My Caption For 2015 Community vs"
+0x014 dwStyle : 0
+0x018 lpszIcon : (null)
+0x01c dwContextHelpId : 0
+0x020 lpfnMsgBoxCallback : (null)
+0x024 dwLanguageId : 0
编辑
从任务管理器创建一个转储并加载它
0:000> .shell -ci "version" grep DMP
Full memory user mini dump: C:\Users\HP\Desktop\cons.DMP
command line: 'windbg -z cons.DMP' Debugger Process 0x17CC
.shell: Process exited
只是为了确保重置上下文记录
0:000> .cxr
Resetting default scope
转储堆栈跟踪 9 感兴趣的帧不在此处)
0:000> kb 5
# ChildEBP RetAddr Args to Child
00 0028f6fc 778766c9 7789382a 00000000 00000000 ntdll!KiFastSystemCallRet
01 0028f700 7789382a 00000000 00000000 00000000 user32!NtUserWaitMessage+0xc
02 0028f734 77893b27 00aa0350 00000000 00000000 user32!DialogBox2+0x207
03 0028f758 778be0d5 77860000 002f63f0 00000000 user32!InternalDialogBox+0xcb
04 0028f7fc 778be659 00000000 69d52104 69d52108 user32!SoftModalMessageBox+0x68a
覆盖感兴趣帧号的本地上下文
0:000> .frame /c /r 04
04 0028f7fc 778be659 user32!SoftModalMessageBox+0x68a
eax=00000001 ebx=0028f958 ecx=0028f458 edx=77ad70f4 esi=005fab18 edi=00000001
eip=778be0d5 esp=0028f760 ebp=0028f7fc iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
user32!SoftModalMessageBox+0x68a:
778be0d5 8945e8 mov dword ptr [ebp-18h],eax ss:0023:0028f7e4=00000000
checking esp you can use esp as it is instead of groping for address
0:000> dc /c 1 @esp l 8
0028f760 77860000 ...w
0028f764 002f63f0 .c/.
0028f768 00000000 ....
0028f76c 778bd648 H..w
0028f770 0028f958 X.(.
0028f774 00000000 ....
0028f778 00000001 ....
0028f77c 0028f958 X.(.
转储 DLGTEMPLATE 第二个参数
0:000> db 2f63f0 lf8
002f63f0 c5 01 c8 80 00 00 00 00-02 00 1a 01 9b 00 a7 00 ................
002f6400 3e 00 00 00 00 00 54 00-68 00 69 00 73 00 20 00 >.....T.h.i.s. .
002f6410 69 00 73 00 20 00 4d 00-79 00 20 00 43 00 61 00 i.s. .M.y. .C.a.
002f6420 70 00 74 00 69 00 6f 00-6e 00 20 00 46 00 6f 00 p.t.i.o.n. .F.o.
002f6430 72 00 20 00 32 00 30 00-31 00 35 00 20 00 43 00 r. .2.0.1.5. .C.
002f6440 6f 00 6d 00 6d 00 75 00-6e 00 69 00 74 00 79 00 o.m.m.u.n.i.t.y.
002f6450 20 00 76 00 73 00 00 00-ff 7f 00 00 01 00 03 50 .v.s..........P
002f6460 00 00 00 00 71 00 2a 00-32 00 0e 00 01 00 ff ff ....q.*.2.......
002f6470 80 00 4f 00 4b 00 00 00-00 00 00 00 80 20 02 50 ..O.K........ .P
002f6480 00 00 00 00 07 00 0e 00-8c 00 09 00 ff ff ff ff ................
002f6490 82 00 54 00 68 00 69 00-73 00 20 00 69 00 73 00 ..T.h.i.s. .i.s.
002f64a0 20 00 6d 00 79 00 20 00-66 00 69 00 72 00 73 00 .m.y. .f.i.r.s.
002f64b0 74 00 20 00 54 00 65 00-73 00 74 00 20 00 77 00 t. .T.e.s.t. .w.
002f64c0 69 00 74 00 68 00 20 00-32 00 30 00 31 00 35 00 i.t.h. .2.0.1.5.
002f64d0 20 00 63 00 6f 00 6d 00-6d 00 75 00 6e 00 69 00 .c.o.m.m.u.n.i.
002f64e0 74 00 79 00 00 00 00 00 t.y.....
typeinfo(您需要适当的私有(private) pdb 或 hack 加载您编译到地址空间的二进制文件,或将 DLGTEMPLATE 结构添加到来自 ms 的 user32 的官方 pdb 中(我以为我在 se 中有一篇解释这一点的帖子,但我似乎无法查找)如果我找到它,稍后会链接它或在网站上搜索谷歌以了解如何在 site:woodmann.com 中将 typeinfo 添加到 pdb
0:000> dt cons!DLGTEMPLATE poi(@esp+4)
+0x000 style : 0x80c801c5
+0x004 dwExtendedStyle : 0
+0x008 cdit : 2
+0x00a x : 0n282
+0x00c y : 0n155
+0x00e cx : 0n167
+0x010 cy : 0n62
0:000> du poi(@esp+4)+16
002f6406 "This is My Caption For 2015 Comm"
002f6446 "unity vs"
edit 2 这是用于转储模式下的实时 session ,您需要修改 pdb,因为您不能使用执行命令
我们处于实时 dbg session 中,我们可以使用在 dmp 模式下不可用的 step 命令
0:000> .tlist -c -v
0n3324 Msgbox.exe
Session: 1 User: HP-PC\HP Command Line: Msgbox.exe
让我们搜索一些我们需要的类型信息
0:000> dt *!*DLGTEMPLATE*
0:000> $$ no the thype info is not available
0:000> $$ we know ole32.dll has it
0:000> $$ so lets hack load it
分配一些内存
0:000> .dvalloc 1000
Allocated 1000 bytes starting at 00020000
save the current eip
0:000> ? @eip
Evaluate expression: 2008221094 = 77b305a6
将模块名称字符串嵌入到分配的内存中的某个地址
0:000> ea 20100 "ole32.dll"
0:000> db 20100 l20
00020100 6f 6c 65 33 32 2e 64 6c-6c 00 00 00 00 00 00 00 ole32.dll.......
00020110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
组装一个 LoadLibraryA 内联调用
0:000> a 20000
00020000 push 20100
push 20100
00020005 call kernel32!LoadLibraryA
call kernel32!LoadLibraryA
0002000a
把eip改成绕路地址
0:000> r eip = 20000
single step to load a dll into the address space
0:000> p
eax=00000000 ebx=00000000 ecx=0026f80c edx=77ad70f4 esi=fffffffe edi=00000000
eip=00020005 esp=0026f824 ebp=0026f854 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
00020005 e852395877 call kernel32!LoadLibraryA (775a395c)
0:000> p
ModLoad: 77930000 77a8c000 C:\Windows\system32\ole32.dll
ModLoad: 75ee0000 75f81000 C:\Windows\system32\RPCRT4.dll
ModLoad: 77530000 7754f000 C:\Windows\system32\IMM32.DLL
ModLoad: 76030000 760fc000 C:\Windows\system32\MSCTF.dll
eax=77930000 ebx=00000000 ecx=77ae6570 edx=002b0174 esi=fffffffe edi=00000000
eip=0002000a esp=0026f828 ebp=0026f854 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
0002000a 0000 add byte ptr [eax],al ds:0023:77930000=4d
重新设置eip
0:000> r eip = 77b305a6
我们研究我们拥有的 typeinfo 和 bingo
0:000> dt *!*DLGTEMPLATE*
ole32!LPDLGTEMPLATEA
ole32!LPDLGTEMPLATE
ole32!LPDLGTEMPLATEW
ole32!LPCDLGTEMPLATE
ole32!LPCDLGTEMPLATEA
ole32!LPCDLGTEMPLATEW
ole32!DLGTEMPLATE
ole32!DLGTEMPLATE
关于ms-word - WinDbg:如何从核心转储中获取在 Word 对话框中显示的消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42662673/
我的Angular-Component位于一个flexbox(id =“log”)中。可以显示或隐藏flexbox。 我的组件内部有一个可滚动区域,用于显示日志消息。 (id =“message-li
我真的很困惑 有一个 phpinfo() 输出: MySQL 支持 启用 客户端 API 版本 5.5.40 MYSQL_MODULE_TYPE 外部 phpMyAdmin 显示: 服务器类型:Mar
我正在研究这个 fiddle : http://jsfiddle.net/cED6c/7/我想让按钮文本在单击时发生变化,我尝试使用以下代码: 但是,它不起作用。我应该如何实现这个?任何帮助都会很棒
我应该在“dogs_cats”中保存表“dogs”和“cats”各自的ID,当看到数据时显示狗和猫的名字。 我有这三个表: CREATE TABLE IF NOT EXISTS cats ( id
我有一个字符串返回到我的 View 之一,如下所示: $text = 'Lorem ipsum dolor ' 我正在尝试用 Blade 显示它: {{$text}} 但是,输出是原始字符串而不是渲染
我无法让我的链接(由图像表示,位于页面左侧)真正有效地显示一个 div(包含一个句子,位于中间)/单击链接时隐藏。 这是我的代码: Practice
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
最初我使用 Listview 来显示 oracle 结果,但是最近我不得不切换到 datagridview 来处理比 Listview 允许的更多的结果。然而,自从切换到数据网格后,我得到的结果越来越
我一直在尝试插入一个 Unicode 字符 ∇ 或 ▽,所以它显示在 Apache FOP 生成的 PDF 中。 这是我到目前为止所做的: 根据这个基本帮助 Apache XSL-FO Input,您
我正在使用 node v0.12.7 编写一个 nodeJS 应用程序。 我正在使用 pm2 v0.14.7 运行我的 nodejs 应用程序。 我的应用程序似乎有内存泄漏,因为它从我启动时的大约 1
好的,所以我有一些 jQuery 代码,如果从下拉菜单中选择了带有前缀 Blue 的项目,它会显示一个输入框。 代码: $(function() { $('#text1').hide();
当我试图检查 Chrome 中的 html 元素时,它显示的是 LESS 文件,而 Firefox 显示的是 CSS 文件。 (我正在使用 Bootstrap 框架) 如何在 Chrome 中查看 c
我是 Microsoft Bot Framework 的新手,我正在通过 youtube 视频 https://youtu.be/ynG6Muox81o 学习它并在 Ubuntu 上使用 python
我正在尝试转换从 mssql 生成的文件到 utf-8。当我打开他的输出 mssql在 Windows Server 2003 中使用 notepad++ 将文件识别为 UCS-2LE我使用 file
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我正在尝试执行单击以打开/关闭一个 div 的功能。 这是基本的,但是,点击只显示 div,当我点击“关闭”时,没有任何反应。 $(".inscricao-email").click(function
假设我有 2 张卡片,屏幕上一次显示一张。我有一个按钮可以用其他卡片替换当前卡片。现在假设卡 1 上有一些数据,卡 2 上有一些数据,我不想破坏它们每个上的数据,或者我不想再次重建它们中的任何一个。
我正在使用 Eloquent Javascript 学习 Javascript。 我在 Firefox 控制台上编写了以下代码,但它返回:“ReferenceError:show() 未定义”为什么?
我正在使用 Symfony2 开发一个 web 项目,我使用 Sonata Admin 作为管理面板,一切正常,但我想要做的是,在 Sonata Admin 的仪表板菜单上,我需要显示隐藏一些菜单取决
我试图显示一个div,具体取决于从下拉列表中选择的内容。例如,如果用户从列表中选择“现金”显示现金div或用户从列表中选择“检查”显示现金div 我整理了样本,但样本不完整,需要接线 http://j
我是一名优秀的程序员,十分优秀!