.NET 2.0应用程序攻击时-安装.NET Runtime之后调试怪异现象

WeirdLogitechRemotingBug

I've been developing using the Logitech io2 Pen SDK recently and also, coincidentally installed .NET 2.0 and Visual Studio 2005 around the same time.

我一直在使用的开发罗技IO2笔SDK最近也不约而同安装了.NET 2.0和Visual Studio 2005在同一时间。

I got this error a few days ago upon docking the pen: "Ticks must be between DateTime.MinValue and DateTime.MaxValue" and noticed that remoting was involved in the stack dump:

几天前,我在停放笔时遇到了这个错误:“ Ticks必须在DateTime.MinValue和DateTime.MaxValue之间”,并注意到堆栈转储中涉及远程处理:

System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Logitech.Pen.Device.IPen.get_LastSynchronizationTime()
   at Logitech.Pen.TrayIcon.PenBalloon.DoRefresh()

System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&msgData,Int32类型) 在Logitech.Pen.Device.IPen.get_LastSynchronizationTime() 在Logitech.Pen.TrayIcon.PenBalloon.DoRefresh()

So, two assemblies were chatting each other up via remoting and something went wrong. Logitech has a number of EXEs that all work together to make io2 Pen Services available in multiple contexts. Don't worry, they don't all run at the same time; they come and go as needed.

因此,两个程序集通过远程相互交谈,出现了问题。 罗技(Logitech)有许多EXE,这些EXE可以一起工作以使io2 Pen Services在多种情况下可用。 不用担心,它们不会同时运行。 他们根据需要来来去去。

I knew that Logitech used .NET 1.1 for their development and I knew that on systems that have both .NET 2.0 and .NET 1.1 that 1.1 EXEs would get the 1.1 CLR loaded by default. However, the only thing that changed was the installation of 2.0.

我知道Logitech使用.NET 1.1进行开发,并且我知道在同时具有.NET 2.0和.NET 1.1的系统上,默认情况下1.1 EXE将加载1.1 CLR。 但是,唯一改变的是2.0的安装。

Which of these was running .NET 2.0? Using Sysinternal's glorious ProcExp that can highlight processes that contain a .NET runtime as well as show exactly what DLLs are loaded in a process's memory space. Looks like Pen.LplsHost.exe gets 2.0 loaded, while EVERY other .EXE gets 1.1.

其中哪个正在运行.NET 2.0? 使用Sysinternal出色的ProcExp可以突出显示包含.NET运行时的进程,并准确显示进程的内存空间中加载了哪些DLL。 看起来Pen.LplsHost.exe获得2.0加载,而其他所有.EXE获得1.1。

That's weird, and it would make sense that if a .NET 1.1 application remoted into a .NET 2.0 application that something odd might happened (Honest question: Doesn't it?).

这很奇怪,并且有道理,如果.NET 1.1应用程序远程到.NET 2.0应用程序中,可能会发生一些奇怪的事情(老实的问题:不是吗? )。

When you install .NET 2.0, does it changed any 1.1 DLLs? Yes and no. The system-wide CLR loader, mscoree.dll changes when you install a new version of the .NET Framework. It's always the last version. This is necessary because the loader ultimately makes the decision of which CLR to load into that process. So, mscoree was updated to make the 1.0, 1.1 or 2.0 decision. 

安装.NET 2.0时,它是否更改了1.1个DLL? 是的,没有。 当您安装新版本的.NET Framework时,系统级CLR加载程序mscoree.dll会更改。 它始终是最新版本。 这是必需的,因为加载程序最终决定将哪个CLR加载到该进程中。 因此,mscoree已更新为做出1.0、1.1或2.0决策。

Now, the real question is: What is it about Pen.LplsHost.exe that causes it to load .NET 2.0?

现在,真正的问题是:导致Pen.LplsHost.exe加载.NET 2.0的问题是什么?

Here's why! It's NOT a .NET application! Reflector reminds me that it's an unmanaged C++ application. It does load the CLR though, so it's likely a CLR Host that does something like this to load the CLR:

这就是为什么! 它不是.NET应用程序! Reflector提醒我这是一个不受管理的C ++应用程序。 它确实加载了CLR,因此可能是CLR主机执行了如下操作来加载CLR:

LPWSTR pszFlavor = L"wks";
ICorRuntimeHost *pHost = NULL;
hr = CorBindToRuntimeEx(
                      //version
                      null,      
                      // svr or wks                       
                      pszFlavor,   
                      //domain-neutral"ness" and gc settings
                      STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST |       
                      STARTUP_CONCURRENT_GC,
                      CLSID_CorRuntimeHost,
                      IID_ICorRuntimeHost,
                      (void **)&pHost);

LPWSTR pszFlavor = L“ wks”; ICorRuntimeHost * pHost = NULL; hr = CorBindToRuntimeEx( //版空值, // svr或wks pszFlavor, //与网域无关的“ ness”和gc设置STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST | STARTUP_CONCURRENT_GC, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void **)&pHost);

However, if you don't pass in a value for version, MSDN says:

但是,如果您不传递版本值,则MSDN会说:

"If the caller specifies null for pwszVersion, the latest version of the common language runtime is loaded. Passing null gives the host no control over which version of the runtime is loaded. While this may be appropriate in some scenarios, it is strongly recommended that the host supply a specific version to load."

“如果调用者为pwszVersion指定了null,则将加载最新版本的公共语言运行时。传递null将使主机无法控制要加载的运行时版本。尽管在某些情况下这可能是适当的,但强烈建议您主机提供要加载的特定版本。”

So instead, they should note http://msdn.com/library/en-us/cpgenref/html/grfuncorbindtoruntimeex.asp and try this instead: 

因此,相反,他们应该注意http://msdn.com/library/en-us/cpgenref/html/grfuncorbindtoruntimeex.asp并尝试以下操作:

LPWSTR pszVer = L"v1.1.4322"; // <!---- Oy!LPWSTR pszFlavor = L"wks";
ICorRuntimeHost *pHost = NULL;
hr = CorBindToRuntimeEx(
                      //version
                      pszVer,  // <!---- Oy!                      // svr or wks                       
                      pszFlavor,   
                      //domain-neutral"ness" and gc settings
                      STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST |       
                      STARTUP_CONCURRENT_GC,
                      CLSID_CorRuntimeHost,
                      IID_ICorRuntimeHost,
                      (void **)&pHost);

LPWSTR pszVer = L“ v1.1.4322”; // <!----哦! LPWSTR pszFlavor = L“ wks”; ICorRuntimeHost * pHost = NULL; hr = CorBindToRuntimeEx( //版pszVer,// <!----哦! // svr或wks pszFlavor, //与网域无关的“ ness”和gc设置STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST | STARTUP_CONCURRENT_GC, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void **)&pHost);

Speculation: I'd bet $100 that the devs aren't asking for .NET 1.1 in Pen.LplsHost.exe and they should have if they were following best practices. As I said, you can override it with the .config file, but the RIGHT thing to do (in the short term) is to ask for the version you want.

推测:我敢打赌,开发人员在Pen.LplsHost.exe中不要求使用.NET 1.1,如果他们遵循最佳实践,他们应该拥有100美元的赌注。 如我所说,您可以使用.config文件覆盖它,但是正确的做法(短期内)是要求提供所需的版本。

I'm chatting with Logitech Support about this, so until I update this post everything I've said so far is just my opinion and speculation and in no way means to impugn they or there developers. It's a difficult thing to anticipate these things and to include version-specific information, especially as a CLR Host.

我正在与Logitech支持人员聊天,因此,在更新此文章之前,到目前为止,我所说的一切只是我的见解和推测,绝不影响他们或那里的开发人员。 很难预料到这些并包含特定于版本的信息,尤其是作为CLR主机时,这是一件困难的事情。

Short term fix: You can easily force Pen.LplsHost.exe (or any application for that matter) to load the .NET 1.1 framework by dropping the attached file into C:\Program Files\Logitech\io2Software. I have done this and haven't see any problems since and noted with ProcExp that 1.1 is now correctly loaded in this process's space.

短期修复:您可以通过将附加的文件拖放到C:\ Program Files \ Logitech \ io2Software中,轻松地强制Pen.LplsHost.exe(或与此相关的任何应用程序)加载.NET 1.1框架。 我已经完成了此操作,此后再也未发现任何问题,并通过ProcExp注意到现在该进程的空间已正确加载了1.1。

<configuration>
    <startup>
        <requiredRuntime version="v1.1.4322"  />
    </startup>
</configuration>

<配置> <启动> <requiredRuntime version =“ v1.1.4322” /> </ startup> </ configuration>

File Attachment: Pen.LplsHost.exe.config (118 bytes)

文件附件:Pen.LplsHost.exe.config(118字节)

UPDATE: Matt Davis (see the comments for this post) nailed it. I was mistaken. I spoke to the team at Logitech and it was, in fact, C++ calling a .NET Assembly via COM Interop. This  could be controlled via the RunTimeVersion key for the InproServer32 key for this RCW within the Registry. However, everything in this post up to the CorBindToRuntimeEx conclusion holds, and the .exe.config solution is also workable one. Logitech is exploring ways to make this easier. My question is, what about Explorer.exe and hosting multiple shell extensions each written in different versions of .NET?

更新:马特·戴维斯(Matt Davis)(请参阅这篇文章的评论)钉上了它。 我误解了。 我与Logitech的团队进行了交谈,实际上,这是C ++通过COM Interop调用.NET程序集。 可以通过注册表中此RCW的InproServer32密钥的RunTimeVersion密钥进行控制。 但是,直到CorBindToRuntimeEx结论为止,本文中的所有内容都适用,.exe.config解决方案也是可行的。 罗技(Logitech)正在探索使这一过程变得更容易的方法。 我的问题是,Explorer.exe并托管多个分别以不同版本的.NET编写的shell扩展如何?

翻译自: https://www.hanselman.com/blog/when-net-20-applications-attack-debugging-weirdness-after-installing-the-net-runtime

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值