首页
社区
课程
招聘
[原创]逆向分析:修复老古董vs2005笔记
发表于: 2022-3-19 16:32 12516

[原创]逆向分析:修复老古董vs2005笔记

2022-3-19 16:32
12516

由于工作需要,还在用vs2005这个老古董,虽然很不喜欢。

虽然很轻,但有两个原因不喜欢:

无法启动这个事已经无数次出现了,重装,重启,屏蔽Assist均是无效。

后来无意间点击了C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\IDE\devenv.com,可以启动了。

但这次这个方法也不行了,实在是忍无可忍。

决定干它。

上调试器,启动devenv.exe

看到崩溃原因 c00000fd,就是栈溢出,看来应该是函数调用无限循环了。

不要问我为啥知道,因为之前遇到过。

看看栈,果然如此,user32->msdev!xxx->user32->msdev!xxx->...

打开IDA,简单看看msenv

CAutoCompletionManagerCL::TargetSubclassProcSTATIC应该是个wndproc,本来逻辑应该是在内部CallWindowProcAW调用原始wndproc,但是CallWindowProcAW又调用了CAutoCompletionManagerCL::TargetSubclassProcSTATIC,这样死循环,一直到栈溢出。

看看CAutoCompletionManagerCL::TargetSubclassProcSTATIC是哪里设置的,找到了:

所以问题应该基本清晰了,SetWindowLongW(v11, -4, (LONG)CAutoCompletionManagerCL::TargetSubclassProcSTATIC);被重复设置了,*((_DWORD *)this + 12) = v7,保存的值被覆盖成了CAutoCompletionManagerCL::TargetSubclassProcSTATIC

所以这样死循环,导致调用栈溢出

第一次进入msenv!CAutoCompletionManagerCL::AttachToCombo设置SetWindowLongW返回就已经是msenv!CAutoCompletionManagerCL::TargetSubclassProcSTATIC

赋值之前看到原始地址:

猜测CAutoCompletionManager::OnCreate中就已经调用SetWindowLongW了

尝试使用条件断点看看能不能找到。

断下后,确认函数没问题,看看调用栈。

可以看到msenv!CAutoCompletionManagerCL::VerifyAttachmentOnCreate内部设置了一次。

所以应该是msevn逻辑出现了问题,应该加上控件创建成功后,才能SetWindowsLong,或者直接在SetWindowLong之前判断是否已经设置过。

我可以给他改改代码,但是挺麻烦的。

再看看是不是有什么可以控制的条件,有更简单的修改方法。

看看CAutoCompletionManagerCL::AttachToCombo被谁调用了:

看看CAutoCompletionManagerCL::UseAutocompletion的逻辑:

猜测跟代码自动完成有关,这个CCmdWindow::ms_fEnableAutocompletion变量好像可以弄弄,如果设置为假,就完全不会进入后面的逻辑。

现在看看CCmdWindow::ms_fEnableAutocompletion在哪里设置的。

好像有戏,CommandWindowAutocompletion是用户配置相关的。CommandWindowAutocompletion未配置默认开启ms_fEnableAutocompletion

通过调试确认,最终找到配置位置:

增加注册表CommandWindowAutocompletion,设置为0,这样ms_fEnableAutocompletion就是0,问题解决。

看名字这个有点像代码自动完成功能的,但不知道ms_fEnableAutocompletion配置为0之后会不会影响该功能。

哈哈,经过验证没有影响,终于又可以正常使用这个老古董了。

(完)

 
 
 
 
 
 
 
 
0:000:x86> kn 10
 # ChildEBP RetAddr 
00 000a3048 76cb9cae ntdll_77660000!RtlActivateActivationContextUnsafeFast+0x18
01 000a3118 76cb9577 USER32!UserCallWinProcCheckWow+0x14e
02 000a3150 76cb771b USER32!CallWindowProcAorW+0x7f
03 000a3168 059dea67 USER32!CallWindowProcW+0x1b //5007ea67
04 000a3188 059dea34 msenv!CAutoCompletionManagerCL::TargetSubclassProc+0x29
05 000a31a4 76cc2edb msenv!CAutoCompletionManagerCL::TargetSubclassProcSTATIC+0x2a
06 000a31d0 76cb9e9a USER32!_InternalCallWinProc+0x2b
07 000a32b4 76cb9577 USER32!UserCallWinProcCheckWow+0x33a
08 000a32ec 76cb771b USER32!CallWindowProcAorW+0x7f
09 000a3304 059dea67 USER32!CallWindowProcW+0x1b
0a 000a3324 059dea34 msenv!CAutoCompletionManagerCL::TargetSubclassProc+0x29
0b 000a3340 76cc2edb msenv!CAutoCompletionManagerCL::TargetSubclassProcSTATIC+0x2a
0c 000a336c 76cb9e9a USER32!_InternalCallWinProc+0x2b
0d 000a3450 76cb9577 USER32!UserCallWinProcCheckWow+0x33a
0e 000a3488 76cb771b USER32!CallWindowProcAorW+0x7f
0f 000a34a0 059dea67 USER32!CallWindowProcW+0x1b
...
0:000:x86> kn 10
 # ChildEBP RetAddr 
00 000a3048 76cb9cae ntdll_77660000!RtlActivateActivationContextUnsafeFast+0x18
01 000a3118 76cb9577 USER32!UserCallWinProcCheckWow+0x14e
02 000a3150 76cb771b USER32!CallWindowProcAorW+0x7f
03 000a3168 059dea67 USER32!CallWindowProcW+0x1b //5007ea67
04 000a3188 059dea34 msenv!CAutoCompletionManagerCL::TargetSubclassProc+0x29
05 000a31a4 76cc2edb msenv!CAutoCompletionManagerCL::TargetSubclassProcSTATIC+0x2a
06 000a31d0 76cb9e9a USER32!_InternalCallWinProc+0x2b
07 000a32b4 76cb9577 USER32!UserCallWinProcCheckWow+0x33a
08 000a32ec 76cb771b USER32!CallWindowProcAorW+0x7f
09 000a3304 059dea67 USER32!CallWindowProcW+0x1b
0a 000a3324 059dea34 msenv!CAutoCompletionManagerCL::TargetSubclassProc+0x29
0b 000a3340 76cc2edb msenv!CAutoCompletionManagerCL::TargetSubclassProcSTATIC+0x2a
0c 000a336c 76cb9e9a USER32!_InternalCallWinProc+0x2b
0d 000a3450 76cb9577 USER32!UserCallWinProcCheckWow+0x33a
0e 000a3488 76cb771b USER32!CallWindowProcAorW+0x7f
0f 000a34a0 059dea67 USER32!CallWindowProcW+0x1b
...
int __userpurge CAutoCompletionManagerCL::TargetSubclassProcSTATIC@<eax>(int a1@<esi>, HWND a2, unsigned int a3, unsigned int a4, unsigned int a5)
{
  CAutoCompletionManagerCL *v5; // ecx
  int result; // eax
 
  if ( GetPropW(a2, L"MSENV_ACMgr") )
    result = CAutoCompletionManagerCL::TargetSubclassProc(v5, a2, a4, a5, a1);
  else
    result = DefWindowProcAW(a2, a3, a4, a5);
  return result;
}
 
text:5007EA3A 000                 push    ebp
.text:5007EA3B 004                 mov     ebp, esp
.text:5007EA3D 004                 cmp     ebx, 0Eh
.text:5007EA40 004                 push    edi
.text:5007EA41 008                 jnz     loc_500FEDCF
.text:5007EA47 008                 mov     dword ptr [esi+34h], 1
.text:5007EA4E
.text:5007EA4E     loc_5007EA4E:                           ; CODE XREF: CAutoCompletionManagerCL::TargetSubclassProc(HWND__ *,uint,uint,long)+803C6↓j
.text:5007EA4E                                             ; CAutoCompletionManagerCL::TargetSubclassProc(HWND__ *,uint,uint,long)+17B9CA↓j ...
.text:5007EA4E 008                 mov     eax, [esi+30h] //=0 不会再调用CallWindowProcAW
.text:5007EA51 008                 xor     edi, edi
.text:5007EA53 008                 test    eax, eax
.text:5007EA55 008                 jz      short loc_5007EA69
.text:5007EA57 008                 push    [ebp+arg_8]
.text:5007EA5A 00C                 push    [ebp+arg_4]
.text:5007EA5D 010                 push    ebx
.text:5007EA5E 014                 push    [ebp+arg_0]
.text:5007EA61 018                 push    eax //调用原始函数
.text:5007EA62 01C                 call    ?CallWindowProcAW@@YGJP6GJPAUHWND__@@IIJ@Z0IIJ@Z ; CallWindowProcAW(long (*)(HWND__ *,uint,uint,long),HWND__ *,uint,uint,long)
.text:5007EA67 008                 mov     edi, eax
.text:5007EA69
.text:5007EA69     loc_5007EA69:                           ; CODE XREF: CAutoCompletionManagerCL::TargetSubclassProc(HWND__ *,uint,uint,long)+1B↑j
.text:5007EA69 008                 cmp     ebx, 82h
.text:5007EA6F 008                 jz      loc_501B3877
.text:5007EA75
int __userpurge CAutoCompletionManagerCL::TargetSubclassProcSTATIC@<eax>(int a1@<esi>, HWND a2, unsigned int a3, unsigned int a4, unsigned int a5)
{
  CAutoCompletionManagerCL *v5; // ecx
  int result; // eax
 
  if ( GetPropW(a2, L"MSENV_ACMgr") )
    result = CAutoCompletionManagerCL::TargetSubclassProc(v5, a2, a4, a5, a1);
  else
    result = DefWindowProcAW(a2, a3, a4, a5);
  return result;
}
 
text:5007EA3A 000                 push    ebp
.text:5007EA3B 004                 mov     ebp, esp
.text:5007EA3D 004                 cmp     ebx, 0Eh
.text:5007EA40 004                 push    edi
.text:5007EA41 008                 jnz     loc_500FEDCF
.text:5007EA47 008                 mov     dword ptr [esi+34h], 1
.text:5007EA4E
.text:5007EA4E     loc_5007EA4E:                           ; CODE XREF: CAutoCompletionManagerCL::TargetSubclassProc(HWND__ *,uint,uint,long)+803C6↓j
.text:5007EA4E                                             ; CAutoCompletionManagerCL::TargetSubclassProc(HWND__ *,uint,uint,long)+17B9CA↓j ...
.text:5007EA4E 008                 mov     eax, [esi+30h] //=0 不会再调用CallWindowProcAW
.text:5007EA51 008                 xor     edi, edi
.text:5007EA53 008                 test    eax, eax
.text:5007EA55 008                 jz      short loc_5007EA69
.text:5007EA57 008                 push    [ebp+arg_8]
.text:5007EA5A 00C                 push    [ebp+arg_4]
.text:5007EA5D 010                 push    ebx
.text:5007EA5E 014                 push    [ebp+arg_0]
.text:5007EA61 018                 push    eax //调用原始函数
.text:5007EA62 01C                 call    ?CallWindowProcAW@@YGJP6GJPAUHWND__@@IIJ@Z0IIJ@Z ; CallWindowProcAW(long (*)(HWND__ *,uint,uint,long),HWND__ *,uint,uint,long)
.text:5007EA67 008                 mov     edi, eax
.text:5007EA69
.text:5007EA69     loc_5007EA69:                           ; CODE XREF: CAutoCompletionManagerCL::TargetSubclassProc(HWND__ *,uint,uint,long)+1B↑j
.text:5007EA69 008                 cmp     ebx, 82h
.text:5007EA6F 008                 jz      loc_501B3877
.text:5007EA75
 
int __userpurge CAutoCompletionManagerCL::AttachToCombo@<eax>(CAutoCompletionManagerCL *this@<ecx>, int a2@<eax>, struct IMsoControl *a3, HWND a4)
{
  result = CAutoCompletionManager::OnCreate(this); //创建控件
  if ( result >= 0 && !result )
  {
 
    v11 = (HWND)*((_DWORD *)this + 10);
    if ( v6 )
      v7 = SetWindowLongW(v11, -4, (LONG)CAutoCompletionManagerCL::TargetSubclassProcSTATIC);
    else
      v7 = SetWindowLongA(v11, -4, (LONG)CAutoCompletionManagerCL::TargetSubclassProcSTATIC);
    v13 = (HWND)*((_DWORD *)this + 10);
    *((_DWORD *)this + 12) = v7; //+30 = 1
int __userpurge CAutoCompletionManagerCL::AttachToCombo@<eax>(CAutoCompletionManagerCL *this@<ecx>, int a2@<eax>, struct IMsoControl *a3, HWND a4)
{
  result = CAutoCompletionManager::OnCreate(this); //创建控件
  if ( result >= 0 && !result )
  {
 
    v11 = (HWND)*((_DWORD *)this + 10);
    if ( v6 )
      v7 = SetWindowLongW(v11, -4, (LONG)CAutoCompletionManagerCL::TargetSubclassProcSTATIC);
    else
      v7 = SetWindowLongA(v11, -4, (LONG)CAutoCompletionManagerCL::TargetSubclassProcSTATIC);
    v13 = (HWND)*((_DWORD *)this + 10);
    *((_DWORD *)this + 12) = v7; //+30 = 1
 
 
 
msenv!CAutoCompletionManagerCL::AttachToCombo+0x60:
05910cb5 894330          mov     dword ptr [ebx+30h],eax ds:002b:06e03228={msenv!_FakeEditProc (0596eab8)}
msenv!CAutoCompletionManagerCL::AttachToCombo+0x60:
05910cb5 894330          mov     dword ptr [ebx+30h],eax ds:002b:06e03228={msenv!_FakeEditProc (0596eab8)}
 
0:000:x86> u CAutoCompletionManagerCL::TargetSubclassProcSTATIC
msenv!CAutoCompletionManagerCL::TargetSubclassProcSTATIC:
05aeea06 55              push    ebp
0:000:x86> bc 1
0:000:x86> bp USER32!SetWindowLongW ".if(poi(esp+c)==05aeea06 ){}.else{g};"
0:000:x86> u CAutoCompletionManagerCL::TargetSubclassProcSTATIC
msenv!CAutoCompletionManagerCL::TargetSubclassProcSTATIC:
05aeea06 55              push    ebp
0:000:x86> bc 1
0:000:x86> bp USER32!SetWindowLongW ".if(poi(esp+c)==05aeea06 ){}.else{g};"
 
USER32!SetWindowLongW:
76cb7730 8bff            mov     edi,edi
0:000:x86> dd esp
00194a2c  05c6a3cc 00093096 fffffffc 05aeea06
00194a3c  07747120 00000000 05aeec46 00000000
 
0:000:x86> kn
 # ChildEBP RetAddr 
00 00194a28 05c6a3cc USER32!SetWindowLongW
01 00194a40 05aeec46 msenv!CAutoCompletionManagerCL::VerifyAttachment+0x69
02 00194a50 05aee7ca msenv!CAutoCompletionManagerCL::VerifyAllAttachments+0x31
03 00194a70 05ae2021 msenv!CAutoCompletionManagerCL::UseAutocompletion+0x3f
04 00194abc 05ae1ceb msenv!CMsoDropdownUser::GetText+0x12f
...
18 001961b0 76cc2edb msenv!TBWndWindowProc+0x65
19 001961dc 76cb9e9a USER32!_InternalCallWinProc+0x2b
1a 001962c0 76cb9a9a USER32!UserCallWinProcCheckWow+0x33a
...
49 00198424 05a90d54 msenv!CVsAutoCompletion::InitUI+0x251
4a 00198440 05a90c6b msenv!CAutoCompletionManager::OnCreate+0x58 //这里是创建
4b 00198448 05a90ae1 msenv!CAutoCompletionManagerCL::AttachToCombo+0x12
4c 00198468 05ae2021 msenv!CAutoCompletionManagerCL::UseAutocompletion+0x95
4d 001984b0 05a90a72 msenv!CMsoDropdownUser::GetText+0x12f
4e 001984c8 05a9096b msenv!TBCDD::ResetEditText+0x12
4f 0019c6d8 05b018aa msenv!TBCDD::FDraw+0x684
50 0019c84c 05b013cc msenv!TB::FDraw+0xbb7
51 0019c8c8 76cc2edb msenv!TBWndProc+0xfa
52 0019c8f4 76cb9e9a USER32!_InternalCallWinProc+0x2b
 
int __usercall CAutoCompletionManagerCL::VerifyAttachment@<eax>(int a1@<esi>)
{
 
      v7 = *(HWND *)(a1 + 40);
      if ( v4 )
        v5 = SetWindowLongW(v7, -4, (LONG)CAutoCompletionManagerCL::TargetSubclassProcSTATIC);
      else
        v5 = SetWindowLongA(v7, -4, (LONG)CAutoCompletionManagerCL::TargetSubclassProcSTATIC);
      *(_DWORD *)(a1 + 48) = v5;
    }
}
USER32!SetWindowLongW:
76cb7730 8bff            mov     edi,edi
0:000:x86> dd esp
00194a2c  05c6a3cc 00093096 fffffffc 05aeea06
00194a3c  07747120 00000000 05aeec46 00000000
 
0:000:x86> kn
 # ChildEBP RetAddr 
00 00194a28 05c6a3cc USER32!SetWindowLongW
01 00194a40 05aeec46 msenv!CAutoCompletionManagerCL::VerifyAttachment+0x69
02 00194a50 05aee7ca msenv!CAutoCompletionManagerCL::VerifyAllAttachments+0x31
03 00194a70 05ae2021 msenv!CAutoCompletionManagerCL::UseAutocompletion+0x3f
04 00194abc 05ae1ceb msenv!CMsoDropdownUser::GetText+0x12f
...
18 001961b0 76cc2edb msenv!TBWndWindowProc+0x65
19 001961dc 76cb9e9a USER32!_InternalCallWinProc+0x2b
1a 001962c0 76cb9a9a USER32!UserCallWinProcCheckWow+0x33a
...
49 00198424 05a90d54 msenv!CVsAutoCompletion::InitUI+0x251
4a 00198440 05a90c6b msenv!CAutoCompletionManager::OnCreate+0x58 //这里是创建
4b 00198448 05a90ae1 msenv!CAutoCompletionManagerCL::AttachToCombo+0x12

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-3-19 16:50 被anhkgg编辑 ,原因:
收藏
免费 10
支持
分享
最新回复 (3)
雪    币: 221
活跃值: (2311)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
学习了.
2022-3-19 21:08
0
雪    币: 3738
活跃值: (3872)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
感谢分享!
2022-3-25 00:04
0
游客
登录 | 注册 方可回帖
返回
//