元始天尊 发表于 2015-2-20 01:15:06

说下安装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]
查看完整版本: 说下安装win8.1遇到几个烦心的事