簡體   English   中英

如何在服務和用戶進程之間共享內存?

[英]How to share memory between services and user processes?

我有一組Win32應用程序,它們使用CreateFileMapping()MapViewOfFile()創建的共享內存段共享信息。 其中一個應用是系統服務; 其余部分由登錄用戶啟動。 在Windows XP上,沒有問題。 我們將我們的片段命名為“Global \\ Something”,一切都很好。

Vista中的額外安全性(以及假設的Windows 7)似乎阻止了這種架構的運行。 不允許普通用戶在全局命名空間中創建(Win32錯誤5)對象。 MSDN表明,如果該帳戶具有“創建全局”權限,那么一切都應該很好,但實際上似乎並非如此。 此外,Vista的“完整性”功能似乎可以防止“低完整性”用戶進程訪問“高完整性”服務創建的共享內存對象。 看起來我應該能夠通過一些神奇的SetSecurityDescriptorSacl()咒語解決這個問題,但是我很難學會說出來。

所以問題是: 在服務和普通用戶進程之間使用共享內存段的正確方法什么?

為了取代“只是關閉UAC”的簡單回答,我們處於一個相當封閉的環境中,這是不可能的。

編輯:服務和用戶進程都需要對段進行讀/寫訪問。

最簡單的方法是讓您的服務創建共享內存並在CreateFileMapping中指定DACL,以授予常規用戶對共享內存的讀訪問權限。

普通用戶沒有create global特權,但服務可以擁有此特權。 如果您必須讓您的用戶創建共享內存然后讓服務探測它,您可以使用IPC方案,其中您的用戶代碼向包含文件映射句柄的服務發送消息,然后該服務將調用DuplicateHandle以獲取參考它。 這將要求您的服務使用調試權限運行。

創建DACL的最簡單方法是使用ConvertStringSecurityDescriptorToSecurityDescriptor,它采用稱為SDDL的格式的字符串來指定ACL。

編寫安全代碼包含有關使用SDDL創建DACL的精彩章節。

// Error handling removed for brevity
SECURITY_ATTRIBUTES attributes;
ZeroMemory(&attributes, sizeof(attributes));
attributes.nLength = sizeof(attributes);
ConvertStringSecurityDescriptorToSecurityDescriptor(
         L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)",
         SDDL_REVISION_1,
         &attributes.lpSecurityDescriptor,
         NULL);

CreateFileMapping(INVALID_HANDLE_VALUE, &attributes,
              PAGE_READWRITE, sizeHigh, sizeLow, L"Global\\MyObject");

LocalFree(attributes.lpSecurityDescriptor);

“D:P(A; OICI; GA ;;; SY)(A; OICI; GA ;;; BA)(A; OICI; GR ;;; IU)”指定DACL。 D:P表示這是一個DACL(而不是SACL ......你很少使用SACL),后面是幾個控制誰可以訪問的ACE字符串。 每一個都是A(允許)並允許對象並包含繼承(OICI)。 第一個授予系統(SY)和管理員(BA,內置管理員)的所有訪問權限(GA - 全部授予)。 最后一次授予讀取(GR)到交互式用戶(IU),這些用戶實際登錄到會話。

完成此操作后,普通用戶應該能夠調用OpenFileMapping來獲取共享映射的句柄,並能夠將其映射到其進程中。 由於普通用戶對該對象擁有有限的權限,因此他們必須確保打開它並將其映射為僅供讀取訪問。

如果用戶需要write-acccess,則用GWGR替換GR。 請注意,這不安全 - 有限的用戶可以在您的服務正在讀取並嘗試解析信息時修改共享內存,從而導致服務崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM