1

我们正在尝试使用内存映射文件技术在进程之间共享一些信息

但是当我们在我们的一个组件(即 IE 工具栏)中使用它时,当 IE 在保护模式下运行时,它会引发访问冲突异常。

有人可以在这方面帮助我吗?

如果有任何替代方法可以在多个进程中共享内存,通过它IE在保护模式下运行时没有任何问题,也请分享

详细的场景已经在这里解释了 谢谢

4

1 回答 1

2

还没回复???

无论如何我找到了解决方案,我们需要先了解问题。

当 IE 在保护模式下运行时,它实际上会将 IE 进程置于低完整性级别,以避免使用来自 IE 的安全对象。因此,如果在高度完整性进程中(例如从控制台或窗口应用程序)中创建了内核对象(内存映射文件),那么当它处于保护模式时,它不会从 IE 访问。

因此,使这项工作必须从高完整性进程将内核对象标记为低完整性级别,该对象也可以从低完整性级别进程访问,尽管它也会使对象易受攻击。

经过长时间的研究,我发现(here)以下 VC++ 代码将内核对象设置为低完整性级别:

LPCWSTR LOW_INTEGRITY_SDDL_SACL_W = L"S:(ML;;NW;;;LW)";

bool SetObjectToLowIntegrity(HANDLE hObject, SE_OBJECT_TYPE type = SE_KERNEL_OBJECT)    
{
    bool bRet = false;
    DWORD dwErr = ERROR_SUCCESS;
    PSECURITY_DESCRIPTOR pSD = NULL;
    PACL pSacl = NULL;
    BOOL fSaclPresent = FALSE;
    BOOL fSaclDefaulted = FALSE;

      if ( ConvertStringSecurityDescriptorToSecurityDescriptorW (LOW_INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD, NULL ) )
      {
        if ( GetSecurityDescriptorSacl (
               pSD, &fSaclPresent, &pSacl, &fSaclDefaulted ) )
          {
          dwErr = SetSecurityInfo (
                    hObject, type, LABEL_SECURITY_INFORMATION,
                    NULL, NULL, NULL, pSacl );

          bRet = (ERROR_SUCCESS == dwErr);
          }

        LocalFree ( pSD );
        }

      return bRet;
    }

为了使其在 C# 中可用,我将上面的 windows APIs 转换为 C#,如下所示;

    public const int LABEL_SECURITY_INFORMATION = 0x00000010;

    public enum SE_OBJECT_TYPE
        {
            SE_UNKNOWN_OBJECT_TYPE = 0,
            SE_FILE_OBJECT,
            SE_SERVICE,
            SE_PRINTER,
            SE_REGISTRY_KEY,
            SE_LMSHARE,
            SE_KERNEL_OBJECT,
            SE_WINDOW_OBJECT,
            SE_DS_OBJECT,
            SE_DS_OBJECT_ALL,
            SE_PROVIDER_DEFINED_OBJECT,
            SE_WMIGUID_OBJECT,
            SE_REGISTRY_WOW64_32KEY
        }

public static bool SetLowIntegrityLevel(IntPtr hObject)
        {
            bool bResult = false;
            IntPtr pSD = IntPtr.Zero;
            IntPtr pSacl = IntPtr.Zero;
            IntPtr lpbSaclPresent = IntPtr.Zero;
            IntPtr lpbSaclDefaulted = IntPtr.Zero;
            uint securityDescriptorSize = 0;

            if (ConvertStringSecurityDescriptorToSecurityDescriptorW("S:(ML;;NW;;;LW)", 1, ref pSD, ref securityDescriptorSize))
            {
                if (GetSecurityDescriptorSacl(pSD, out lpbSaclPresent, out pSacl, out lpbSaclDefaulted))
                {
                    int result = SetSecurityInfo(hObject, 
                                                  SE_OBJECT_TYPE.SE_KERNEL_OBJECT, 
                                                  LABEL_SECURITY_INFORMATION, 
                                                  IntPtr.Zero, 
                                                  IntPtr.Zero, 
                                                  IntPtr.Zero, 
                                                  pSacl);
                    bResult = (result == 0);
                }
                LocalFree(pSD);
            }

            return bResult;
        }

[DllImport("Advapi32.dll", EntryPoint = "SetSecurityInfo")]
        public static extern int SetSecurityInfo(IntPtr hFileMappingObject,
                                                    SE_OBJECT_TYPE objectType,
                                                    Int32 securityInfo,
                                                    IntPtr psidOwner,
                                                    IntPtr psidGroup,
                                                    IntPtr pDacl,
                                                    IntPtr pSacl);

        [DllImport("advapi32.dll", EntryPoint = "GetSecurityDescriptorSacl")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern Boolean GetSecurityDescriptorSacl(
            IntPtr pSecurityDescriptor,
            out IntPtr lpbSaclPresent,
            out IntPtr pSacl,
            out IntPtr lpbSaclDefaulted);

        [DllImport("advapi32.dll", EntryPoint = "ConvertStringSecurityDescriptorToSecurityDescriptorW")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern Boolean ConvertStringSecurityDescriptorToSecurityDescriptorW(
            [MarshalAs(UnmanagedType.LPWStr)] String strSecurityDescriptor,
            UInt32 sDRevision,
            ref IntPtr securityDescriptor,
            ref UInt32 securityDescriptorSize);

        [DllImport("kernel32.dll", EntryPoint = "LocalFree")]
        public static extern UInt32 LocalFree(IntPtr hMem);
于 2011-02-01T12:15:20.290 回答