如何以编程方式设置SeCreateGlobalPrivilege?(How can I set SeCreateGlobalPrivilege programmatically?)

编程入门 行业动态 更新时间:2024-10-24 20:19:05
如何以编程方式设置SeCreateGlobalPrivilege?(How can I set SeCreateGlobalPrivilege programmatically?)

我想知道如何以编程方式将SeCreateGlobalPrivilege设置为无session0进程,该进程试图打开带有Global\前缀的MemoryMappedFile ,该进程将用于在2个进程之间共享一些数据,一个与session0一起运行(Windows服务),另一个正在运行通过在用户登录系统时调用CreateProcessAsUser启动的进程。

传递给CreateProcessAsUser函数的访问令牌是从“explorer”进程复制的,其中sessionId与WTSGetActiveConsoleSessionId()的结果相匹配。

我有这个在session0下运行的Owin中间件,它返回由用户进程分配的MemoryMappedFile内容, MemoryMappedFile用户进程持续监视特定的本地文件,该文件映射到用于使用HTTP从外部访问数据的URL。

我不能让Windows服务进程打开MemoryMappedFile,因为它会创建一些任何sesison0进程都不知道的任意位置。

以下是我试图在这种特定情况下使其工作的代码片段。 只有当前面两个进程都使用相同的sessionId运行时,它才有效,无论是否有全局前缀。

public class FileView { private readonly AutoResetEvent _run = new AutoResetEvent(false); private readonly AutoResetEvent _update = new AutoResetEvent(false); private ILog logger = LogManager.GetLogger("weldR"); private bool IsDisposed { get; set; } private byte[] Data { get; set; } private string MapName { get; set; } private string MutexName { get; set; } private MemoryMappedFileSecurity Security { get; set; } public FileView(string url) { if (url.StartsWith("/")) { url = url.Substring(1); } MapName = string.Format("Global\\{0}",String.Concat("pipe://", url)); MutexName = string.Format("Global\\{0}", url.GetHashCode().ToString("x")); Security = new MemoryMappedFileSecurity(); Security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>("everyone", MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow)); Task.Factory.StartNew(Run); } void Run() { while (!IsDisposed) { if(Data != null) { Process process = Process.GetCurrentProcess(); using (new PrivilegeEnabler(process, Privilege.CreateGlobal)) { var mutex = new Mutex(true, MutexName); using (var mmf = MemoryMappedFile.CreateNew(MapName, Data.Length + 8, MemoryMappedFileAccess.ReadWriteExecute, MemoryMappedFileOptions.None, Security, HandleInheritability.Inheritable)) { using (var viewAccessor = mmf.CreateViewAccessor()) { try { var size = Data.Length.Bytes(); viewAccessor.WriteArray(0, size, 0, size.Length); viewAccessor.WriteArray(size.Length + 1, Data, 0, Data.Length); } catch (Exception e) { logger.ErrorFormat(e.ToString()); } } mutex.ReleaseMutex(); _update.Set(); _run.WaitOne(); mutex.WaitOne(); } } } else { _run.WaitOne(); } } } public void Update(byte[] data) { Data = data; _run.Set(); _update.WaitOne(); } public void Dispose() { IsDisposed = true; _run.Set(); _update.Set(); } } private static Action<OwinRequest, OwinResponse> Serve(string path) { return (request, response) => { //var pipename = String.Concat("pipe://", path); // var pipemutex = path.GetHashCode().ToString("x"); var pipename = string.Format("Global\\{0}", String.Concat("pipe://", path)); var pipemutex = string.Format("Global\\{0}", path.GetHashCode().ToString("x")); using (var mmf = MemoryMappedFile.OpenExisting(pipename)) { using (var mutex = Mutex.OpenExisting(pipemutex)) { try { mutex.WaitOne(); using (var accessor = mmf.CreateViewAccessor()) { var offset = 0; var fileLength = new byte[4]; accessor.ReadArray(offset, fileLength, 0, fileLength.Length); offset += fileLength.Length; var size = fileLength.Int32(); var buff = new byte[size]; accessor.ReadArray(offset, buff, 0, buff.Length); var lastWriteTimeUtc = new DateTime(); var etag = string.Concat("\"", lastWriteTimeUtc.Ticks.ToString("x"), "\""); var lastModified = lastWriteTimeUtc.ToString("R"); if ("HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase)) return; //if (CacheHelpers.ReturnNotModified(etag, lastWriteTimeUtc, context)) //{ // mutex.ReleaseMutex(); // return TaskHelpers.Completed(); //} response.AddHeader("ETag", etag); response.AddHeader("Last-Modified", lastModified); response.AddHeader("Content-Type", Mime.MimeTypeFromExtension(path, "text/plain")); response.AddHeader("Content-Length", size.ToString(CultureInfo.InvariantCulture)); response.Body.Write(buff, 0, buff.Length); } } finally { mutex.ReleaseMutex(); } } } }; }

当Window Service进程尝试打开由用户会话进程创建的MemoryMappedFile时,我得到以下异常。

2014-02-27 11:21:18,677 [1704 | 22 | DEBUG] XXX:System.IO.FileNotFoundException:指定されたファイルが见つかりません。场所System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath)场所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName,HandleInheritability inheritability,Int32 desiredAccessRights,Boolean createOrOpen)场所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName,MemoryMappedFileRights desiredAccessRights,HandleInheritability inheritability)场所System.IO.MemoryMappedFiles.MemoryMappedFile .OpenExisting(String mapName)

I would like to know how I can programmatically set SeCreateGlobalPrivilege to a none session0 process that's trying to open a MemoryMappedFile with Global\ prefix, which will be used to share some data between 2 processes, one running with session0 (Windows Service) and other being a process that is started by invoking CreateProcessAsUser upon a user logging on to the system.

The access token passed to CreateProcessAsUser function is duplicated from the process of "explorer" whose sessionId matches the result of WTSGetActiveConsoleSessionId().

I have this Owin middleware which runs under session0 that returns contents of MemoryMappedFile allocated by a user process that continuously monitors a specific local file which is mapped to an url that is used to access the data from outside using HTTP.

I can't have the Windows Service process open the MemoryMappedFile as it would create some arbitrary place that is unknown to that none sesison0 process.

The following is the code snippet that I'm trying to make it work under this specific circumstance. It only works if both of the aforementioned processes run with the same sessionId, regardless of whether there is a Global prefix or not.

public class FileView { private readonly AutoResetEvent _run = new AutoResetEvent(false); private readonly AutoResetEvent _update = new AutoResetEvent(false); private ILog logger = LogManager.GetLogger("weldR"); private bool IsDisposed { get; set; } private byte[] Data { get; set; } private string MapName { get; set; } private string MutexName { get; set; } private MemoryMappedFileSecurity Security { get; set; } public FileView(string url) { if (url.StartsWith("/")) { url = url.Substring(1); } MapName = string.Format("Global\\{0}",String.Concat("pipe://", url)); MutexName = string.Format("Global\\{0}", url.GetHashCode().ToString("x")); Security = new MemoryMappedFileSecurity(); Security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>("everyone", MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow)); Task.Factory.StartNew(Run); } void Run() { while (!IsDisposed) { if(Data != null) { Process process = Process.GetCurrentProcess(); using (new PrivilegeEnabler(process, Privilege.CreateGlobal)) { var mutex = new Mutex(true, MutexName); using (var mmf = MemoryMappedFile.CreateNew(MapName, Data.Length + 8, MemoryMappedFileAccess.ReadWriteExecute, MemoryMappedFileOptions.None, Security, HandleInheritability.Inheritable)) { using (var viewAccessor = mmf.CreateViewAccessor()) { try { var size = Data.Length.Bytes(); viewAccessor.WriteArray(0, size, 0, size.Length); viewAccessor.WriteArray(size.Length + 1, Data, 0, Data.Length); } catch (Exception e) { logger.ErrorFormat(e.ToString()); } } mutex.ReleaseMutex(); _update.Set(); _run.WaitOne(); mutex.WaitOne(); } } } else { _run.WaitOne(); } } } public void Update(byte[] data) { Data = data; _run.Set(); _update.WaitOne(); } public void Dispose() { IsDisposed = true; _run.Set(); _update.Set(); } } private static Action<OwinRequest, OwinResponse> Serve(string path) { return (request, response) => { //var pipename = String.Concat("pipe://", path); // var pipemutex = path.GetHashCode().ToString("x"); var pipename = string.Format("Global\\{0}", String.Concat("pipe://", path)); var pipemutex = string.Format("Global\\{0}", path.GetHashCode().ToString("x")); using (var mmf = MemoryMappedFile.OpenExisting(pipename)) { using (var mutex = Mutex.OpenExisting(pipemutex)) { try { mutex.WaitOne(); using (var accessor = mmf.CreateViewAccessor()) { var offset = 0; var fileLength = new byte[4]; accessor.ReadArray(offset, fileLength, 0, fileLength.Length); offset += fileLength.Length; var size = fileLength.Int32(); var buff = new byte[size]; accessor.ReadArray(offset, buff, 0, buff.Length); var lastWriteTimeUtc = new DateTime(); var etag = string.Concat("\"", lastWriteTimeUtc.Ticks.ToString("x"), "\""); var lastModified = lastWriteTimeUtc.ToString("R"); if ("HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase)) return; //if (CacheHelpers.ReturnNotModified(etag, lastWriteTimeUtc, context)) //{ // mutex.ReleaseMutex(); // return TaskHelpers.Completed(); //} response.AddHeader("ETag", etag); response.AddHeader("Last-Modified", lastModified); response.AddHeader("Content-Type", Mime.MimeTypeFromExtension(path, "text/plain")); response.AddHeader("Content-Length", size.ToString(CultureInfo.InvariantCulture)); response.Body.Write(buff, 0, buff.Length); } } finally { mutex.ReleaseMutex(); } } } }; }

I get the following Exception when the Window Service process try to open the MemoryMappedFile created by user session process.

2014-02-27 11:21:18,677 [1704|22|DEBUG] XXX: System.IO.FileNotFoundException: 指定されたファイルが見つかりません。 場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 場所 System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName, HandleInheritability inheritability, Int32 desiredAccessRights, Boolean createOrOpen) 場所 System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability) 場所 System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName)

最满意答案

这似乎不可能。 我只是猜测,我看到其他博客文章和论坛条目建议打开带有Global \前缀的MemoryMappedFile仅允许具有管理员权限的进程。

This seems impossible. I'm just guessing however, I see other blog posts and forum entries that suggest Opening a MemoryMappedFile with Global\ prefix is only allowed by a process with admin privilege.

更多推荐

本文发布于:2023-08-06 13:49:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1451943.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方式   SeCreateGlobalPrivilege   programmatically   set

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!