c06d007f异常的解决方法

c06d007f这个异常通常是在PE的延迟加载dll的时候发生的,加载器找不到对应的dll就会抛出这个异常。如果我们对这个异常不熟悉,按照常规方式去找上下文,那么结果肯定会让你失望。例如3.2526.1373.0版本的libcef在XP上运行的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0:000> kb
# ChildEBP RetAddr Args to Child
00 0012f218 7c92d9ac 7c86449d d0000144 00000004 ntdll!KiFastSystemCallRet
01 0012f21c 7c86449d d0000144 00000004 00000000 ntdll!ZwRaiseHardError+0xc
02 0012f4a0 7c843892 0012f4c8 7c839b21 0012f4d0 kernel32!UnhandledExceptionFilter+0x628
03 0012f4a8 7c839b21 0012f4d0 00000000 0012f4d0 kernel32!BaseProcessStart+0x39
04 0012f4d0 7c9232a8 0012f5bc 0012ffe0 0012f5d4 kernel32!_except_handler3+0x61
05 0012f4f4 7c92327a 0012f5bc 0012ffe0 0012f5d4 ntdll!ExecuteHandler2+0x26
06 0012f5a4 7c92e46a 00000000 0012f5d4 0012f5bc ntdll!ExecuteHandler+0x24
07 0012f5a4 00000000 00000000 0012f5d4 0012f5bc ntdll!KiUserExceptionDispatcher+0xe
WARNING: Frame IP not in any known module. Following frames may be wrong.
08 0012fff4 004a991e 00000000 78746341 00000020 0x0
09 0012fff8 00000000 78746341 00000020 00000001 cefclient!pre_c_init+0xb9 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 261]
0:000> .cxr 0012f5d4;k
eax=0012f8a4 ebx=1314a58c ecx=00000000 edx=00000001 esi=0012f954 edi=68d60000
eip=00000000 esp=0012fff8 ebp=00000000 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
00000000 ?? ???
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 0012fff4 004a991e 0x0
01 0012fff8 00000000 cefclient!pre_c_init+0xb9 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 261]

直接看栈回溯或者通过设置cxr看栈回溯,并没有帮助我们找到什么有用的信息。

这里要使用的方法是,利用异常的参数来找到具体延迟加载谁的时候发生了异常。

1
2
3
4
5
6
7
8
0:000> .exr 0012f5bc
ExceptionAddress: 7c812aeb (kernel32!RaiseException+0x00000053)
ExceptionCode: c06d007f
ExceptionFlags: 00000000
NumberParameters: 1
Parameter[0]: 0012f918

这里的参数0,就是我们要找的目标,记录了出错时候ebp-0x30的数据,也就是含有关键信息的地方。让我们仔细看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
0:000> dds 0012f918
0012f918 00000024
0012f91c 1314a58c libcef!_DELAY_IMPORT_DESCRIPTOR_dbghelp_dll
0012f920 13181dbc libcef!_imp__SymGetSearchPathW
0012f924 12ebdd20 libcef!_sz_dbghelp_dll
0012f928 00000001
0012f92c 1314ac8e libcef!dxva2_NULL_THUNK_DATA_DLN+0x7e
0012f930 68d60000 dbghelp!_imp__CryptAcquireContextA <PERF> (dbghelp+0x0)
0012f934 00000000
0012f938 0000007f
0012f93c 1314c138 libcef!dxva2_NULL_THUNK_DATA_DLN+0x1528
0012f940 00000003
0012f944 00000000
0012f948 0012f9f8
0012f94c 11d17587 libcef!_tailMerge_dbghelp_dll+0xd
0012f950 0012f918
0012f954 13181dbc libcef!_imp__SymGetSearchPathW
0012f958 00000008
0012f95c 7c9301bb ntdll!RtlAllocateHeap+0xeac
0012f960 1019014e libcef!base::debug::`anonymous namespace'::InitializeSymbols+0x9e [f:\stnts\browser\cef\ws\src\chromium\src\base\debug\stack_trace_win.cc @ 79]
0012f964 ffffffff
0012f968 00170880

我们可以清楚的看到加载器延迟加载SymGetSearchPathW的时候发生了问题。让我们进一步用depends工具验证一下

20160223003624

如上图所示,XP自带的dbghelp里没有SymGetSearchPathW这个导出函数。要解决这个异常,实际上就需要在运行目录里添加一个稍微新一点的dbghelp文件,我这里替换的是6.2.9200.16384的dbghelp,替换过后问题已经不再出现了。

20160223003711

debugging

调试器最早的中断应用程序的方法

这篇Blog分享一个Windbg的小技巧,就是让被调试程序更早的中断到调试器。熟悉Windbg的朋友都知道,用调试器运行程序,默认情况下都会中断到ntdll!LdrpDoDebuggerBreak。但是有时候我们会想去调试程序加载的过程,这个时候就需要我们更早的中断下来。那么这里就用利用到调试器最早接受到的调试事件了。CREATE_PROCESS_DEBUG_EVENT,这个调试事件是创建进程的时候进程发给调试器的,在这个时候,你甚至连ntdll都没有完成加载,这也导致ntdll的符号无法加载,很多有用的功能用不上。但幸运的是,虽然ntdll没有完成加载,但是已经加载到了内存,另外我们可以用手动加载符号的方法,把符号文件加载到ntdll的内存上去。

演示如下:

windbg.EXE -xe cpr -xe ld notepad.exe

这里设置中断系统事件cpr,也就是CREATE_PROCESS_DEBUG_EVENT

1
2
3
4
5
6
7
8
0:000> lm
start end module name
00007ff7`3f6e0000 00007ff7`3f721000 notepad (deferred)
0:000> !teb
TEB at 000000d995d21000
error InitTypeRead( TEB )...

中断下来后我们可以看到,!teb是没法用的

1
2
3
4
5
6
7
8
0:000> .imgscan
MZ at 00007ff7`3f6e0000, prot 00000002, type 01000000 - size 41000
Name: notepad.exe
MZ at 00007ffb`7c7b0000, prot 00000002, type 01000000 - size 1c1000
Name: ntdll.dll
0:000> .reload /f ntdll.dll=00007ffb`7c7b0000

我们需要找到ntdll的模块,然后手动加载符号,然后就可以使用和ntdll有关系的命令了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
0:000> lm
start end module name
00007ff7`3f6e0000 00007ff7`3f721000 notepad (deferred)
00007ffb`7c7b0000 00007ffb`7c971000 ntdll (pdb symbols) e:\workspace\mysymbols\ntdll.pdb\F296699DB5314A06935E88564D8CD2731\ntdll.pdb
0:000> !teb
TEB at 000000d995d21000
ExceptionList: 0000000000000000
StackBase: 000000d995af0000
StackLimit: 000000d995adf000
SubSystemTib: 0000000000000000
FiberData: 0000000000001e00
ArbitraryUserPointer: 0000000000000000
Self: 000000d995d21000
EnvironmentPointer: 0000000000000000
ClientId: 0000000000001c8c . 00000000000017c4
RpcHandle: 0000000000000000
Tls Storage: 0000000000000000
PEB Address: 000000d995d20000
LastErrorValue: 0
LastStatusValue: 0
Count Owned Locks: 0
HardErrorMode: 0

debugging