我们将.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.
最佳答案 关于类似问题
here的讨论.最有趣的部分是:
Mscorwks.dll is just the messenger. It is telling you that it detected a loaderlock. It is your code that caused it.