我们将.NET运行时托管为Win32程序的一部分,最近它已开始在mscorwks.dll中的特定地址处持续中断。
在指定的地址处,有一个0xCC字节,它是一个INT 3指令,用于触发调试器。
有没有人见过这个?
我无法在dll中看到足够的信息来明确它的位置,功能或来源,但它绝对不在我们的任何库中。
调用堆栈看起来像这样(这是来自Delphi 2007):
:7a04f02a ; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
:7a052fc6 ; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
:7a053e72 ; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
:7a03b970 ; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
:7a00351e ; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
:7a0255e0 ; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
:79e71e6d ; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
:7e42b372 USER32.MoveWindow + 0xd4
:7e4565b7 USER32.GetRawInputDeviceInfoW + 0x5f
:7e42ce7c USER32.SetLayeredWindowAttributes + 0x6a
它失败的地址是0x7A04F029,内存中的反汇编如下:
7A04F020 call $7a14be35
7A04F025 cmp [esi],ebx
7A04F027 jz $7a04f02a
7A04F029 int 3 <-- here's the culprit
7A04F02A mov byte ptr [ebp-$04],$02
7A04F02E lea ecx,[ebp-$00000224]
7A04F034 call $79e82214
很容易摆脱,只需每次用0x90(NOP)修补内存中的字节,但下次启动调试器时,dll当然会重新加载。
我已经半心半意地尝试修补文件本身,但我不确定这也是个好主意。我已经验证了CC字节是dll的一部分,用十六进制编辑器找到了周围的字节模式。
有关如何解决此问题的任何提示?其他人看过这个吗?
正如答案中所提到的,这是一个LoaderLock问题。在Win32中构建的DLL需要为我们的.NET系统公开一些函数,其方式与我们托管.NET运行时的方式无关。该项目包含了几个包含将要公开的函数的单元,但遗憾的是还添加了大量的代码,这些代码在应用程序中很有用,但不适用于此DLL。
将我需要的函数分离出来,将DLL的大小从7MB缩小到大约100KB,并且也摆脱了LoaderLock。
答案 0 :(得分:2)
讨论了类似的问题here。最有趣的部分是:
Mscorwks.dll只是信使。它告诉你它检测到了一个装载机锁。这是你的代码造成的。
答案 1 :(得分:0)
你应该能够获得mscorwks的符号 - 我在这里有几个版本,所以MS symserv在过去一定很有用。
这可能有助于了解发生了什么。
由于您在USER32.dll中有跟踪这一事实,我怀疑您已经配置了一些符号内容,但如果您没有,那么这可能会有所帮助:http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
我自己不使用Delphi,但我猜它会使用dbghelp.dll来做符号/ PDB的东西,因此即使它没有任何明确的UI来帮助它也可以设置使用symserv。