附:您可以直接看最后几行的结论。。。。。。
下午正逆向的带劲,要查windows内核某函数参数,向平常一样打开source insight, 令人喷饭的是
si竟然异常了,这软件也能异常。还以来中了什么东西被人插了,看看它的进程模块,无异常,难道
是被无模块的插了?本人行走江湖有些年头了,向来小心,这种可能性不大。算了,换版本。
于是google,迅雷一起上,soso地下来3,4个版本,一痛装啊,再令人喷饭的是,全都异常。
再google之,有人说需要把什么注册表的什么地方、我的文档里的source insight目录删除,好,我删。
再开,还是异常。受不了,直接上OD。
OD加载之,异常发生此外:
00412993 /$ 55 push ebp
00412994 |. 8BEC mov ebp, esp
00412996 |. 51 push ecx
00412997 |. FF75 08 push dword ptr [ebp+8] ; /Arg1
0041299A |. E8 DCFAFFFF call 0041247B ; \Insight3.0041247B
0041299F |. 8945 FC mov dword ptr [ebp-4], eax
004129A2 |. 8B45 0C mov eax, dword ptr [ebp+C]
004129A5 |. 83E0 01 and eax, 1
004129A8 |. C1E0 08 shl eax, 8
004129AB |. 8B4D FC mov ecx, dword ptr [ebp-4]
004129AE 8B09 mov ecx, dword ptr [ecx] ;这里异常了
异常发生在最后一句指令处,即mov ecx, dword ptr [ecx],此时ecx为0,看看,ecx就是call 0041247B
的返回值,在这个call处下断,ctrl+F2重新加载,第一次断下,[ebp+8]为0,call 0041247B返回某个地址,正常。
第二次断下,[ebp+8]为-1,call 0041247B返回0,执行到004129AE处,当然异常了。
看来,原因出在[ebp+8]这个参数上,第二次断下的时候,看栈:
调用堆栈: 主线程
地址 堆栈 函数过程 / 参数 调用来自 结构
0006F550 00446393 Insight3.00412993 Insight3.0044638E 0006F86C
0006F554 00000001 Arg1 = 00000001
0006F558 00000000 Arg2 = 00000000
0006F870 00445FE6 Insight3.00446132 Insight3.00445FE1 0006F86C
0006F874 00000000 Arg1 = 00000000
0006F878 0006FAA8 Arg2 = 0006FAA8
0006F87C 00000001 Arg3 = 00000001
0006F880 00000001 Arg4 = 00000001
0006F884 0000000A Arg5 = 0000000A
0006F888 0006FED0 Arg6 = 0006FED0
0006FED8 0044070A Insight3.00445DAE Insight3.00440705 0006FED4
0006FEDC 00091F0E Arg1 = 00091F0E
0006FEE0 0000000A Arg2 = 0000000A
0006FEE4 0006FF2C Arg3 = 0006FF2C
0006FF38 005214AB Insight3.004405A8 Insight3.<模块入口点>+0C9 0006FF34
0006FF3C 00400000 Arg1 = 00400000
0006FF40 00000000 Arg2 = 00000000
0006FF44 00091F0E Arg3 = 00091F0E
0006FF48 0000000A Arg4 = 0000000A
调用是从00446132发起来,返回地址是00446393,跟随到这个返回地址看看:
0044636E |> \6A 00 push 0 ; /Arg4 = 00000000
00446370 |. 68 60805C00 push 005C8060 ; |Arg3 = 005C8060 ASCII "C:\DOCUME~1\DevUser\LOCALS~1\Temp\"
00446375 |. 6A 00 push 0 ; |Arg2 = 00000000
00446377 |. 68 BCCE5B00 push 005BCEBC ; |Arg1 = 005BCEBC ASCII "TFXXXXXX"
0044637C |. E8 2ACAFCFF call 00412DAB ; \Insight3.00412DAB
00446381 |. A3 D8955C00 mov dword ptr [5C95D8], eax
00446386 |. 6A 00 push 0
00446388 |. FF35 D8955C00 push dword ptr [5C95D8]
0044638E |. E8 00C6FCFF call 00412993 <----出问题的call
00446393 |. 833D D8955C00>cmp dword ptr [5C95D8], -1 <----返回到这里
可以看出,出问题的call的参数,就是5C95D8的内容,也就是call 00412DAB的返回值,也就是说当
call 00412DAB 返回-1时,就会出现当前的这个异常,于是在call 00412DAB处下断,经过数次粗跟,
可以断定当第二次断在这里时,这个call返回-1,于是,重新加载,第二次断在这里时,F7跟入
00412DAB /$ 55 push ebp
00412DAC |. 8BEC mov ebp, esp
00412DAE |. 81EC 00010000 sub esp, 100
00412DB4 |. 56 push esi
00412DB5 |. 57 push edi
00412DB6 |. 8D85 00FFFFFF lea eax, dword ptr [ebp-100]
00412DBC |. 50 push eax ; /Arg4
00412DBD |. FF75 10 push dword ptr [ebp+10] ; |Arg3
00412DC0 |. FF75 0C push dword ptr [ebp+C] ; |Arg2
00412DC3 |. FF75 08 push dword ptr [ebp+8] ; |Arg1
00412DC6 |. E8 D1FEFFFF call 00412C9C ; \Insight3.00412C9C
00412DCB |. 85C0 test eax, eax
00412DCD |. 75 16 jnz short 00412DE5
通过对这段的代码2次动态跟踪,发现当00412DC6处的call 00412C9C返回0时,这个函数返回-1,于是,跟入00412C9C这个函数
00412C9C /$ 55 push ebp
00412C9D |. 8BEC mov ebp, esp
00412C9F |. 81EC 0C030000 sub esp, 30C
00412CA5 |. 68 FF000000 push 0FF
00412CAA |. 8D85 00FFFFFF lea eax, dword ptr [ebp-100]
00412CB0 |. 50 push eax
00412CB1 |. FF75 08 push dword ptr [ebp+8]
00412CB4 |. E8 17030000 call 00412FD0
00412CB9 |. 8D85 00FEFFFF lea eax, dword ptr [ebp-200]
00412CBF |. 50 push eax ; /Arg1
00412CC0 |. E8 2B0A0000 call 004136F0 ; \Insight3.004136F0
00412CC5 |. FF75 10 push dword ptr [ebp+10] ; /Arg1
00412CC8 |. E8 AB090000 call 00413678 ; \Insight3.00413678
00412CCD |. 85C0 test eax, eax
00412CCF |. 75 07 jnz short 00412CD8
00412CD1 |. 33C0 xor eax, eax
00412CD3 |. E9 CF000000 jmp 00412DA7
00412CD8 |> 837D 0C 00 cmp dword ptr [ebp+C], 0
00412CDC |. 75 39 jnz short 00412D17
00412CDE |. 8D85 FCFCFFFF lea eax, dword ptr [ebp-304]
00412CE4 |. 50 push eax ; /TempName
00412CE5 |. 6A 00 push 0 ; |Unique = 0
00412CE7 |. FF75 08 push dword ptr [ebp+8] ; |Prefix
00412CEA |. FF75 10 push dword ptr [ebp+10] ; |Path
00412CED |. FF15 C4C25200 call dword ptr [<&KERNEL32.GetTempFileNameA>] ; \GetTempFileNameA
00412CF3 |. 85C0 test eax, eax
00412CF5 |. 75 07 jnz short 00412CFE
通过对这段代码的2次动态跟踪,发现对GetTempFileNameA的调用失败,会造成这个函数返回0
0006F108 005C8060 |Path = "C:\DOCUME~1\DevUser\LOCALS~1\Temp\"
0006F10C 005BCEBC |Prefix = "TFXXXXXX"
0006F110 00000000 |Unique = 0
0006F114 0006F120 \TempName = 0006F120
这时,相关参数如上,即source insight要在C:\DOCUME~1\DevUser\LOCALS~1\Temp\目录创建以TFX开头的临时文件,如果创建失败,返回0。
显然,创建失败了。到这个目录里看看,dir TFX*,一堆的文件,好,del TFX*,重新加载,运行,OKey了。
总结:当C:\DOCUME~1\DevUser\LOCALS~1\Temp\目录创建以TFX开头的临时文件过多,造成无法在这个目录创建以TFX开头的临时文件,会造成
source insight的崩溃,因为source insight对创建得到的临时文件句柄的有效性未做任何检测。
下午正逆向的带劲,要查windows内核某函数参数,向平常一样打开source insight, 令人喷饭的是
si竟然异常了,这软件也能异常。还以来中了什么东西被人插了,看看它的进程模块,无异常,难道
是被无模块的插了?本人行走江湖有些年头了,向来小心,这种可能性不大。算了,换版本。
于是google,迅雷一起上,soso地下来3,4个版本,一痛装啊,再令人喷饭的是,全都异常。
再google之,有人说需要把什么注册表的什么地方、我的文档里的source insight目录删除,好,我删。
再开,还是异常。受不了,直接上OD。
OD加载之,异常发生此外:
00412993 /$ 55 push ebp
00412994 |. 8BEC mov ebp, esp
00412996 |. 51 push ecx
00412997 |. FF75 08 push dword ptr [ebp+8] ; /Arg1
0041299A |. E8 DCFAFFFF call 0041247B ; \Insight3.0041247B
0041299F |. 8945 FC mov dword ptr [ebp-4], eax
004129A2 |. 8B45 0C mov eax, dword ptr [ebp+C]
004129A5 |. 83E0 01 and eax, 1
004129A8 |. C1E0 08 shl eax, 8
004129AB |. 8B4D FC mov ecx, dword ptr [ebp-4]
004129AE 8B09 mov ecx, dword ptr [ecx] ;这里异常了
异常发生在最后一句指令处,即mov ecx, dword ptr [ecx],此时ecx为0,看看,ecx就是call 0041247B
的返回值,在这个call处下断,ctrl+F2重新加载,第一次断下,[ebp+8]为0,call 0041247B返回某个地址,正常。
第二次断下,[ebp+8]为-1,call 0041247B返回0,执行到004129AE处,当然异常了。
看来,原因出在[ebp+8]这个参数上,第二次断下的时候,看栈:
调用堆栈: 主线程
地址 堆栈 函数过程 / 参数 调用来自 结构
0006F550 00446393 Insight3.00412993 Insight3.0044638E 0006F86C
0006F554 00000001 Arg1 = 00000001
0006F558 00000000 Arg2 = 00000000
0006F870 00445FE6 Insight3.00446132 Insight3.00445FE1 0006F86C
0006F874 00000000 Arg1 = 00000000
0006F878 0006FAA8 Arg2 = 0006FAA8
0006F87C 00000001 Arg3 = 00000001
0006F880 00000001 Arg4 = 00000001
0006F884 0000000A Arg5 = 0000000A
0006F888 0006FED0 Arg6 = 0006FED0
0006FED8 0044070A Insight3.00445DAE Insight3.00440705 0006FED4
0006FEDC 00091F0E Arg1 = 00091F0E
0006FEE0 0000000A Arg2 = 0000000A
0006FEE4 0006FF2C Arg3 = 0006FF2C
0006FF38 005214AB Insight3.004405A8 Insight3.<模块入口点>+0C9 0006FF34
0006FF3C 00400000 Arg1 = 00400000
0006FF40 00000000 Arg2 = 00000000
0006FF44 00091F0E Arg3 = 00091F0E
0006FF48 0000000A Arg4 = 0000000A
调用是从00446132发起来,返回地址是00446393,跟随到这个返回地址看看:
0044636E |> \6A 00 push 0 ; /Arg4 = 00000000
00446370 |. 68 60805C00 push 005C8060 ; |Arg3 = 005C8060 ASCII "C:\DOCUME~1\DevUser\LOCALS~1\Temp\"
00446375 |. 6A 00 push 0 ; |Arg2 = 00000000
00446377 |. 68 BCCE5B00 push 005BCEBC ; |Arg1 = 005BCEBC ASCII "TFXXXXXX"
0044637C |. E8 2ACAFCFF call 00412DAB ; \Insight3.00412DAB
00446381 |. A3 D8955C00 mov dword ptr [5C95D8], eax
00446386 |. 6A 00 push 0
00446388 |. FF35 D8955C00 push dword ptr [5C95D8]
0044638E |. E8 00C6FCFF call 00412993 <----出问题的call
00446393 |. 833D D8955C00>cmp dword ptr [5C95D8], -1 <----返回到这里
可以看出,出问题的call的参数,就是5C95D8的内容,也就是call 00412DAB的返回值,也就是说当
call 00412DAB 返回-1时,就会出现当前的这个异常,于是在call 00412DAB处下断,经过数次粗跟,
可以断定当第二次断在这里时,这个call返回-1,于是,重新加载,第二次断在这里时,F7跟入
00412DAB /$ 55 push ebp
00412DAC |. 8BEC mov ebp, esp
00412DAE |. 81EC 00010000 sub esp, 100
00412DB4 |. 56 push esi
00412DB5 |. 57 push edi
00412DB6 |. 8D85 00FFFFFF lea eax, dword ptr [ebp-100]
00412DBC |. 50 push eax ; /Arg4
00412DBD |. FF75 10 push dword ptr [ebp+10] ; |Arg3
00412DC0 |. FF75 0C push dword ptr [ebp+C] ; |Arg2
00412DC3 |. FF75 08 push dword ptr [ebp+8] ; |Arg1
00412DC6 |. E8 D1FEFFFF call 00412C9C ; \Insight3.00412C9C
00412DCB |. 85C0 test eax, eax
00412DCD |. 75 16 jnz short 00412DE5
通过对这段的代码2次动态跟踪,发现当00412DC6处的call 00412C9C返回0时,这个函数返回-1,于是,跟入00412C9C这个函数
00412C9C /$ 55 push ebp
00412C9D |. 8BEC mov ebp, esp
00412C9F |. 81EC 0C030000 sub esp, 30C
00412CA5 |. 68 FF000000 push 0FF
00412CAA |. 8D85 00FFFFFF lea eax, dword ptr [ebp-100]
00412CB0 |. 50 push eax
00412CB1 |. FF75 08 push dword ptr [ebp+8]
00412CB4 |. E8 17030000 call 00412FD0
00412CB9 |. 8D85 00FEFFFF lea eax, dword ptr [ebp-200]
00412CBF |. 50 push eax ; /Arg1
00412CC0 |. E8 2B0A0000 call 004136F0 ; \Insight3.004136F0
00412CC5 |. FF75 10 push dword ptr [ebp+10] ; /Arg1
00412CC8 |. E8 AB090000 call 00413678 ; \Insight3.00413678
00412CCD |. 85C0 test eax, eax
00412CCF |. 75 07 jnz short 00412CD8
00412CD1 |. 33C0 xor eax, eax
00412CD3 |. E9 CF000000 jmp 00412DA7
00412CD8 |> 837D 0C 00 cmp dword ptr [ebp+C], 0
00412CDC |. 75 39 jnz short 00412D17
00412CDE |. 8D85 FCFCFFFF lea eax, dword ptr [ebp-304]
00412CE4 |. 50 push eax ; /TempName
00412CE5 |. 6A 00 push 0 ; |Unique = 0
00412CE7 |. FF75 08 push dword ptr [ebp+8] ; |Prefix
00412CEA |. FF75 10 push dword ptr [ebp+10] ; |Path
00412CED |. FF15 C4C25200 call dword ptr [<&KERNEL32.GetTempFileNameA>] ; \GetTempFileNameA
00412CF3 |. 85C0 test eax, eax
00412CF5 |. 75 07 jnz short 00412CFE
通过对这段代码的2次动态跟踪,发现对GetTempFileNameA的调用失败,会造成这个函数返回0
0006F108 005C8060 |Path = "C:\DOCUME~1\DevUser\LOCALS~1\Temp\"
0006F10C 005BCEBC |Prefix = "TFXXXXXX"
0006F110 00000000 |Unique = 0
0006F114 0006F120 \TempName = 0006F120
这时,相关参数如上,即source insight要在C:\DOCUME~1\DevUser\LOCALS~1\Temp\目录创建以TFX开头的临时文件,如果创建失败,返回0。
显然,创建失败了。到这个目录里看看,dir TFX*,一堆的文件,好,del TFX*,重新加载,运行,OKey了。
总结:当C:\DOCUME~1\DevUser\LOCALS~1\Temp\目录创建以TFX开头的临时文件过多,造成无法在这个目录创建以TFX开头的临时文件,会造成
source insight的崩溃,因为source insight对创建得到的临时文件句柄的有效性未做任何检测。
解决办法:删除C:\DOCUME~1\DevUser\LOCALS~1\Temp\目录下以TFX开头的所有临时文件
亲测有效:可能有的机器中文件名和上文中不同,例如本机(win7)的对应文件:C:\Documents and Settings\Default User\Local Settings\Temp,或者该文件夹是空的,直接删除该文件夹,还有win7可能需要先获取管理员权限才能打开对应文件夹。