由于工作需要,还在用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::VerifyAttachment
在OnCreate
内部设置了一次。
所以应该是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
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
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
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
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
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-3-19 16:50
被anhkgg编辑
,原因: