说下安装win8.1遇到几个烦心的事
本帖最后由 元始天尊 于 2015-2-20 11:03 编辑把自己机子上的win7升级为win8.1以后:
1.每次重启后,宽带账号无法登陆,错误651.。。。。。结果百度一下发现是微软bug,安装了某个kb???补丁就ok了
2.msvc启动崩溃,吧Msdev.exe改名就可以了,用windbg调了一下,分析出了一些原因,但是为何改名就可以启动还分析不出来
3.chrome图标双击后弹窗“没有注册类”,网上查了一下,改改注册表,没成功,不打算搞了。
以下是我的分析过程:
用windbg载入,执行到崩溃会有异常Access Violation,此时看调用栈,发现诡异的事情:
0:000> k
ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
0018ed3f 03124100 0x1f2702
0018ed43 4e3e3850 0x3124100
0018ed47 00000000 0x4e3e3850
0:000> !address 03124100
Usage: Stack
Base Address: 030b0000
End Address: 031ac000
Region Size: 000fc000
State: 00002000 MEM_RESERVE
Protect: <info not present at the target>
Type: 00020000 MEM_PRIVATE
Allocation Base: 030b0000
Allocation Protect: 00000004 PAGE_READWRITE
More info: ~3k
0:000> !address 4e3e3850
Usage: Free
Base Address: 03302000
End Address: 50000000
Region Size: 4ccfe000
State: 00010000 MEM_FREE
Protect: 00000001 PAGE_NOACCESS
Type: <info not present at the target>
再用lm查看载入模块,发现栈有问题,初步断定是调用栈损坏,现在无法进入到有问题的函数中,因此要另想办法
~*k查看全部线程调用栈:
0:000> ~*k
.0Id: 3084.4ce4 Suspend: 1 Teb: 7ffdd000 Unfrozen
ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
0018ed3f 03124100 0x1f2702
0018ed43 4e3e3850 0x3124100
0018ed47 00000000 0x4e3e3850
1Id: 3084.1640 Suspend: 1 Teb: 7ffda000 Unfrozen
ChildEBP RetAddr
02f6fde4 77420393 ntdll!NtWaitForWorkViaWorkerFactory+0xc
02f6ff88 76b2919f ntdll!TppWorkerThread+0x259
02f6ff94 7745b5af KERNEL32!BaseThreadInitThunk+0xe
02f6ffdc 7745b57a ntdll!__RtlUserThreadStart+0x2f
02f6ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
2Id: 3084.2d70 Suspend: 1 Teb: 7ffd7000 Unfrozen
ChildEBP RetAddr
0306fde4 77420393 ntdll!NtWaitForWorkViaWorkerFactory+0xc
0306ff88 76b2919f ntdll!TppWorkerThread+0x259
0306ff94 7745b5af KERNEL32!BaseThreadInitThunk+0xe
0306ffdc 7745b57a ntdll!__RtlUserThreadStart+0x2f
0306ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
3Id: 3084.243c Suspend: 1 Teb: 7fe9f000 Unfrozen
ChildEBP RetAddr
031afb70 76250927 ntdll!NtWaitForMultipleObjects+0xc
031afcf4 771c5fd0 KERNELBASE!WaitForMultipleObjectsEx+0xcc
031afe28 771c603e combase!WaitCoalesced+0x73
031afe50 771c6101 combase!CROIDTable::WorkerThreadLoop+0x4b
031aff78 771c6257 combase!CRpcThread::WorkerLoop+0x2e
031aff88 76b2919f combase!CRpcThreadCache::RpcWorkerThreadEntry+0x16
031aff94 7745b5af KERNEL32!BaseThreadInitThunk+0xe
031affdc 7745b57a ntdll!__RtlUserThreadStart+0x2f
031affec 00000000 ntdll!_RtlUserThreadStart+0x1b
4Id: 3084.2ae0 Suspend: 1 Teb: 7fe9c000 Unfrozen
ChildEBP RetAddr
032efd00 76250927 ntdll!NtWaitForMultipleObjects+0xc
032efe84 76b29188 KERNELBASE!WaitForMultipleObjectsEx+0xcc
*** ERROR: Symbol file could not be found.Defaulted to export symbols for D:\VS1999\COMMON\MSDEV98\BIN\devshl.dll -
032efea0 50031876 KERNEL32!WaitForMultipleObjects+0x19
WARNING: Stack unwind information not available. Following frames may be wrong.
032efecc 500317e5 devshl!Ordinal5687+0x8a
032efed4 5da272c6 devshl!Ordinal5569+0x24
032eff48 769e0bc4 MFC42!_AfxThreadEntry+0xdd
032eff80 769e0cec msvcrt!_beginthreadex+0xc9
032eff88 76b2919f msvcrt!_endthreadex+0x8a
032eff94 7745b5af KERNEL32!BaseThreadInitThunk+0xe
032effdc 7745b57a ntdll!__RtlUserThreadStart+0x2f
032effec 00000000 ntdll!_RtlUserThreadStart+0x1b
发现出问题的线程为0号线程,而作为跳板,线程4比较靠谱,因此第一个断点设置在500317e5的上一条指令处。重新加载程序,在该处下断点,等断下后将前4个线程冻结,只留当前线程
~*f
~4s
~u
之后运行到线程结束,再切换回0号线程,做“执行到返回”操作N次,直到重现异常,如果发生异常,则记住该位置下次执行之前做步入操作,这样一点点缩小bug出现位置的范围,
devedit!InitPackage+0x56:
50822bb8 85c0 test eax,eax
devshl!Ordinal3467+0x9a:
50036fa3 83c410 add esp,10h
devshl!Ordinal3467+0x95:
50036f9e e847a2ffff call devshl!Ordinal4845+0x30 (500311ea)
devshl!Ordinal3467+0x95:
50036f9e e847a2ffff call devshl!Ordinal4845+0x30 (500311ea)
while ( 1 )
{
v4 = sub_500311EA(*(HMODULE *)(dword_500FFDA0 + 4 * v3), (CStringList *)&v25, 0);
if ( !v4 && !*(_DWORD *)(v2 + 644) )
break;
if ( v4 == 1 )
++*(_DWORD *)a2;
++v3;
if ( v3 >= dword_500FFD9C )
goto LABEL_9;
}
500311EA DevShl.dll Ordinal5125
执行到这里,发现第二次调用该函数时出现异常,因此下次重新加载之后先步过一次,第二次再步入,继续定位:
devshl!Ordinal4845+0x82:
5003123c e8e7010000 call devshl!Ordinal4845+0x26e (50031428)
CStringList::Find((CStringList *)&unk_500FEBD0, v27, 0)
MFC42!CStringList::Find+0x18:
62ffb49e e843feffff call MFC42!operator== (62ffb2e6)
62ffb4a3 84c0 test al,al
0:000> u 62ffb2e6
MFC42!operator==:
62ffb2e6 8bff mov edi,edi
62ffb2e8 52 push edx
62ffb2e9 ff31 push dword ptr
62ffb2eb ff150c410963 call dword ptr
62ffb2f1 f7d8 neg eax
62ffb2f3 59 pop ecx
62ffb2f4 1bc0 sbb eax,eax
62ffb2f6 59 pop ecx
0:000> uf 62ffb2e6
MFC42!operator==:
62ffb2e6 8bff mov edi,edi
62ffb2e8 52 push edx
62ffb2e9 ff31 push dword ptr
62ffb2eb ff150c410963 call dword ptr
62ffb2f1 f7d8 neg eax
62ffb2f3 59 pop ecx
62ffb2f4 1bc0 sbb eax,eax
62ffb2f6 59 pop ecx
62ffb2f7 40 inc eax
62ffb2f8 c3 ret
最后定位到了MFC42.dll的_imp__mbscmp函数中,_imp前缀的函数其实是为导入库_declspec(dllimport)产生的,位于在pe导入表中,里面有4字节数据,系统在加载后动态地将函数_mbscmp真正的地址写入该处以实现动态绑定,之后就可以通过call dword ptr进行调用了。下面来看
0:000> u MFC42!_imp___mbscmp
MFC42!_imp___mbscmp:
6309410c 0000 add byte ptr ,al
6309410e 0300 add eax,dword ptr
MFC42!_imp___mbscmp 的数据为03000000,
0:000> u .
0003000a 83781800 cmp dword ptr ,0
0003000e 751a jne 0003002a
00030010 c74010ffffffffmov dword ptr ,0FFFFFFFFh
00030017 c74001000000ffmov dword ptr ,0FF000000h
0003001e 896040 mov dword ptr ,esp
00030021 0000 add byte ptr ,al
00030023 00ff add bh,bh
00030025 159426b663 adc eax,offset AcGenral!g_pfnStackSwap (63b62694)
0:000> u poi(6309410c)
00030000 64a1180f0000 mov eax,dword ptr fs:
00030006 0bc0 or eax,eax
00030008 7420 je 0003002a
0003000a 83781800 cmp dword ptr ,0
0003000e 751a jne 0003002a
00030010 c74010ffffffffmov dword ptr ,0FFFFFFFFh
00030017 c74001000000ffmov dword ptr ,0FF000000h
0003001e 896040 mov dword ptr ,esp
该处的代码没有任何意义,完全不是mbscmp的代码,mbscmp应该是个比较函数的!!!,而_mbscmp 函数真正的地址为:
0:000> u _mbscmp
msvcrt!_mbscmp:
759f5153 8bff mov edi,edi
759f5155 55 push ebp
759f5156 8bec mov ebp,esp
759f5158 6a00 push 0
759f515a ff750c push dword ptr
759f515d ff7508 push dword ptr
759f5160 e80a000000 call msvcrt!_mbscmp_l (759f516f)
759f5165 83c40c add esp,0Ch
也就是说在写导入表时产生了错误,但是为什么是30000呢,带着这个疑问,我又继续分析:
由于_imp___mbscmp是mfc42.dll的,因此需要等待该dll加载以后才可以下断点
sxe ld mfc42
ba r4 6309410C
硬件断点共断下3次:
Breakpoint 0 hit
eax=00000000 ebx=00000294 ecx=75965153 edx=75940000 esi=75941a60 edi=6527410c
eip=778a8db9 esp=0018f8a0 ebp=0018fab0 iopl=0 nv up ei pl zr na pe nc
cs=0023ss=002bds=002bes=002bfs=0053gs=002b efl=00000246
ntdll!LdrpSnapModule+0x37c:
778a8db9 8b8d50feffff mov ecx,dword ptr ss:002b:0018f900={MFC42!_imp__GetVersion (6527503c)}
0:000> ub
ntdll!LdrpSnapModule+0x35c:
778a8d99 898590feffff mov dword ptr ,eax
778a8d9f 898558feffff mov dword ptr ,eax
778a8da5 3bce cmp ecx,esi
778a8da7 7730 ja ntdll!LdrpSnapModule+0x3a6 (778a8dd9)
778a8da9 85c0 test eax,eax
778a8dab 0f88c3370400 js ntdll!LdrpSnapModule+0x43dd7 (778ec574)
778a8db1 8bbd3cfeffff mov edi,dword ptr
778a8db7 890f mov dword ptr ,ecx
查看写入_imp的地址,发现确实是_mbscmp函数的:
0:000> u ecx
msvcrt!_mbscmp:
75965153 8bff mov edi,edi
75965155 55 push ebp
75965156 8bec mov ebp,esp
75965158 6a00 push 0
7596515a ff750c push dword ptr
7596515d ff7508 push dword ptr
75965160 e80a000000 call msvcrt!_mbscmp_l (7596516f)
75965165 83c40c add esp,0Ch
Breakpoint 0 hit
eax=ffffffff ebx=00614c90 ecx=6527410c edx=75965153 esi=0062dce0 edi=00000100
eip=73d5402f esp=0018f9dc ebp=0018fa2c iopl=0 nv up ei ng nz na pe nc
cs=0023ss=002bds=002bes=002bfs=0053gs=002b efl=00000286
apphelp!SepRouterHookImportedApi+0x7f:
73d5402f 8bda mov ebx,edx
0:000> ub
apphelp!SepRouterHookImportedApi+0x6a:
73d5401a 8bcf mov ecx,edi
73d5401c 83e11f and ecx,1Fh
73d5401f c1ef05 shr edi,5
73d54022 83c8ff or eax,0FFFFFFFFh
73d54025 d3e0 shl eax,cl
73d54027 8b4dc8 mov ecx,dword ptr
73d5402a 8945d8 mov dword ptr ,eax
73d5402d 8b11 mov edx,dword ptr
这一次是从_imp读取地址,此时该地址还是正常的
0:000> u ecx
MFC42!_imp___mbscmp:
6527410c 53 push ebx
6527410d 51 push ecx
6527410e 96 xchg eax,esi
6527410f 75d3 jne MFC42!_imp___vscprintf (652740e4)
65274111 c29475 ret 7594h
Breakpoint 0 hit
eax=00030000 ebx=0018fa54 ecx=d6e90000 edx=00000000 esi=0018fa50 edi=6527410c
eip=73d54af3 esp=0018f98c ebp=0018f9d0 iopl=0 nv up ei ng nz na pe cy
cs=0023ss=002bds=002bes=002bfs=0053gs=002b efl=00000287
apphelp!SepIatPatch+0x40:
73d54af3 c745e401000000mov dword ptr ,1 ss:002b:0018f9b4=00000000
0:000> ub
apphelp!SepIatPatch+0x26:
73d54ad9 3b3b cmp edi,dword ptr
73d54adb 0f8248920200 jb apphelp!SepIatPatch+0x29276 (73d7dd29)
73d54ae1 8b4608 mov eax,dword ptr
73d54ae4 0303 add eax,dword ptr
73d54ae6 3bf8 cmp edi,eax
73d54ae8 0f833b920200 jae apphelp!SepIatPatch+0x29276 (73d7dd29)
73d54aee 8b4508 mov eax,dword ptr
73d54af1 8907 mov dword ptr ,eax
此时是写入_imp地址,可以看出这一次写入的地址是0x30000
0:000> u eax
00030000 64a1180f0000 mov eax,dword ptr fs:
00030006 0bc0 or eax,eax
00030008 7420 je 0003002a
0003000a 83781800 cmp dword ptr ,0
0003000e 751a jne 0003002a
00030010 c74010ffffffffmov dword ptr ,0FFFFFFFFh
00030017 c74001000000ffmov dword ptr ,0FF000000h
0003001e 896040 mov dword ptr ,esp
从上面过程可以看出,2次写入过程,第一次写入的是正常的_mbscmp地址,而第二次对该地址写入则是错误的,
很奇怪,写一次就够了啊,为什么要写多次,可以看出第二次写入是apphelp.dll搞的鬼,SepIatPatch这个函数我没查到,不过从名称上看,
像是hook Iat,而这块代码因某种原因未成功。
0:000> k
ChildEBP RetAddr
0018f9d0 73d54a31 apphelp!SepIatPatch+0x40
0018fa2c 73d53c72 apphelp!SepRouterHookImportedApi+0x1e6
0018fa70 73d53b37 apphelp!SepRouterHookIAT+0x123
0018fa8c 73d53ae9 apphelp!SeRouterHookDll+0x34
0018fa9c 778608b4 apphelp!SE_DllLoaded+0x6c
0018fac8 778a9485 ntdll!LdrpSendPostSnapNotifications+0xe7
0018fad8 778a9ad1 ntdll!LdrpNotifyLoadOfGraph+0x3c
0018fae8 778a8cf1 ntdll!LdrpNotifyLoadOfGraph+0x22
0018fb10 778b2556 ntdll!LdrpPrepareModuleForExecution+0xf0
0018fcb8 778b17ec ntdll!LdrpInitializeProcess+0x14ec
0018fd08 778995a6 ntdll!_LdrpInitialize+0xad
0018fd10 00000000 ntdll!LdrInitializeThunk+0x10
就研究到这里吧,如果哪位高人知道PEB->VDM结构或者msdev改名之后影响了系统什么变数,不妨告知一二
改了名的msdev1.exe就没有加载apphelp.dll。。。。。。。。。。奇怪
页:
[1]