长亭百川云 - 文章详情

vs2005无法启动分析笔记

汉客儿安全笔记

39

2024-07-13

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

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

  1. 调试总要加载符号,不让加非加,慢的无语

  2. 时不时总是无缘无故无法启动

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

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

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

决定干它。

上调试器,启动devenv.exe

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

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

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

0:000:x86> kn 10

打开IDA,简单看看msdev

int __userpurge CAutoCompletionManagerCL::TargetSubclassProcSTATIC@<eax>(int a1@<esi>, HWND a2, unsigned int a3, unsigned int a4, unsigned int a5)

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

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

int __userpurge CAutoCompletionManagerCL::AttachToCombo@<eax>(CAutoCompletionManagerCL *this@<ecx>, int a2@<eax>, struct IMsoControl *a3, HWND a4)

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

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

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

赋值之前看到原始地址:

msenv!CAutoCompletionManagerCL::AttachToCombo+0x60:

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

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

0:000:x86> u CAutoCompletionManagerCL::TargetSubclassProcSTATIC

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

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

USER32!SetWindowLongW:

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

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

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

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

Breakpoint 0 hit

看看CAutoCompletionManagerCL::UseAutocompletion的逻辑:

int __userpurge CAutoCompletionManagerCL::UseAutocompletion@<eax>(CVSShellMenu *a1@<ecx>, struct IMsoControl *a2@<edi>, struct IMsoControl *a3)

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

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

void __stdcall PrefInitPart2()

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

int __userpurge GetUserOption@<eax>(int a1@<eax>, LPCWSTR lpValueName, LPBYTE lpData, DWORD cbData, unsigned int a5)

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

计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\8.0\General

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

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

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

(完)

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2