将 C++CLI 包装器从 .NET 4.0 迁移到 4.5 会导致 Windows Server 2012 R2 出现 winsock 错误
Migrating C++CLI wrapper from .NET 4.0 to 4.5 cause winsock error on Windows Server 2012 R2
我已经为我们使用的通信中间件构建了一个 C++ CLI 包装器。
包装器已经在 .NET 4.5 中并且在 Windows 7 和 Windows Server 2008 R2 中工作正常。但在 Windows Server 2012 R2 中它崩溃并在 mswsock.dll
中出现 "Access violation" 错误
有趣的是,如果我构建包装器并测试应用程序以面向 .NET 4.0,它就可以工作。但是当我将它们重新定位到 .NET 4 时。5.x 它会触发异常。
我尝试调查安全性、强命名、热修复 .NET,但没有用。
令我困扰的是它在 .NET 4.0 中的 Server 2012 R2 上运行,但在 4.5.x 上运行。并且显然是在本机代码访问 winsock API 时发生了访问冲突。
有没有人遇到过同样的问题,或者类似的 Server 2012 .NET 4.0 vs 4.5.x wiredness?
当 运行 .NET 4.5 应用程序在 Server 2012 中激活时,是否有任何安全机制对 4.0 应用程序不活动。具体关于 CLI 模块?
技术:本机代码是使用 VS2010 编译的,因此包装器是使用 VS2012 中的编译器编译的。编辑 C++ CLI 项目文件以设置所需的框架目标。测试应用程序是用 C# 编写的。
所以我们最终找到了这个bug。第三方通信中间件在 64 位版本中存在错误。一个指针被转换为 long 并再次返回,导致 64 位寻址错误。
为什么这个是在使用.NET 4.5 时首先引起的,我不知道。我似乎使用 .NET 4.5 的 Server 2012 R2 总是在 32 位地址范围之外分配内存。至少在我们的试验台上。它总是出现此访问冲突错误。
Server 2012 R2 with .NET 4.5 always allocates memory outside a 32-bit address scope
是的,当您在 EXE 文件上使用 Dumpbin.exe /headers 时,这是非常明显的。我将 post 它显示的输出的相关部分:
4.00 operating system version
0.00 image version
6.00 subsystem version // <== here
0 Win32 version
8000 size of image
200 size of headers
0 checksum
3 subsystem (Windows CUI)
8560 DLL characteristics
High Entropy Virtual Addresses // <=== here
Dynamic base
NX compatible
No structured exception handler
Terminal Server Aware
子系统版本是 .NET 4.5 编译的可执行文件中的第一个重要变化。版本 6.00 是 Vista 的版本,之前设置为 4.00。一个副作用是该程序无法再在 XP 和 Server 2003 上 运行。版本 6 是对 Windows 内核的最后一次大修。巨大的改变,让 Vista 如此不受欢迎的那种。
而High Entropy Virtual Addresses
特征是重要的变化。那就是导致您的本机代码中的错误被触发的原因。此选项与 ASLR(地址 Space 布局随机化)有关,这是一种针对恶意软件的反制措施。通过随机化地址 space 布局,恶意软件很难攻击代码,它不再依赖此类代码存在于已知地址。
原始版本的 ASLR,由 Dynamic base
选项启用,通过选择 256 个可能的地址偏移之一来随机化地址。在启动时选择。在 64 位进程中有更好的选择,它有更大的地址 space。 /HIGHENTROPYVA 链接器选项启用它。但副作用是地址不再可能位于较低的 4 GB 地址 space。从而触发铸造错误。
.NET 4.5 编译器在您针对 4.5 及更高版本时打开这些,4.0 编译器没有。不必再支持 XP 和 Server 2003(它们不能 运行 4.5)启用这些选项。
我已经为我们使用的通信中间件构建了一个 C++ CLI 包装器。 包装器已经在 .NET 4.5 中并且在 Windows 7 和 Windows Server 2008 R2 中工作正常。但在 Windows Server 2012 R2 中它崩溃并在 mswsock.dll
中出现 "Access violation" 错误有趣的是,如果我构建包装器并测试应用程序以面向 .NET 4.0,它就可以工作。但是当我将它们重新定位到 .NET 4 时。5.x 它会触发异常。
我尝试调查安全性、强命名、热修复 .NET,但没有用。
令我困扰的是它在 .NET 4.0 中的 Server 2012 R2 上运行,但在 4.5.x 上运行。并且显然是在本机代码访问 winsock API 时发生了访问冲突。
有没有人遇到过同样的问题,或者类似的 Server 2012 .NET 4.0 vs 4.5.x wiredness?
当 运行 .NET 4.5 应用程序在 Server 2012 中激活时,是否有任何安全机制对 4.0 应用程序不活动。具体关于 CLI 模块?
技术:本机代码是使用 VS2010 编译的,因此包装器是使用 VS2012 中的编译器编译的。编辑 C++ CLI 项目文件以设置所需的框架目标。测试应用程序是用 C# 编写的。
所以我们最终找到了这个bug。第三方通信中间件在 64 位版本中存在错误。一个指针被转换为 long 并再次返回,导致 64 位寻址错误。
为什么这个是在使用.NET 4.5 时首先引起的,我不知道。我似乎使用 .NET 4.5 的 Server 2012 R2 总是在 32 位地址范围之外分配内存。至少在我们的试验台上。它总是出现此访问冲突错误。
Server 2012 R2 with .NET 4.5 always allocates memory outside a 32-bit address scope
是的,当您在 EXE 文件上使用 Dumpbin.exe /headers 时,这是非常明显的。我将 post 它显示的输出的相关部分:
4.00 operating system version
0.00 image version
6.00 subsystem version // <== here
0 Win32 version
8000 size of image
200 size of headers
0 checksum
3 subsystem (Windows CUI)
8560 DLL characteristics
High Entropy Virtual Addresses // <=== here
Dynamic base
NX compatible
No structured exception handler
Terminal Server Aware
子系统版本是 .NET 4.5 编译的可执行文件中的第一个重要变化。版本 6.00 是 Vista 的版本,之前设置为 4.00。一个副作用是该程序无法再在 XP 和 Server 2003 上 运行。版本 6 是对 Windows 内核的最后一次大修。巨大的改变,让 Vista 如此不受欢迎的那种。
而High Entropy Virtual Addresses
特征是重要的变化。那就是导致您的本机代码中的错误被触发的原因。此选项与 ASLR(地址 Space 布局随机化)有关,这是一种针对恶意软件的反制措施。通过随机化地址 space 布局,恶意软件很难攻击代码,它不再依赖此类代码存在于已知地址。
原始版本的 ASLR,由 Dynamic base
选项启用,通过选择 256 个可能的地址偏移之一来随机化地址。在启动时选择。在 64 位进程中有更好的选择,它有更大的地址 space。 /HIGHENTROPYVA 链接器选项启用它。但副作用是地址不再可能位于较低的 4 GB 地址 space。从而触发铸造错误。
.NET 4.5 编译器在您针对 4.5 及更高版本时打开这些,4.0 编译器没有。不必再支持 XP 和 Server 2003(它们不能 运行 4.5)启用这些选项。