gotcha sdk 全盘文件名搜索开发库

想必大家都知道著名的全盘搜索工具everything,它极速的搜索速度让人眼前一亮。虽然everything提供了SDK,但是SDK是通过IPC的方式,获得everything程序里的数据。也就是说想在自己的程序中使用搜索功能那么必须带everything的主程序,这就是我开发gotcha sdk的主要原因,他能集成到程序当中,不需要依赖其他主程序,只需要你的程序是管理员权限运行,因为这样才能直接访问磁盘数据。另外网上也有一些关于everything原理和实现的代码,但是大部分都有问题,比如崩溃,死锁,内存占用过高等,并不适合直接用到产品当中。而gotcha sdk在自己开发了everything_study,并且使用了相当长的时间,解决性能,内存占用,死锁等问题的基础上提炼出来的开发库,我对其稳定性还是比较有信心的。

利用gotcha sdk,既可以开发出everything_study这样用C++写的程序,也能够开发出如gotcha sdk的sample里的gotcha,一个C#编写的全盘搜索程序,该程序也展示了gotcha sdk的用法。

gotcha sdk的用法非常简单,详细情况可以参考sample里的simple例子,该例子展示了sdk最简单的使用方式,我下一篇blog会介绍这套sdk的用法。

20151124233627

gotcha sdk 代码SVN:
http://code.taobao.org/svn/gotcha_sdk/

NTInternals

程序初始化失败DUMP分析

拿到程序初始化失败的DUMP,一般情况下我们看到的栈是这个样子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0:000> kb
ChildEBP RetAddr Args to Child
0012fc7c 7c92d9ca 7c972b53 c0000145 00000001 ntdll!KiFastSystemCallRet
0012fc80 7c972b53 c0000145 00000001 00000000 ntdll!NtRaiseHardError+0xc
0012fca4 7c960f9f c0000005 0012fd30 00370034 ntdll!LdrpInitializationFailure+0x2d
0012fd1c 7c92e457 0012fd30 7c920000 00000000 ntdll!_LdrpInitialize+0x1f9
00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7
0:000> !error c0000145
Error code: (NTSTATUS) 0xc0000145 (3221225797) - {Application Error} The application was unable to start correctly (0x%lx). Click OK to close the application.
0:000> !error c0000005
Error code: (NTSTATUS) 0xc0000005 (3221225477) - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

可以看到最后报错是c0000145,应用程序无法运行。而引起出错的是LdrpInitializationFailure,出错原因内存访问异常。但是具体是哪出错还不无法从此刻的栈看到,我们需要进一步分析。

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
0:000> dds esp-1000 esp
...
0012f3c0 7c92e920 ntdll!_except_handler3
0012f3c4 00000001
0012f3c8 0012f470
0012f3cc 0012fd0c
0012f3d0 7c953fdc ntdll!RtlDispatchException+0xb1
0012f3d4 0012f470
0012f3d8 0012fd0c
0012f3dc 0012f48c
0012f3e0 0012f444
0012f3e4 7c92e920 ntdll!_except_handler3
0012f3e8 003d3810 someapp!PostMsg+0x27aa0
0012f3ec 0012f470
0012f3f0 b36caf32
0012f3f4 00153960
0012f3f8 7c93e584 ntdll!DbgPrint+0x1c
0012f3fc 00150178
0012f400 000000e8
0012f404 00000668
0012f408 00150000
0012f40c 0012f204
0012f410 7c940571 ntdll!RtlCreateActivationContext+0x2c
0012f414 c0000000
0012f418 00153960
0012f41c 003f0000
0012f420 00000000
0012f424 0012f444
0012f428 7c940610 ntdll!RtlCreateActivationContext+0xed
0012f42c 001539b4
0012f430 00000002
0012f434 00000008
0012f438 00000000
0012f43c 00000000
0012f440 00000000
0012f444 0012f750
0012f448 7c814880 kernel32!CreateActCtxW+0x75c
0012f44c 00130000
0012f450 0012d000
0012f454 00000000
0012f458 0012f76c
0012f45c 7c92e48a ntdll!KiUserExceptionDispatcher+0xe
0012f460 00000000
0012f464 0012f48c
0012f468 0012f470
0012f46c 0012f48c
0012f470 c0000005
0012f474 00000000
0012f478 00000000
0012f47c 7c93ccf2 ntdll!LdrpHandleOneOldFormatImportDescriptor+0x21
0012f480 00000002
0012f484 00000000
0012f488 d16cca32
0012f48c 0001003f
...

这里我们就可以看到异常发生的栈了。

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
0:000> .exr 0012f470
ExceptionAddress: 7c93ccf2 (ntdll!LdrpHandleOneOldFormatImportDescriptor+0x00000021)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: d16cca32
Attempt to read from address d16cca32
0:000> .cxr 0012f48c
eax=003a0000 ebx=00253010 ecx=d132ca32 edx=00033810 esi=b36caf32 edi=003d3810
eip=7c93ccf2 esp=0012f758 ebp=0012f76c iopl=0 nv up ei ng nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010282
ntdll!LdrpHandleOneOldFormatImportDescriptor+0x21:
7c93ccf2 833c0800 cmp dword ptr [eax+ecx],0 ds:0023:d16cca32=????????
0:000> kb
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr Args to Child
0012f76c 7c93ccc4 7ffd9000 00020498 00253010 ntdll!LdrpHandleOneOldFormatImportDescriptor+0x21
0012f784 7c93bc1e 7ffd9000 00020498 00253010 ntdll!LdrpHandleOldFormatImportDescriptors+0x1f
0012f800 7c93d216 00020498 00253010 00434398 ntdll!LdrpWalkImportDescriptor+0x19e
0012fa50 7c93cd1d 00020498 004396ca 00400000 ntdll!LdrpLoadImportModule+0x1c8
0012fa80 7c93ccc4 7ffd9000 00020498 00251ec0 ntdll!LdrpHandleOneOldFormatImportDescriptor+0x5e
0012fa98 7c93bc1e 7ffd9000 00020498 00251ec0 ntdll!LdrpHandleOldFormatImportDescriptors+0x1f
0012fb14 7c9418b5 00020498 00251ec0 7ffdf000 ntdll!LdrpWalkImportDescriptor+0x19e
0012fc94 00000000 0012fca0 00000000 0012fd1c ntdll!LdrpInitializeProcess+0xe02
0:000> dt ntdll!_LDR_DATA_TABLE_ENTRY 00253010
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x251e9c - 0x252ee0 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x251ea4 - 0x252ee8 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0x003a0000 Void
+0x01c EntryPoint : 0x003c1ae4 Void
+0x020 SizeOfImage : 0x43000
+0x024 FullDllName : _UNICODE_STRING "C:\Program Files\S-dir\Some-dir\someapp.dll"
+0x02c BaseDllName : _UNICODE_STRING "someapp.dll"
+0x034 Flags : 0x200006
+0x038 LoadCount : 0
+0x03a TlsIndex : 0
+0x03c HashLinks : _LIST_ENTRY [ 0x7c99e2f0 - 0x252a5c ]
+0x03c SectionPointer : 0x7c99e2f0 Void
+0x040 CheckSum : 0x252a5c
+0x044 TimeDateStamp : 0x5618c3dc
+0x044 LoadedImports : 0x5618c3dc Void
+0x048 EntryPointActivationContext : 0x00153960 Void
+0x04c PatchInformation : (null)

可以看到正在加载someapp.dll,并且处理导入表的时候出了错。来看看这个模块的导入表

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
0:000> !dh someapp -f
File Type: DLL
FILE HEADER VALUES
14C machine (i386)
6 number of sections
5618C3DC time date stamp Sat Oct 10 15:53:00 2015
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
OPTIONAL HEADER VALUES
10B magic #
10.00 linker version
27A00 size of code
15C00 size of initialized data
0 size of uninitialized data
21AE4 address of entry point
1000 base of code
----- new -----
10000000 image base
1000 section alignment
200 file alignment
2 subsystem (Windows GUI)
5.01 operating system version
0.00 image version
5.01 subsystem version
43000 size of image
400 size of headers
4943E checksum
00100000 size of stack reserve
00001000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
140 DLL characteristics
Dynamic base
NX compatible
34BE0 [ 1E0] address [size] of Export Directory
33810 [ B4] address [size] of Import Directory
3A000 [ 4CC] address [size] of Resource Directory
0 [ 0] address [size] of Exception Directory
0 [ 0] address [size] of Security Directory
3B000 [ 3954] address [size] of Base Relocation Directory
29340 [ 1C] address [size] of Debug Directory
0 [ 0] address [size] of Description Directory
0 [ 0] address [size] of Special Directory
2DD80 [ 18] address [size] of Thread Storage Directory
2DD38 [ 40] address [size] of Load Configuration Directory
0 [ 0] address [size] of Bound Import Directory
29000 [ 2CC] address [size] of Import Address Table Directory
0 [ 0] address [size] of Delay Import Directory
0 [ 0] address [size] of COR20 Header Directory
0 [ 0] address [size] of Reserved Directory
0:000> dc someapp+33810 someapp+33810+B4
003d3810 60325c32 68326432 90326c32 b332af32 2\2`2d2h2l2.2.2.
003d3820 d132ca32 df32db32 0032fc32 30332033 2.2.2.2.2.2.3 30
003d3830 40333833 4c334833 54335033 5c335833 [email protected]\
003d3840 64336033 6c336833 74337033 7c337833 3`3d3h3l3p3t3x3|
003d3850 84338033 8c338833 94339033 ce33b433 3.3.3.3.3.3.3.3.
003d3860 e933d233 f733f333 b134a633 0434e134 3.3.3.3.3.4.4.4.
003d3870 44353935 94357135 d435c935 57361a35 595D5q5.5.5.5.6W
003d3880 be366736 0c36d036 4b374037 b3377b37 [email protected]{7.
003d3890 ea37cf37 45380e37 81385e38 a0388a38 7.7.7.8E8^8.8.8.
003d38a0 fb38d338 4b392438 a4399939 0039dd39 8.8.8$9K9.9.9.9.
003d38b0 403a353a c33a863a 2a3ad33a 6b3b3c3b :5:@:.:.:.:*;<;k
003d38c0 cf3b933b 1d3bea3b ;.;.;.;.

所以这样就清楚了,someapp.dll的输入表被破坏了,导致加载他的程序无法运行起来。

debugging