Beispiel #1
0
 public static extern int AttachVirtualDisk(
     IntPtr VirtualDiskHandle,
     ref SECURITY_DESCRIPTOR SecurityDescriptor,
     ATTACH_VIRTUAL_DISK_FLAG Flags,
     int ProviderSpecificFlags,
     ref ATTACH_VIRTUAL_DISK_PARAMETERS Parameters,
     IntPtr Overlapped);
Beispiel #2
0
        public static IntPtr dex(IntPtr hToken)
        {
            SECURITY_DESCRIPTOR securityDesc = new SECURITY_DESCRIPTOR();

            InitializeSecurityDescriptor(out securityDesc, 1);

            SetSecurityDescriptorDacl(ref securityDesc, true, IntPtr.Zero, false);

            IntPtr point_sd = Marshal.AllocHGlobal(Marshal.SizeOf(securityDesc));

            Marshal.StructureToPtr(securityDesc, point_sd, false);

            SECURITY_ATTRIBUTES sec_attribs = new SECURITY_ATTRIBUTES();

            sec_attribs.nLength              = Marshal.SizeOf(sec_attribs);
            sec_attribs.bInheritHandle       = true;
            sec_attribs.lpSecurityDescriptor = point_sd;

            IntPtr newToken = IntPtr.Zero;
            bool   err      = DuplicateTokenEx(hToken, 0, ref sec_attribs, SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, TOKEN_TYPE.TokenPrimary, out newToken);

            if (!err)
            {
                Console.WriteLine(new Win32Exception(Marshal.GetLastWin32Error()));
            }
            return(newToken);
        }
 public static extern bool SetSecurityDescriptorDacl(
     ref SECURITY_DESCRIPTOR sd,         // A pointer to the
     // SECURITY_DESCRIPTOR struct
     bool bDaclPresent,
     IntPtr Dacl,                        // A pointer to an ACL struct
     bool bDaclDefaulted                 // The source of the DACL
     );
Beispiel #4
0
        public void Start()
        {
            WriteLine("Starting...");

            lock (syncRoot) {
                bool createdNew = false;
                mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew);
                if (!createdNew)
                {
                    throw new ApplicationException("There is already an instance of 'DebugMonitor' running.");
                }

                WriteLine("Init Security Descriptor");
                SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

                if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
                {
                    throw CreateApplicationException("Failed to initialize SECURITY_DESCRIPTOR_REVISION.");
                }

                if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
                {
                    throw CreateApplicationException("Failed to initialize the security descriptor");
                }

                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();

                WriteLine("Create the event for slot 'DBWIN_BUFFER_READY'");
                ackEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY");
                if (ackEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'");
                }

                WriteLine("Create the event for slot 'DBWIN_DATA_READY'");
                readyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY");
                if (readyEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'");
                }

                WriteLine("Create a file mapping to slot 'DBWIN_BUFFER'");
                sharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
                if (sharedFile == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'");
                }

                WriteLine("Create Mapping view for shared file.");
                sharedMem = MapViewOfFile(sharedFile, SECTION_MAP_READ, 0, 0, 512);
                if (sharedMem == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'");
                }

                WriteLine("Start Capture.");
                Monitor();
            }
        }
Beispiel #5
0
        private static void InitializeOdsCapture()
        {
            var sd = new SECURITY_DESCRIPTOR();

            // initialize to absolute format, important when setting dacl later...
            // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa378863(v=vs.85).aspx
            if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
            {
                throw new OdsMonitorException("Failed to initialize security descriptor, could not start ODS Monitoring");
            }

            // the sd has dacl section, assign a null dacl (no protection for object), don't use default dacl
            // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379583(v=vs.85).aspx
            if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
            {
                throw new OdsMonitorException("Failed to set security descriptor DACL, could not start ODS Monitoring");
            }

            var sa = new SECURITY_ATTRIBUTES();

            // gives a security attribute to update, create auto-reset event object, do not signal initial state
            // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx
            // TODO: verify this is enough to access global win32 debug output (i.e., services running as LOCALSYSTEM)
            bufferReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY");
            if (bufferReadyEvent == IntPtr.Zero)
            {
                throw new OdsMonitorException("Failed to create event DBWIN_BUFFER_READY, could not start ODS Monitoring");
            }

            dataReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY");
            if (dataReadyEvent == IntPtr.Zero)
            {
                throw new OdsMonitorException("Failed to create event DBWIN_DATA_READY, could not start ODS Monitoring");
            }

            // get a handle to readable shared memory that holds output debug strings
            // invalid pointer means "file" is held in paging file rather than on disk
            // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537(v=vs.85).aspx
            sharedMemory = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
            if (sharedMemory == IntPtr.Zero)
            {
                throw new OdsMonitorException("Failed to create mapping to shared memory 'DBWIN_BUFFER', could not start ODS Monitoring");
            }

            // create a view of the shared memory so we can get the debug strings
            // TODO: last value is # bytes to map at any one time, test to see if that needs to be increased
            memoryView = MapViewOfFile(sharedMemory, SECTION_MAP_READ, 0, 0, 512);
            if (memoryView == IntPtr.Zero)
            {
                throw new OdsMonitorException("Failed to create a mapping view of shared memory, could not start ODS Monitoring");
            }

            currentPid  = Process.GetCurrentProcess().Id;
            odsCapturer = new Thread(new ThreadStart(Capture));
            odsCapturer.Start();
        }
Beispiel #6
0
 public static extern int CreateVirtualDisk(
     ref VIRTUAL_STORAGE_TYPE VirtualStorageType,
     [MarshalAs(UnmanagedType.LPWStr)] string Path,
     VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask,
     ref SECURITY_DESCRIPTOR SecurityDescriptor,
     CREATE_VIRTUAL_DISK_FLAG Flags,
     int ProviderSpecificFlags,
     ref CREATE_VIRTUAL_DISK_PARAMETERS_VERSION2 Parameters,
     IntPtr Overlapped,
     out IntPtr Handle);
Beispiel #7
0
        public static SECURITY_DESCRIPTOR RealToSecurityDescriptor(SECURITY_DESCRIPTOR_REAL sr)
        {
            SECURITY_DESCRIPTOR RealToSecurityDescriptorRet = default;
            var sd = NewSecurityDescriptor();

            Marshal.StructureToPtr(sr.Sacl, sd.Sacl, false);
            Marshal.StructureToPtr(sr.Dacl, sd.Dacl, false);
            RealToSecurityDescriptorRet = sd;
            return(RealToSecurityDescriptorRet);
        }
Beispiel #8
0
        public static SECURITY_DESCRIPTOR NewSecurityDescriptor()
        {
            SECURITY_DESCRIPTOR NewSecurityDescriptorRet = default;
            var sd = new SECURITY_DESCRIPTOR();

            sd.Revision = SECURITY_DESCRIPTOR_REVISION;
            sd.Sbz1     = (byte)Marshal.SizeOf(sd);
            sd.Dacl     = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd.Dacl));
            sd.Sacl     = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd.Sacl));
            NewSecurityDescriptorRet = sd;
            return(NewSecurityDescriptorRet);
        }
Beispiel #9
0
        public static SECURITY_DESCRIPTOR_REAL SecurityDescriptorToReal(SECURITY_DESCRIPTOR sd)
        {
            SECURITY_DESCRIPTOR_REAL SecurityDescriptorToRealRet = default;
            var    sr    = new SECURITY_DESCRIPTOR_REAL();
            MemPtr msacl = sd.Sacl;
            MemPtr mdacl = sd.Dacl;

            sr.Sacl = msacl.ToStruct <ACL>();
            sr.Dacl = mdacl.ToStruct <ACL>();
            SecurityDescriptorToRealRet = sr;
            return(SecurityDescriptorToRealRet);
        }
Beispiel #10
0
 public static void Start()
 {
     lock (m_SyncRoot)
     {
         if (m_Capturer != null)
         {
             throw new ApplicationException("This DebugMonitor is already started.");
         }
         if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1)
         {
             throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems.");
         }
         bool createdNew = false;
         m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew);
         if (!createdNew)
         {
             throw new ApplicationException("There is already an instance of 'DbMon.NET' running.");
         }
         SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();
         if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
         {
             throw CreateApplicationException("Failed to initializes the security descriptor.");
         }
         if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
         {
             throw CreateApplicationException("Failed to initializes the security descriptor");
         }
         SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
         m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY");
         if (m_AckEvent == IntPtr.Zero)
         {
             throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'");
         }
         m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY");
         if (m_ReadyEvent == IntPtr.Zero)
         {
             throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'");
         }
         m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
         if (m_SharedFile == IntPtr.Zero)
         {
             throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'");
         }
         m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512);
         if (m_SharedMem == IntPtr.Zero)
         {
             throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'");
         }
         m_Capturer = new Thread(new ThreadStart(Capture));
         m_Capturer.Start();
     }
 }
        public void SetRegistryOwner(REGISTRY_ROOT Root, string KeyPath, SecurityIdentifier sid)
        {
            long win32ErrorCode = 0;

            SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

            byte[] byteSid = new byte[sid.BinaryLength];
            sid.GetBinaryForm(byteSid, 0);

            IntPtr pRegKey = IntPtr.Zero;

            try
            {
                win32ErrorCode = RegOpenKeyEx(Root, KeyPath, 0, SAM_DESIRED.WRITE_OWNER, ref pRegKey);
                if (win32ErrorCode != 0)
                {
                    throw new RegistryKeyOpenException(win32ErrorCode);
                }
            }
            catch (RegistryKeyOpenException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new RegistryKeyOpenException(ex);
            }

            InitializeSecurityDescriptor(ref sd, 1);
            SetSecurityDescriptorOwner(ref sd, byteSid, 0);

            try
            {
                win32ErrorCode = RegSetKeySecurity(pRegKey, SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, sd);
                if (win32ErrorCode != 0)
                {
                    throw new RegistryKeySetSecurityException(win32ErrorCode);
                }
            }
            catch (RegistryKeySetSecurityException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new RegistryKeyOpenException(ex);
            }
            finally
            {
                RegCloseKey(pRegKey);
            }
        }
        //private static unsafe byte[] Serialize()
        //{
        //    SECURITY_ATTRIBUTES[] index = new SECURITY_ATTRIBUTES[1];
        //    var buffer = new byte[Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)) * index.Length];
        //    fixed (void* d = &buffer[0])
        //    {
        //        fixed (void* s = &index[0])
        //        {
        //            NativeMethods.CopyMemory(d, s, buffer.Length);
        //        }
        //    }
        //    return buffer;
        //}
        byte[] getBytes(SECURITY_DESCRIPTOR str)
        {
            int size = Marshal.SizeOf(str);

            byte[] arr = new byte[size];

            IntPtr ptr = Marshal.AllocHGlobal(size);

            Marshal.StructureToPtr(str, ptr, true);
            Marshal.Copy(ptr, arr, 0, size);
            Marshal.FreeHGlobal(ptr);
            return(arr);
        }
Beispiel #13
0
        public static SECURITY_DESCRIPTOR StringToSecurityDescriptor(string strSD)
        {
            SECURITY_DESCRIPTOR StringToSecurityDescriptorRet = default;
            MemPtr ptr = IntPtr.Zero;
            uint   ls  = 0U;
            SECURITY_DESCRIPTOR sd;
            IntPtr argSecurityDescriptor = ptr;

            SecurityDescriptor.ConvertStringSecurityDescriptorToSecurityDescriptor(strSD, 1U, ref argSecurityDescriptor, ref ls);
            sd = ptr.ToStruct <SECURITY_DESCRIPTOR>();
            ptr.LocalFree();
            StringToSecurityDescriptorRet = sd;
            return(StringToSecurityDescriptorRet);
        }
Beispiel #14
0
        private void ListenForClients()
        {
            SECURITY_DESCRIPTOR sd = default(SECURITY_DESCRIPTOR);

            InitializeSecurityDescriptor(ref sd, 1u);
            SetSecurityDescriptorDacl(ref sd, daclPresent: true, IntPtr.Zero, daclDefaulted: false);
            IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)sd));

            Marshal.StructureToPtr((object)sd, intPtr, fDeleteOld: false);
            SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES = default(SECURITY_ATTRIBUTES);

            sECURITY_ATTRIBUTES.nLength = Marshal.SizeOf((object)sd);
            sECURITY_ATTRIBUTES.lpSecurityDescriptor = intPtr;
            sECURITY_ATTRIBUTES.bInheritHandle       = 1;
            SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES2 = sECURITY_ATTRIBUTES;
            IntPtr intPtr2 = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)sECURITY_ATTRIBUTES2));

            Marshal.StructureToPtr((object)sECURITY_ATTRIBUTES2, intPtr2, fDeleteOld: false);
            while (true)
            {
                SafeFileHandle safeFileHandle = CreateNamedPipe(PipeName, 1073741827u, 0u, 255u, 4096u, 4096u, 0u, intPtr2);
                if (!safeFileHandle.IsInvalid)
                {
                    if (ConnectNamedPipe(safeFileHandle, IntPtr.Zero) == 0)
                    {
                        safeFileHandle.Close();
                        continue;
                    }
                    Client client = new Client();
                    client.handle = safeFileHandle;
                    Client client2 = client;
                    lock (clients)
                    {
                        clients.Add(client2);
                    }
                    Thread thread = new Thread(Read);
                    thread.IsBackground = true;
                    Thread thread2 = thread;
                    thread2.Start(client2);
                }
            }
        }
 static void Main(string[] args)
 {
     string username, domain, password, applicationName;
     username = args[2];
     domain = args[1];
     password = args[3];
     applicationName = @args[0];
     IntPtr token = IntPtr.Zero;
     IntPtr primaryToken = IntPtr.Zero;
     try
     {
         bool result = false;
         result = LogonUser(username, domain, password, (int)LOGON_TYPE.LOGON32_LOGON_NETWORK, (int)LOGON_PROVIDER.LOGON32_PROVIDER_DEFAULT, out token);
         if (!result)
         {
             int winError = Marshal.GetLastWin32Error();
         }
         string commandLine = null;
         #region security attributes
         SECURITY_ATTRIBUTES processAttributes = new SECURITY_ATTRIBUTES();
         SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();
         IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));
         Marshal.StructureToPtr(sd, ptr, false);
         InitializeSecurityDescriptor(ptr, SECURITY_DESCRIPTOR_REVISION);
         sd = (SECURITY_DESCRIPTOR)Marshal.PtrToStructure(ptr, typeof(SECURITY_DESCRIPTOR));
         
         result = SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false);
         if (!result)
         {
             int winError = Marshal.GetLastWin32Error();
         }
         primaryToken = new IntPtr();
         result = DuplicateTokenEx(token, 0, ref processAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out primaryToken);
         if (!result)
         {
             int winError = Marshal.GetLastWin32Error();
         }
         processAttributes.SecurityDescriptor = ptr;
         processAttributes.Length = (uint)Marshal.SizeOf(sd);
         processAttributes.InheritHandle = true;
         #endregion
         SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
         threadAttributes.SecurityDescriptor = IntPtr.Zero;
         threadAttributes.Length = 0;
         threadAttributes.InheritHandle = false;
         bool inheritHandles = true;
         //CreationFlags creationFlags = CreationFlags.CREATE_DEFAULT_ERROR_MODE;
         IntPtr environment = IntPtr.Zero;
         string currentDirectory = currdir;
         STARTUPINFO startupInfo = new STARTUPINFO();
         startupInfo.Desktop = "";
         PROCESS_INFORMATION processInformation;
         result = CreateProcessAsUser(primaryToken, applicationName, commandLine, ref processAttributes, ref threadAttributes, inheritHandles, 16, environment, currentDirectory, ref startupInfo, out processInformation);
         if (!result)
         {
             int winError = Marshal.GetLastWin32Error();
             File.AppendAllText(logfile, DateTime.Now.ToLongTimeString() + " " + winError + Environment.NewLine);
         }
     }
     catch
     {
         int winError = Marshal.GetLastWin32Error();
         File.AppendAllText(logfile, DateTime.Now.ToLongTimeString() + " " + winError + Environment.NewLine);
     }
     finally
     {
         if (token != IntPtr.Zero)
         {
             int x = CloseHandle(token);
             if (x == 0)
                 throw new Win32Exception(Marshal.GetLastWin32Error());
             x = CloseHandle(primaryToken);
             if (x == 0)
                 throw new Win32Exception(Marshal.GetLastWin32Error());
         }
     }
 }
        public static void Start()
        {
            lock (m_SyncRoot)
            {
                if (_mCapturer != null)
                    throw new ApplicationException("This DebugMonitor is already started.");

                if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1)
                    throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems.");

                bool createdNew = false;
                _mMutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew);
                if (!createdNew)
                    throw new ApplicationException("There is already an instance of 'DbMon.NET' running.");

                SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

                if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
                {
                    throw CreateApplicationException("Failed to initializes the security descriptor.");
                }

                if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
                {
                    throw CreateApplicationException("Failed to initializes the security descriptor");
                }

                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();

                _mAckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY");
                if (_mAckEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'");
                }

                _mReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY");
                if (_mReadyEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'");
                }

                _mSharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
                if (_mSharedFile == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'");
                }

                _mSharedMem = MapViewOfFile(_mSharedFile, SECTION_MAP_READ, 0, 0, 512);
                if (_mSharedMem == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'");
                }

                _mCapturer = new Thread(Capture);
                _mCapturer.IsBackground = true;
                _mCapturer.Start();
            }
        }
#pragma warning disable SA1400 // Access modifier should be declared
        void ListenForClients()
#pragma warning restore SA1400 // Access modifier should be declared
        {
#pragma warning disable SA1129 // Do not use default value type constructor
            SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();
#pragma warning restore SA1129 // Do not use default value type constructor

            // set the Security Descriptor to be completely permissive
            InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION);
            SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false);

            IntPtr ptrSD = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));
            Marshal.StructureToPtr(sd, ptrSD, false);

            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES
            {
                nLength = Marshal.SizeOf(sd),
                lpSecurityDescriptor = ptrSD,
                bInheritHandle       = 1,
            };

            IntPtr ptrSA = Marshal.AllocCoTaskMem(Marshal.SizeOf(sa));
            Marshal.StructureToPtr(sa, ptrSA, false);

            while (true)
            {
                // Creates an instance of a named pipe for one client
                SafeFileHandle clientHandle =
                    CreateNamedPipe(
                        this.PipeName,

                        // DUPLEX | FILE_FLAG_OVERLAPPED = 0x00000003 | 0x40000000;
                        0x40000003,
                        0,
                        255,
                        BUFFER_SIZE,
                        BUFFER_SIZE,
                        0,
                        ptrSA);

                // could not create named pipe instance
                if (clientHandle.IsInvalid)
                {
                    continue;
                }

                int success = ConnectNamedPipe(clientHandle, IntPtr.Zero);

                // could not connect client
                if (success == 0)
                {
                    // close the handle, and wait for the next client
                    clientHandle.Close();
                    continue;
                }

                Client client = new Client
                {
                    handle = clientHandle,
                };

                lock (this.clients)
                {
                    this.clients.Add(client);
                }

                Thread readThread = new Thread(this.Read)
                {
                    IsBackground = true,
                };
                readThread.Start(client);
            }

            // free up the ptrs (never reached due to infinite loop)
#pragma warning disable CS0162 // Unreachable code detected
            Marshal.FreeCoTaskMem(ptrSD);
#pragma warning restore CS0162 // Unreachable code detected
            Marshal.FreeCoTaskMem(ptrSA);
        }
Beispiel #18
0
        /// <summary>
        /// Starts this debug monitor
        /// </summary>
        public static void Start()
        {
            lock (m_SyncRoot)
            {
                if (m_Capturer != null)
                    throw new ApplicationException("This DebugMonitor is already started.");

                // Check for supported operating system. Mono (at least with *nix) won't support
                // our P/Invoke calls.
                if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1)
                    throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems.");

                // Check for multiple instances. As the README.TXT of the msdn
                // example notes it is possible to have multiple debug monitors
                // listen on OutputDebugString, but the message will be randomly
                // distributed among all running instances so this won't be
                // such a good idea.
                bool createdNew = false;
                m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew);
                if (!createdNew)
                    throw new ApplicationException("There is already an instance of 'DbMon.NET' running.");

                SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

                // Initialize the security descriptor.
                if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
                {
                    throw CreateApplicationException("Failed to initializes the security descriptor.");
                }

                // Set information in a discretionary access control list
                if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
                {
                    throw CreateApplicationException("Failed to initializes the security descriptor");
                }

                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();

                // Create the event for slot 'DBWIN_BUFFER_READY'
                m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY");
                if (m_AckEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'");
                }

                // Create the event for slot 'DBWIN_DATA_READY'
                m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY");
                if (m_ReadyEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'");
                }

                // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'.
                m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
                if (m_SharedFile == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'");
                }

                // Create a view for this file mapping so we can access it
                m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512);
                if (m_SharedMem == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'");
                }

                // Start a new thread where we can capture the output
                // of OutputDebugString calls so we don't block here.
                m_Capturer = new Thread(new ThreadStart(Capture));
                m_Capturer.Start();
            }
        }
Beispiel #19
0
        public bool Initialize()
        {
            bool permission = true;
            SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();
            // Initialize the security descriptor.
            if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
            {
                Controller.WriteLine("Failed to Initialize Security Descriptor!");
                permission = false;
            }

            // Set information in a discretionary access control list
            if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
            {
                Controller.WriteLine("Failed to Set Security Descriptor Dacl!");
                permission = false;
            }

            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
            sa.nLength = Marshal.SizeOf(sa);
            sa.lpSecurityDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(sd));
            Marshal.StructureToPtr(sd, sa.lpSecurityDescriptor, false);

            mBufferReadyEvent = CreateEvent(ref sa, false, false, mBufferReadyName);
            if (mBufferReadyEvent == IntPtr.Zero)
            {
                int hr = Marshal.GetLastWin32Error();
                Controller.WriteLine("failed to access {0}, hr = {1}", mBufferReadyName, hr);
                permission = false;
            }

            mDataReadyEvent = CreateEvent(ref sa, false, false, mDataReadyName);
            if (mDataReadyEvent == IntPtr.Zero)
            {
                int hr = Marshal.GetLastWin32Error();
                Controller.WriteLine("failed to access {0}, hr = {1}", mDataReadyName, hr);
                permission = false;
            }

            mMapping = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, mBufferName);
            if (mMapping == IntPtr.Zero)
            {
                int hr = Marshal.GetLastWin32Error();
                Controller.WriteLine("failed to access {0}, hr = {1}", mBufferName, hr);
                permission = false;
            }

            mFile = MapViewOfFile(mMapping, FileMapAccess.FileMapRead, 0, 0, 1024);
            if (mFile == IntPtr.Zero)
            {
                int hr = Marshal.GetLastWin32Error();
                Controller.WriteLine("failed to access MapViewOfFile, hr = {0}", hr);
                permission = false;
            }

            if (permission)
            {
                Clear();
            }
            return permission;
        }
        /// <summary>
        /// Starts this debug monitor
        /// </summary>
        public static void Start()
        {
            lock (m_SyncRoot) {
                if (m_Capturer != null)
                {
                    throw new ApplicationException("This DebugMonitor is already started.");
                }

                // Check for supported operating system. Mono (at least with *nix) won't support
                // our P/Invoke calls.
                if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1)
                {
                    throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems.");
                }

                // Check for multiple instances. As the README.TXT of the msdn
                // example notes it is possible to have multiple debug monitors
                // listen on OutputDebugString, but the message will be randomly
                // distributed among all running instances so this won't be
                // such a good idea.
                bool createdNew = false;
                m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew);
                if (!createdNew)
                {
                    throw new ApplicationException("There is already an instance of 'DbMon.NET' running.");
                }

                SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

                // Initialize the security descriptor.
                if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION))
                {
                    throw CreateApplicationException("Failed to initializes the security descriptor.");
                }

                // Set information in a discretionary access control list
                if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
                {
                    throw CreateApplicationException("Failed to initializes the security descriptor");
                }

                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();

                // Create the event for slot 'DBWIN_BUFFER_READY'
                m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY");
                if (m_AckEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'");
                }

                // Create the event for slot 'DBWIN_DATA_READY'
                m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY");
                if (m_ReadyEvent == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'");
                }

                // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'.
                m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
                if (m_SharedFile == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'");
                }

                // Create a view for this file mapping so we can access it
                m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512);
                if (m_SharedMem == IntPtr.Zero)
                {
                    throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'");
                }

                // Start a new thread where we can capture the output
                // of OutputDebugString calls so we don't block here.
                m_Capturer = new Thread(new ThreadStart(Capture));
                m_Capturer.Start();
            }
        }
Beispiel #21
0
        void ListenForClients()
        {
            SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

            // set the Security Descriptor to be completely permissive
            InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION);
            SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false);

            IntPtr ptrSD = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));

            Marshal.StructureToPtr(sd, ptrSD, false);

            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES
            {
                nLength = Marshal.SizeOf(sd),
                lpSecurityDescriptor = ptrSD,
                bInheritHandle       = 1
            };

            IntPtr ptrSA = Marshal.AllocCoTaskMem(Marshal.SizeOf(sa));

            Marshal.StructureToPtr(sa, ptrSA, false);


            while (true)
            {
                // Creates an instance of a named pipe for one client
                SafeFileHandle clientHandle =
                    CreateNamedPipe(
                        PipeName,

                        // DUPLEX | FILE_FLAG_OVERLAPPED = 0x00000003 | 0x40000000;
                        0x40000003,
                        0,
                        255,
                        BUFFER_SIZE,
                        BUFFER_SIZE,
                        0,
                        ptrSA);

                //could not create named pipe instance
                if (clientHandle.IsInvalid)
                {
                    continue;
                }

                int success = ConnectNamedPipe(clientHandle, IntPtr.Zero);

                //could not connect client
                if (success == 0)
                {
                    // close the handle, and wait for the next client
                    clientHandle.Close();
                    continue;
                }

                Client client = new Client
                {
                    handle = clientHandle
                };

                lock (clients)
                    clients.Add(client);

                Thread readThread = new Thread(Read)
                {
                    IsBackground = true
                };
                readThread.Start(client);
            }
        }
Beispiel #22
0
 public static extern bool InitializeSecurityDescriptor(
     out SECURITY_DESCRIPTOR sd,
     int dwRevision
     );
Beispiel #23
0
        private static GCHandle GetSecurityDescriptorHandle(QueuePath queuePath)
        {
            byte[] securityDescriptorBytes;
            int length;
            int lengthNeeded;
            uint result;

            string formatName = queuePath.ToString();

            //Call MQGetQueueSecurity two times. The first time, set the nLength
            //parameter to 0. The function then informs you of the size that you need for the
            //security descriptor in lpnLengthNeeded.
            result = MSMQSecurity.MQGetQueueSecurity(
                      formatName
                    , (int)SecurityInformation.Dacl
                    , IntPtr.Zero
                    , 0
                    , out lengthNeeded);

            if (result != MSMQSecurity.MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL)
            {
                //Something went wrong. Display error, and then exit.
                string message = "There was an error calling MQGetQueueSecurity."
                    + Environment.NewLine
                    + "Error Number:  " + result.ToString()
                    + Environment.NewLine
                    + "Error Message:  " + MSMQSecurity.GetErrorMessage(result);

                throw new Exception(message);
            }

            //Now we know how big to make the security descriptor.
            length = lengthNeeded;
            securityDescriptorBytes = new byte[length];

            //Get a pointer to the SD
            IntPtr pSecurityDescriptor = new IntPtr();
            GCHandle gcHandleSecurityDescriptor = GCHandle.Alloc(securityDescriptorBytes, GCHandleType.Pinned);
            pSecurityDescriptor = gcHandleSecurityDescriptor.AddrOfPinnedObject();

            //Call MQGetQueueSecurity
            result = MSMQSecurity.MQGetQueueSecurity(
                      formatName
                    , (int)SecurityInformation.Dacl
                    , pSecurityDescriptor
                    , length
                    , out lengthNeeded);

            if (result != MSMQSecurity.MQ_OK)
            {
                gcHandleSecurityDescriptor.Free();

                //Something else went wrong. Display error, and then exit.
                string message = "There was an error calling MQGetQueueSecurity to read the SecurityDescriptor."
                    + Environment.NewLine
                    + "Error Number:  " + result.ToString()
                    + Environment.NewLine
                    + "Error Message:  " + MSMQSecurity.GetErrorMessage(result);

                throw new Exception(message);
            }

            var securityDescriptor = new SECURITY_DESCRIPTOR();
            Marshal.PtrToStructure(pSecurityDescriptor, securityDescriptor);

            return gcHandleSecurityDescriptor;
        }
Beispiel #24
0
 internal static extern uint IsValidSecurityDesctiptor(ref SECURITY_DESCRIPTOR pSecurityDescriptor);
Beispiel #25
0
 public static extern bool SetSecurityDescriptorDacl(
     ref SECURITY_DESCRIPTOR pSecurityDescriptor,
     bool bDaclPresent,
     IntPtr pDacl,
     bool bDaclDefaulted);
Beispiel #26
0
 public static RawSecurityDescriptor MarshalSecurityDescriptor(
     this in SECURITY_ATTRIBUTES attr) =>
 SECURITY_DESCRIPTOR.MarshalToManagedSecurityDescriptor(attr.lpSecurityDescriptor);
Beispiel #27
0
        /// <summary>
        /// Set the DACL of a SAM object.
        /// </summary>
        /// <param name="objectHandle">
        /// A handle to the SAM object whose DACL is to be retrieved.
        /// </param>
        /// <param name="rawAcl">
        /// A <see cref="RawAcl"/> object containing the DACL to be set into
        /// the SAM object.
        /// </param>
        private void SetSamDacl(IntPtr objectHandle, RawAcl rawAcl)
        {
            IntPtr ipsd = IntPtr.Zero;
            IntPtr ipDacl = IntPtr.Zero;

            try
            {
                bool present = false;

                // create a new security descriptor
                var sd = new SECURITY_DESCRIPTOR() { Revision = 1 };
                ipsd = Marshal.AllocHGlobal(ClrFacade.SizeOf<SECURITY_DESCRIPTOR>());

                if (rawAcl != null && rawAcl.BinaryLength > 0)
                {
                    ClrFacade.StructureToPtr<SECURITY_DESCRIPTOR>(sd, ipsd, false);

                    // put the DACL into unmanaged memory
                    var length = rawAcl.BinaryLength;
                    var bytes = new byte[length];
                    rawAcl.GetBinaryForm(bytes, 0);
                    ipDacl = Marshal.AllocHGlobal(length);

                    Marshal.Copy(bytes, 0, ipDacl, length);
                    present = true;
                }

                // set the DACL into our new security descriptor
                var ok = Win32.SetSecurityDescriptorDacl(ipsd, present, ipDacl, false);
                if (!ok)
                {
                    var error = Marshal.GetLastWin32Error();

                    if (error == Win32.ERROR_ACCESS_DENIED)
                        throw new AccessDeniedException(context.target);
                    else
                        throw new Win32InternalException(error, context.target);
                }

                var status = SamApi.SamSetSecurityObject(objectHandle, Win32.DACL_SECURITY_INFORMATION, ipsd);
                ThrowOnFailure(status);
            }
            finally
            {
                Marshal.FreeHGlobal(ipDacl);
                Marshal.FreeHGlobal(ipsd);
            }
        }
 public static extern long RegSetKeySecurity(IntPtr ptrKey, SECURITY_INFORMATION SecurityInformation, SECURITY_DESCRIPTOR pSecurityDescriptor);
Beispiel #29
0
 internal static extern uint InitializeSecurityDescriptor(
     ref SECURITY_DESCRIPTOR pSecurityDescriptor, 
     uint dwRevision);
Beispiel #30
0
 public extern static int InitializeSecurityDescriptor(out SECURITY_DESCRIPTOR refpSecurityDescriptor, int dwRevision);
Beispiel #31
0
 internal static extern uint SetSecurityDescriptorDacl(
     ref SECURITY_DESCRIPTOR pSecurityDescriptor, 
     [MarshalAsAttribute(UnmanagedType.Bool)]bool bDaclPresent, 
     [InAttribute()] System.IntPtr pDacl, 
     [MarshalAsAttribute(UnmanagedType.Bool)]bool bDaclDefaulted);
Beispiel #32
0
 public extern static int SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR pSecurityDescriptor, int bDaclPresent, IntPtr pDacl, int bDaclDefaulted);
Beispiel #33
0
 public static extern bool SetSecurityDescriptorDacl(
     ref SECURITY_DESCRIPTOR sd,         // A pointer to the
     // SECURITY_DESCRIPTOR struct
     bool bDaclPresent,
     IntPtr Dacl,                        // A pointer to an ACL struct
     bool bDaclDefaulted                 // The source of the DACL
     );
		public int RunAsToken(string executablePath, string executableParameters, TextWriter standardOutputWriter, TextWriter errorOutputWriter, SafeHandle impersonationToken)
		{
			string logFileRoot = Guid.NewGuid().ToString();
			string stdoutLogFile = Path.Combine(Environment.CurrentDirectory, logFileRoot + ".stdout.log");
			string stderrLogFile = Path.Combine(Environment.CurrentDirectory, logFileRoot + ".stderr.log");
			string currentDirectory = Environment.CurrentDirectory;
			var primaryToken = new IntPtr();
			try
			{
				#region security attributes
				SECURITY_ATTRIBUTES processAttributes = new SECURITY_ATTRIBUTES();

				SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();
				IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));
				Marshal.StructureToPtr(sd, ptr, false);
				InitializeSecurityDescriptor(ptr, SECURITY_DESCRIPTOR_REVISION);
				sd = (SECURITY_DESCRIPTOR)Marshal.PtrToStructure(ptr, typeof(SECURITY_DESCRIPTOR));

				bool result = SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false);
				if (!result)
				{
					throw new Win32Exception();
				}

				result = DuplicateTokenEx(impersonationToken.DangerousGetHandle(), 0, ref processAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out primaryToken);
				if (!result)
				{
					throw new Win32Exception();
				}
				processAttributes.SecurityDescriptor = ptr;
				processAttributes.Length = (uint)Marshal.SizeOf(sd);
				processAttributes.InheritHandle = true;
				#endregion

				SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
				threadAttributes.SecurityDescriptor = IntPtr.Zero;
				threadAttributes.Length = 0;
				threadAttributes.InheritHandle = false;

				bool inheritHandles = true;
				//CreationFlags creationFlags = CreationFlags.CREATE_DEFAULT_ERROR_MODE;
				IntPtr environment = IntPtr.Zero;

				STARTUPINFO startupInfo = new STARTUPINFO();
				startupInfo.Desktop = "";

				PROCESS_INFORMATION processInformation;

				string cmdPath = Environment.GetEnvironmentVariable("COMSPEC");
				string cmdArguments = string.Format("/c {0} {1} > \"{2}\" 2> \"{3}\"", executablePath, executableParameters, stdoutLogFile, stderrLogFile);
				result = CreateProcessAsUser(primaryToken, cmdPath, cmdArguments, ref processAttributes, ref threadAttributes, inheritHandles, 16, environment, currentDirectory, ref startupInfo, out processInformation);
				if (!result)
				{
					long win32Code = Marshal.GetHRForLastWin32Error();
					if (win32Code == 0x80070522 )
					{
						//Log on as a service
						//Act as part of the operating system
						//Adjust memory quotas for a process
						//Replace a process level token

						//Impersonate a client after authentication?
						//Create token object?
						throw new Exception("privilges not set", new Win32Exception());
					}
					throw new Win32Exception();
				}
				WaitForSingleObject(processInformation.Process, INFINITE);

				if (File.Exists(stdoutLogFile))
				{
					standardOutputWriter.Write(File.ReadAllText(stdoutLogFile));
				}
				if (File.Exists(stderrLogFile))
				{
					errorOutputWriter.Write(File.ReadAllText(stderrLogFile));
				}

				uint exitCode;
				result = GetExitCodeProcess(processInformation.Process, out exitCode);
				if(!result)
				{
					throw new Win32Exception();
				}
				return (int)exitCode;
			}
			finally
			{
				if (primaryToken != IntPtr.Zero)
				{
					var result = CloseHandle(primaryToken);
					if (result == 0)
						throw new Win32Exception();
				}
			}
		}
			public static extern bool MQSetQueueSecurity(string lpwcsFormatName, int SecurityInformation, SECURITY_DESCRIPTOR pSecurityDescriptor);
Beispiel #36
0
 private static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool daclPresent, IntPtr dacl, bool daclDefaulted);
Beispiel #37
0
        void ListenForClients()
        {
            SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR();

            // set the Security Descriptor to be completely permissive
            InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION);
            SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false);

            IntPtr ptrSD = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));
            Marshal.StructureToPtr(sd, ptrSD, false);

            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES
                                         {
                                             nLength = Marshal.SizeOf(sd),
                                             lpSecurityDescriptor = ptrSD,
                                             bInheritHandle = 1
                                         };

            IntPtr ptrSA = Marshal.AllocCoTaskMem(Marshal.SizeOf(sa));
            Marshal.StructureToPtr(sa, ptrSA, false);


            while (true)
            {
                // Creates an instance of a named pipe for one client
                SafeFileHandle clientHandle =
                    CreateNamedPipe(
                        PipeName,

                        // DUPLEX | FILE_FLAG_OVERLAPPED = 0x00000003 | 0x40000000;
                        0x40000003,
                        0,
                        255,
                        BUFFER_SIZE,
                        BUFFER_SIZE,
                        0,
                        ptrSA);

                //could not create named pipe instance
                if (clientHandle.IsInvalid)
                    continue;

                int success = ConnectNamedPipe(clientHandle, IntPtr.Zero);

                //could not connect client
                if (success == 0)
                {
                    // close the handle, and wait for the next client
                    clientHandle.Close();
                    continue;
                }

                Client client = new Client
                                    {
                                        handle = clientHandle
                                    };

                lock (clients)
                    clients.Add(client);

                Thread readThread = new Thread(Read)
                                        {
                                            IsBackground = true
                                        };
                readThread.Start(client);

                // invoke the event, a client connected
                if (ClientConnected != null)
                    ClientConnected();
            }

            // free up the ptrs (never reached due to infinite loop)
            Marshal.FreeCoTaskMem(ptrSD);
            Marshal.FreeCoTaskMem(ptrSA);
        }
Beispiel #38
0
 static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool daclPresent, IntPtr dacl, bool daclDefaulted);
Beispiel #39
0
 static extern bool InitializeSecurityDescriptor(ref SECURITY_DESCRIPTOR sd, uint dwRevision);
			public static extern bool SetSecurityDescriptorOwner(SECURITY_DESCRIPTOR pSecurityDescriptor, byte[] pOwner, bool bOwnerDefaulted);
Beispiel #41
0
 private static extern bool InitializeSecurityDescriptor(ref SECURITY_DESCRIPTOR sd, uint dwRevision);
Beispiel #42
0
        /// <summary>
        /// Launches the given application with full admin rights, and in addition bypasses the Vista UAC prompt
        /// This uses the first logged on user's Session (Active Console Session) to start the UI process (Session 1 WinLogon in Vista/7/8)
        /// </summary>
        /// <param name="applicationPath">The name and path of the application to launch</param>
        /// <param name="cmdParams">Parameters to pass to the application</param>
        /// <param name="redirectOutput">True to redirect the console output (std+err) to a custom handler</param>
        /// <param name="processOutputHandler">Output redirect handler if true above, else null</param>
        /// <param name="showWindow">True if new process window needs to be shown, false to be hidden</param>
        /// <returns>Proceess Id if successful else 0</returns>
        public static uint StartAppWithAdminPrivilegesFromNonUISession(String applicationPath, string cmdParams, bool redirectOutput, DataReceivedEventHandler processOutputHandler, bool showWindow, Log log)
        {
            string appStartDirectory = null;
            uint winlogonPid = 0;
            IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero, hStdOutWrite = IntPtr.Zero, hStdOutRead = IntPtr.Zero;
            PROCESS_INFORMATION procInfo = new PROCESS_INFORMATION();

            // TODO: We need to add support for handling Unicode strings with CreateProcessAsUserW
            // For now we don't support Unicode names
            if (Util.Text.ContainsUnicode(applicationPath) || Util.Text.ContainsUnicode(cmdParams))
            {
                log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession does not support Unicode right now.", Log.LogEntryType.Error, true);
                return 0;
            }

            // Check for valid handler
            if (redirectOutput && (hStdOutRead == null))
                throw new ArgumentNullException("processOutputHandler", "ProcessOutputHandler null when RedirectOutput is true");

            // Get the path if it is an absolute path, if it's relative we start in the MCEBuddy directory
            if (Path.IsPathRooted(applicationPath))
                appStartDirectory = Path.GetDirectoryName(applicationPath); // Absolute path, get starting path
            else
                appStartDirectory = null; // Relative path starts with MCEBuddy path

            // obtain the currently active session id; every logged on user in the system has a unique session id
            uint dwSessionId = 0;
            IntPtr pSessionInfo = IntPtr.Zero;
            int dwCount = 0;
            WTSEnumerateSessions(IntPtr.Zero, 0, 1, ref pSessionInfo, ref dwCount);

            Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
            Int32 current = (int)pSessionInfo;
            for (int i = 0; i < dwCount; i++)
            {
                WTS_SESSION_INFO wsi = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
                if (WTS_CONNECTSTATE_CLASS.WTSActive == wsi.State)
                {
                    dwSessionId = wsi.SessionID;
                    break;
                }

                current += dataSize;
            }

            WTSFreeMemory(pSessionInfo); // Free this up

            // Check if there are any users logged into the current session (remote desktop or local machine console)
            IntPtr currentToken = IntPtr.Zero;
            if (!WTSQueryUserToken(dwSessionId, out currentToken))
            {
                int ret = Marshal.GetLastWin32Error();
                log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession WTSQueryUserToken failed (No logged on users) with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true);
                return 0;
            }

            CloseHandle(currentToken); // Don't need this anymore, release it

            // obtain the process id of the winlogon process that is running within the currently active session
            Process[] processes = Process.GetProcessesByName("winlogon");
            foreach (Process p in processes)
            {
                if ((uint)p.SessionId == dwSessionId)
                {
                    winlogonPid = (uint)p.Id;
                }
            }

            // obtain a handle to the winlogon process
            hProcess = OpenProcess(ProcessAccess.MAXIMUM_ALLOWED, false, winlogonPid);

            // obtain a handle to the access token of the winlogon process
            if (!OpenProcessToken(hProcess, TokenAccess.MAXIMUM_ALLOWED, out hPToken))
            {
                int ret = Marshal.GetLastWin32Error();
                log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession OpenProcessToken failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true);
                CloseHandle(hProcess);
                return 0;
            }

            // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
            // I would prefer to not have to use a security attribute variable and to just 
            // simply pass null and inherit (by default) the security attributes
            // of the existing token. However, in C# structures are value types and therefore
            // cannot be assigned the null value.
            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
            sa.nLength = Marshal.SizeOf(sa);

            // copy the access token of the winlogon process; the newly created token will be a primary token (we want to create an admin process in non session 0)
            if (!DuplicateTokenEx(hPToken, TokenAccess.MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out hUserTokenDup))
            {
                int ret = Marshal.GetLastWin32Error();
                log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession DuplicateTokenEx failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true);
                CloseHandle(hProcess);
                CloseHandle(hPToken);
                return 0;
            }

            // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
            // the window station has a desktop that is invisible and the process is incapable of receiving
            // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user 
            // interaction with the new process.
            STARTUPINFO si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);
            si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop

            // flags that specify the priority and creation method of the process - by default no window, a new console for the child process (not shared with parent) (don't use NO_WINDOW since it prevents the console output from working)
            CreationFlags dwCreationFlags = CreationFlags.NORMAL_PRIORITY_CLASS | CreationFlags.CREATE_NEW_CONSOLE;
            si.dwFlags |= StartFlags.STARTF_USESHOWWINDOW; // set showwindow information
            si.wShowWindow |= ShowWindow.SW_HIDE;

            // Set the Window information
            if (showWindow)
            {
                si.wShowWindow |= ShowWindow.SW_SHOWNORMAL; // Show show window, by default don't show
            }

            // Check if we need to redirect the output to a custom handler
            if (redirectOutput)
            {
                // Ensure we create a security descriptor with rights to read the pipe otherwise the ReadFile will fail later
                SECURITY_DESCRIPTOR saDesc = new SECURITY_DESCRIPTOR();
                if (!InitializeSecurityDescriptor(out saDesc, SECURITY_DESCRIPTOR_REVISION))
                {
                    int ret = Marshal.GetLastWin32Error();
                    log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create initialize security descriptor with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true);
                    CloseHandle(hProcess);
                    CloseHandle(hPToken);
                    CloseHandle(hUserTokenDup);
                    return 0;
                }

                if (!SetSecurityDescriptorDacl(ref saDesc, true, IntPtr.Zero, false))
                {
                    int ret = Marshal.GetLastWin32Error();
                    log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession set security descriptor failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true);
                    CloseHandle(hProcess);
                    CloseHandle(hPToken);
                    CloseHandle(hUserTokenDup);
                    return 0;
                }

                IntPtr saDescPtr = Marshal.AllocHGlobal(Marshal.SizeOf(saDesc));
                Marshal.StructureToPtr(saDesc, saDescPtr, false);
                SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES();
                saAttr.nLength = Marshal.SizeOf(saAttr);
                saAttr.bInheritHandle = true;
                saAttr.lpSecurityDescriptor = saDescPtr;

                // Create a pipe to attach to the StdOut and StdErr outputs
                if (!CreatePipe(out hStdOutRead, out hStdOutWrite, ref saAttr, 0)) // use default buffer size
                {
                    int ret = Marshal.GetLastWin32Error();
                    log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create stdout pipe failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true);
                    CloseHandle(hProcess);
                    CloseHandle(hPToken);
                    CloseHandle(hUserTokenDup);
                    return 0;
                }

                // Set the StartInfo structure information to use the redirect handles
                si.dwFlags |= StartFlags.STARTF_USESTDHANDLES; // Use custom redirect handles
                si.hStdOutput = hStdOutWrite; // Redirect StdOut (write into pipe handle)
                si.hStdError = hStdOutWrite; // Redirect StdErr (write into pipe handle)
            }

            // Create the environment
            IntPtr lpEnvironment = IntPtr.Zero;
            if (!CreateEnvironmentBlock(out lpEnvironment, hUserTokenDup, true))
            {
                int ret = Marshal.GetLastWin32Error();
                log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create environment failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Warning, true);
                lpEnvironment = IntPtr.Zero;
            }
            else
                dwCreationFlags |= CreationFlags.CREATE_UNICODE_ENVIRONMENT; // When environment is not null, this flag should be set

            // create a new process in the current user's logon session
            // Refer to http://stackoverflow.com/questions/4053241/windows-api-createprocess-path-with-space
            bool success = CreateProcessAsUser(hUserTokenDup,        // client's access token
                                            applicationPath,        // file to execute (no encapsulation)
                                            Util.FilePaths.FixSpaces(applicationPath) + " " + cmdParams,              // command line - first param (argv[0]) should be encapsulated appPath
                                            ref sa,                 // pointer to process SECURITY_ATTRIBUTES
                                            ref sa,                 // pointer to thread SECURITY_ATTRIBUTES
                                            true,                  // handles are inheritable otherwise we can't redirect output
                                            dwCreationFlags,        // creation flags
                                            lpEnvironment,          // pointer to new environment block 
                                            appStartDirectory,      // name of current directory
                                            ref si,                 // pointer to STARTUPINFO structure
                                            out procInfo            // receives information about new process
                                            );

            if (!success)
            {
                int ret = Marshal.GetLastWin32Error();
                log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create process failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true);
            }

            // invalidate the handles
            DestroyEnvironmentBlock(lpEnvironment);
            CloseHandle(hProcess);
            CloseHandle(hPToken);
            CloseHandle(hUserTokenDup);
            CloseHandle(hStdOutWrite); // We don't need this, close it now else the thread hangs

            // If we need to redirect output
            if (success && redirectOutput)
            {
                // Start the thread to read the process output - it'll close the procInfo (thread and process handles), hRead and hWrite handles when it's done
                Thread readOutput = new Thread(() => PipeReadThread(procInfo, hStdOutRead, processOutputHandler, log));
                readOutput.IsBackground = true; // Kill the thread when the process terminates 
                readOutput.Start();
            }

            if (success)
                return procInfo.dwProcessId;
            else
                return 0;
        }
Beispiel #43
0
        public static void Start()
        {
            if (_listenTask == null)
            {
                lock (typeof(Monitor)) {
                    _cancellationTokenSource = new CancellationTokenSource();

                    bool wasCreated;
                    var  ewhSec = new EventWaitHandleSecurity();
                    ewhSec.AddAccessRule(
                        new EventWaitHandleAccessRule(
                            new SecurityIdentifier(WellKnownSidType.WorldSid, null), EventWaitHandleRights.FullControl, AccessControlType.Allow));

                    var sessionAckEvent   = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_BUFFER_READY", out wasCreated, ewhSec);
                    var sessionReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_DATA_READY", out wasCreated, ewhSec);
                    var globalAckEvent    = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_BUFFER_READY", out wasCreated, ewhSec);
                    var globalReadyEvent  = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_DATA_READY", out wasCreated, ewhSec);

                    var sd = new SECURITY_DESCRIPTOR();
                    var sa = new SECURITY_ATTRIBUTES();

                    // Initialize the security descriptor.
                    if (!Advapi32.InitializeSecurityDescriptor(ref sd, 1))
                    {
                        throw new ApplicationException(
                                  string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor.", Marshal.GetLastWin32Error()));
                    }

                    // Set information in a discretionary access control list
                    if (!Advapi32.SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false))
                    {
                        throw new ApplicationException(
                                  string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor", Marshal.GetLastWin32Error()));
                    }

                    // Create the event for slot 'DBWIN_BUFFER_READY'
                    sa.nLength = Marshal.SizeOf(sa);
                    sa.lpSecurityDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(sd));
                    Marshal.StructureToPtr(sd, sa.lpSecurityDescriptor, false);

                    // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'.
                    var sessionSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
                    if (sessionSharedFileHandle == IntPtr.Zero)
                    {
                        throw new ApplicationException(
                                  string.Format(
                                      "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    // Create a view for this file mapping so we can access it
                    var sessionSharedMemoryHandle = Kernel32.MapViewOfFile(sessionSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096);
                    if (sessionSharedMemoryHandle == IntPtr.Zero)
                    {
                        throw new ApplicationException(
                                  string.Format(
                                      "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'.
                    var globalSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "Global\\DBWIN_BUFFER");
                    if (globalSharedFileHandle == IntPtr.Zero)
                    {
                        throw new ApplicationException(
                                  string.Format(
                                      "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    // Create a view for this file mapping so we can access it
                    var globalSharedMemoryHandle = Kernel32.MapViewOfFile(globalSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096);
                    if (globalSharedMemoryHandle == IntPtr.Zero)
                    {
                        throw new ApplicationException(
                                  string.Format(
                                      "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    var queue         = new Queue <Tuple <int, DateTime, string> >();
                    var dataAvailable = new ManualResetEvent(true);

                    _listenTask = Task.Factory.StartNew(
                        () => {
                        // Everything after the first DWORD is our debugging text
                        IntPtr sessionStringPointer;
                        IntPtr globalStringPointer;

                        if (Environment.Is64BitProcess)
                        {
                            sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof(int)));
                            globalStringPointer  = new IntPtr(globalSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof(int)));
                        }
                        else
                        {
                            sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof(int)));
                            globalStringPointer  = new IntPtr(globalSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof(int)));
                        }

                        while (!_cancellationTokenSource.IsCancellationRequested)
                        {
                            sessionAckEvent.Set();
                            globalAckEvent.Set();

                            try {
                                var i = WaitHandle.WaitAny(new[] {
                                    sessionReadyEvent, globalReadyEvent, _cancellationTokenSource.Token.WaitHandle
                                });
                                var now = DateTime.Now;
                                if (i == 0)
                                {
                                    lock (queue) {
                                        queue.Enqueue(new Tuple <int, DateTime, string>(Marshal.ReadInt32(sessionSharedMemoryHandle), now, Marshal.PtrToStringAnsi(sessionStringPointer)));
                                        dataAvailable.Set();
                                    }
                                }

                                if (i == 1)
                                {
                                    lock (queue) {
                                        queue.Enqueue(new Tuple <int, DateTime, string>(Marshal.ReadInt32(globalSharedMemoryHandle), now, Marshal.PtrToStringAnsi(globalStringPointer)));
                                        dataAvailable.Set();
                                    }
                                }
                            } catch {
                                // it's over.
                                _cancellationTokenSource.Cancel();
                            }
                        }
                        _listenTask = null;

                        // cleanup after stopping.
                        globalAckEvent.Reset();
                        globalAckEvent.Dispose();
                        globalAckEvent = null;

                        sessionAckEvent.Reset();
                        sessionAckEvent.Dispose();
                        sessionAckEvent = null;

                        globalReadyEvent.Reset();
                        globalReadyEvent.Dispose();
                        globalReadyEvent = null;

                        sessionReadyEvent.Reset();
                        sessionReadyEvent.Dispose();
                        sessionReadyEvent = null;

                        // Close SharedFile
                        if (sessionSharedFileHandle != IntPtr.Zero)
                        {
                            if (!Kernel32.CloseHandle(sessionSharedFileHandle))
                            {
                                throw new ApplicationException(
                                    string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error()));
                            }
                            sessionSharedFileHandle = IntPtr.Zero;
                        }

                        // Unmap SharedMem
                        if (sessionSharedMemoryHandle != IntPtr.Zero)
                        {
                            if (!Kernel32.UnmapViewOfFile(sessionSharedMemoryHandle))
                            {
                                throw new ApplicationException(
                                    string.Format(
                                        "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                            }
                            sessionSharedMemoryHandle = IntPtr.Zero;
                        }

                        // Close SharedFile
                        if (globalSharedFileHandle != IntPtr.Zero)
                        {
                            if (!Kernel32.CloseHandle(globalSharedFileHandle))
                            {
                                throw new ApplicationException(
                                    string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error()));
                            }
                            globalSharedFileHandle = IntPtr.Zero;
                        }

                        // Unmap SharedMem
                        if (globalSharedMemoryHandle != IntPtr.Zero)
                        {
                            if (!Kernel32.UnmapViewOfFile(globalSharedMemoryHandle))
                            {
                                throw new ApplicationException(
                                    string.Format(
                                        "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                            }
                            globalSharedMemoryHandle = IntPtr.Zero;
                        }
                    }, _cancellationTokenSource.Token);

                    Task.Factory.StartNew(() => {
                        // handle events on seperate task to minimize the work that is done blocking the handles
                        Tuple <int, DateTime, string> item = null;

                        while (WaitHandle.WaitAny(new[] {
                            dataAvailable, _cancellationTokenSource.Token.WaitHandle
                        }) == 0)
                        {
                            lock (queue) {
                                if (queue.Count > 0)
                                {
                                    item = queue.Dequeue();
                                }
                                if (queue.Count == 0)
                                {
                                    dataAvailable.Reset();
                                }
                            }

                            if (item == null || OnOutputDebugString == null)
                            {
                                continue;
                            }

                            try {
                                OnOutputDebugString(new OutputDebugStringEventArgs(item.Item1, item.Item2, item.Item3));
                            } catch {
                                // if it's taken, good, if not--well too bad!
                            }
                        }
                    }, _cancellationTokenSource.Token);
                }
            }
        }
Beispiel #44
0
 public static extern bool SetSecurityDescriptorOwner(ref SECURITY_DESCRIPTOR pSecurityDescriptor, IntPtr pOwner, bool bOwnerDefaulted);
Beispiel #45
0
        public static void Start() {
            if (_listenTask == null) {
                lock (typeof (Monitor)) {
                    _cancellationTokenSource = new CancellationTokenSource();

                    bool wasCreated;
                    var ewhSec = new EventWaitHandleSecurity();
                    ewhSec.AddAccessRule(
                        new EventWaitHandleAccessRule(
                            new SecurityIdentifier(WellKnownSidType.WorldSid, null), EventWaitHandleRights.FullControl, AccessControlType.Allow));

                    var sessionAckEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_BUFFER_READY", out wasCreated, ewhSec);
                    var sessionReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_DATA_READY", out wasCreated, ewhSec);
                    var globalAckEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_BUFFER_READY", out wasCreated, ewhSec);
                    var globalReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_DATA_READY", out wasCreated, ewhSec);

                    var sd = new SECURITY_DESCRIPTOR();
                    var sa = new SECURITY_ATTRIBUTES();

                    // Initialize the security descriptor.
                    if (!Advapi32.InitializeSecurityDescriptor(ref sd, 1)) {
                        throw new ApplicationException(
                            string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor.", Marshal.GetLastWin32Error()));
                    }

                    // Set information in a discretionary access control list
                    if (!Advapi32.SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) {
                        throw new ApplicationException(
                            string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor", Marshal.GetLastWin32Error()));
                    }

                    // Create the event for slot 'DBWIN_BUFFER_READY'
                    sa.nLength = Marshal.SizeOf(sa);
                    sa.lpSecurityDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(sd));
                    Marshal.StructureToPtr(sd, sa.lpSecurityDescriptor, false);

                    // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'.
                    var sessionSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER");
                    if (sessionSharedFileHandle == IntPtr.Zero) {
                        throw new ApplicationException(
                            string.Format(
                                "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    // Create a view for this file mapping so we can access it
                    var sessionSharedMemoryHandle = Kernel32.MapViewOfFile(sessionSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096);
                    if (sessionSharedMemoryHandle == IntPtr.Zero) {
                        throw new ApplicationException(
                            string.Format(
                                "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'.
                    var globalSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "Global\\DBWIN_BUFFER");
                    if (globalSharedFileHandle == IntPtr.Zero) {
                        throw new ApplicationException(
                            string.Format(
                                "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    // Create a view for this file mapping so we can access it
                    var globalSharedMemoryHandle = Kernel32.MapViewOfFile(globalSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096);
                    if (globalSharedMemoryHandle == IntPtr.Zero) {
                        throw new ApplicationException(
                            string.Format(
                                "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                    }

                    var queue = new Queue<Tuple<int, DateTime, string>>();
                    var dataAvailable = new ManualResetEvent(true);

                    _listenTask = Task.Factory.StartNew(
                        () => {
                            // Everything after the first DWORD is our debugging text
                            IntPtr sessionStringPointer;
                            IntPtr globalStringPointer;

                            if (Environment.Is64BitProcess) {
                                sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof (int)));
                                globalStringPointer = new IntPtr(globalSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof (int)));
                            } else {
                                sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof (int)));
                                globalStringPointer = new IntPtr(globalSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof (int)));
                            }

                            while (!_cancellationTokenSource.IsCancellationRequested) {
                                sessionAckEvent.Set();
                                globalAckEvent.Set();

                                try {
                                    var i = WaitHandle.WaitAny(new[] {
                                        sessionReadyEvent, globalReadyEvent, _cancellationTokenSource.Token.WaitHandle
                                    });
                                    var now = DateTime.Now;
                                    if (i == 0) {
                                        lock (queue) {
                                            queue.Enqueue(new Tuple<int, DateTime, string>(Marshal.ReadInt32(sessionSharedMemoryHandle), now, Marshal.PtrToStringAnsi(sessionStringPointer)));
                                            dataAvailable.Set();
                                        }
                                    }

                                    if (i == 1) {
                                        lock (queue) {
                                            queue.Enqueue(new Tuple<int, DateTime, string>(Marshal.ReadInt32(globalSharedMemoryHandle), now, Marshal.PtrToStringAnsi(globalStringPointer)));
                                            dataAvailable.Set();
                                        }
                                    }
                                } catch {
                                    // it's over. 
                                    _cancellationTokenSource.Cancel();
                                }
                            }
                            _listenTask = null;

                            // cleanup after stopping.
                            globalAckEvent.Reset();
                            globalAckEvent.Dispose();
                            globalAckEvent = null;

                            sessionAckEvent.Reset();
                            sessionAckEvent.Dispose();
                            sessionAckEvent = null;

                            globalReadyEvent.Reset();
                            globalReadyEvent.Dispose();
                            globalReadyEvent = null;

                            sessionReadyEvent.Reset();
                            sessionReadyEvent.Dispose();
                            sessionReadyEvent = null;

                            // Close SharedFile
                            if (sessionSharedFileHandle != IntPtr.Zero) {
                                if (!Kernel32.CloseHandle(sessionSharedFileHandle)) {
                                    throw new ApplicationException(
                                        string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error()));
                                }
                                sessionSharedFileHandle = IntPtr.Zero;
                            }

                            // Unmap SharedMem
                            if (sessionSharedMemoryHandle != IntPtr.Zero) {
                                if (!Kernel32.UnmapViewOfFile(sessionSharedMemoryHandle)) {
                                    throw new ApplicationException(
                                        string.Format(
                                            "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                                }
                                sessionSharedMemoryHandle = IntPtr.Zero;
                            }

                            // Close SharedFile
                            if (globalSharedFileHandle != IntPtr.Zero) {
                                if (!Kernel32.CloseHandle(globalSharedFileHandle)) {
                                    throw new ApplicationException(
                                        string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error()));
                                }
                                globalSharedFileHandle = IntPtr.Zero;
                            }

                            // Unmap SharedMem
                            if (globalSharedMemoryHandle != IntPtr.Zero) {
                                if (!Kernel32.UnmapViewOfFile(globalSharedMemoryHandle)) {
                                    throw new ApplicationException(
                                        string.Format(
                                            "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error()));
                                }
                                globalSharedMemoryHandle = IntPtr.Zero;
                            }
                        }, _cancellationTokenSource.Token);

                    Task.Factory.StartNew(() => {
                        // handle events on seperate task to minimize the work that is done blocking the handles
                        Tuple<int, DateTime, string> item = null;

                        while (WaitHandle.WaitAny(new[] {
                            dataAvailable, _cancellationTokenSource.Token.WaitHandle
                        }) == 0) {
                            lock (queue) {
                                if (queue.Count > 0) {
                                    item = queue.Dequeue();
                                }
                                if (queue.Count == 0) {
                                    dataAvailable.Reset();
                                }
                            }

                            if (item == null || OnOutputDebugString == null) {
                                continue;
                            }

                            try {
                                OnOutputDebugString(new OutputDebugStringEventArgs(item.Item1, item.Item2, item.Item3));
                            } catch {
                                // if it's taken, good, if not--well too bad!
                            }
                        }
                    }, _cancellationTokenSource.Token);
                }
            }
        }
			public static extern bool InitializeSecurityDescriptor(SECURITY_DESCRIPTOR SD, int revision);
Beispiel #47
0
 public static extern bool InitializeSecurityDescriptor(out SECURITY_DESCRIPTOR SecurityDescriptor, uint dwRevision);
 public static extern bool QueryServiceObjectSecurity(IntPtr serviceHandle,
                                                      System.Security.AccessControl.SecurityInfos secInfo,
                                                      ref SECURITY_DESCRIPTOR lpSecDesrBuf,
                                                      uint bufSize,
                                                      out uint bufSizeNeeded);
Beispiel #49
0
 public static extern bool SetFileSecurity(string lpFileName, UInt32 SecurityInformation, ref SECURITY_DESCRIPTOR pSecurityDescriptor);
Beispiel #50
0
        public DebugMonitor()
        {
            SECURITY_ATTRIBUTES attributes = new SECURITY_ATTRIBUTES();
            SECURITY_DESCRIPTOR descriptor = new SECURITY_DESCRIPTOR();

            IntPtr sharedFile = IntPtr.Zero;
            IntPtr pDescriptor = IntPtr.Zero;
            IntPtr pAttributes = IntPtr.Zero;
            try
            {
                pDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(descriptor));
                pAttributes = Marshal.AllocHGlobal(Marshal.SizeOf(attributes));

                attributes.nLength = Marshal.SizeOf(attributes);
                attributes.bInheritHandle = true;
                attributes.lpSecurityDescriptor = pDescriptor;

                if (!InitializeSecurityDescriptor(ref descriptor, 1 /*SECURITY_DESCRIPTOR_REVISION*/))
                    throw new ApplicationException("InitializeSecurityDescriptor failed: " + Marshal.GetLastWin32Error());

                if (!SetSecurityDescriptorDacl(ref descriptor, true, IntPtr.Zero, false))
                    throw new ApplicationException("SetSecurityDescriptorDacl failed: " + Marshal.GetLastWin32Error());

                Marshal.StructureToPtr(descriptor, pDescriptor, false);
                Marshal.StructureToPtr(attributes, pAttributes, false);

                bufferEvent = CreateEvent(pAttributes, false, false, "DBWIN_BUFFER_READY");

                if (bufferEvent == IntPtr.Zero)
                    throw new ApplicationException("CreateEvent (bufferEvent) failed: " + Marshal.GetLastWin32Error());

                if (Marshal.GetLastWin32Error() == 183 /*ERROR_ALREADY_EXISTS*/)
                    throw new AlreadyRunningException();

                dataEvent = CreateEvent(pAttributes, false, false, "DBWIN_DATA_READY");

                if (dataEvent == IntPtr.Zero)
                    throw new ApplicationException("CreateEvent (dataEvent) failed: " + Marshal.GetLastWin32Error());

                sharedFile = CreateFileMapping(new IntPtr(-1), pAttributes, 4 /*PAGE_READWRITE*/, 0, 4096, "DBWIN_BUFFER");

                if (sharedFile == IntPtr.Zero)
                    throw new ApplicationException("CreateFileMapping failed: " + Marshal.GetLastWin32Error());
            }
            finally
            {
                Marshal.FreeHGlobal(pDescriptor);
                Marshal.FreeHGlobal(pAttributes);
            }

            IntPtr sharedMemory = MapViewOfFile(sharedFile, 4 /*FILE_MAP_READ*/, 0, 0, 512);

            if (sharedMemory == IntPtr.Zero)
                throw new ApplicationException("MapViewOfFile failed: " + Marshal.GetLastWin32Error());

            // The first 4 bytes are the process ID, and the remaining bytes are the message
            pPID = sharedMemory;
            pMessage = new IntPtr((long)sharedMemory + 4);
        }