Capturing AccessViolation in .NET 4. Good or bad?

There is an object of type SECURITY_IDENTIFIER in the file. I need to get the owner SID from this structure. To do this, I call GetSecurityDescriptorOwner the WinAPI function and create a System.Security.Principal.SecurityIdentifier (it has an overload that takes IntPtr as an argument)

The problem is that this structure in the file is sometimes interrupted, so the pointer I get from GetSecurityDescriptorOwner is invalid. This is not IntPtr.Zero, it is not valid, so when I create an object of type SecurityIdentifier , I get an AccessViolationException that cannot be caught with .NET 4 with a simple try-catch.

I know an attribute that allows catching such exceptions, so I have used it for now, but I do not like this solution. It is not recommended to catch Corrupted State Exceptions (CSE), but I do not see other solutions. This WinAPI function returns an invalid pointer to me, and I see no way to check it for validity. Any ideas?

Update

Winapi

 BOOL WINAPI GetSecurityDescriptorOwner( _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor, _Out_ PSID *pOwner, _Out_ LPBOOL lpbOwnerDefaulted ); 

Extern definition

 [DllImport("Advapi32.dll")] static extern bool GetSecurityDescriptorOwner( IntPtr pSecurityDescriptor, out IntPtr owner, out bool defaulted); 

Update

 private static SecurityIdentifier GetSecurityIdentifier() { // Allocate managed buffer for invalid security descriptor structure (20 bytes) int[] b = new int[5] {1, 1, 1, 1, 1}; // Allocate unmanaged memory for security descriptor IntPtr descriptorPtr = Marshal.AllocHGlobal(b.Length); // Copy invalid security descriptor structure to the unmanaged buffer Marshal.Copy(b, 0, descriptorPtr, b.Length); IntPtr ownerSid; bool defaulted; if (GetSecurityDescriptorGroup(descriptorPtr, out ownerSid, out defaulted)) { // GetSecurityDescriptorGroup returns true, but `ownerSid` is `1` // Marshal.GetLastWin32Error returns 0 here return new SecurityIdentifier(ownerSid); } return null; } 

This code sometimes throws Corrected exceptions from the SecurityIdentifier constructor. Any solutions?

+4
source share
2 answers

Have you tried calling IsValidSecurityDescriptor ?

 [DllImport("Advapi32.dll")] static extern bool IsValidSecurityDescriptor(IntPtr pSecurityDescriptor); if (IsValidSecurityDescriptor(descriptorPtr) && GetSecurityDescriptorOwner(descriptorPtr, out ownerSid, out defaulted)) { return new SecurityIdentifier(ownerSid); } 
+1
source

Updated:

Try this instead:

  [DllImport("Advapi32.dll")] static extern bool GetSecurityDescriptorOwner( [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] Int32[] securityDescriptor, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1)] out Byte[] owner, out Boolean defaulted); [DllImport("Advapi32.dll")] static extern bool IsValidSecurityDescriptor( [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] Int32[] securityDescriptor); private static SecurityIdentifier GetSecurityIdentifier() { // Allocate managed buffer for invalid security descriptor structure (20 bytes) Int32[] b = new[] { 1, 1, 1, 1, 1 }; Byte[] ownerSid; bool defaulted; if (IsValidSecurityDescriptor(b) && GetSecurityDescriptorOwner(b, out ownerSid, out defaulted)) { return new SecurityIdentifier(ownerSid, 0); } return null; } static void Main() { for (Int32 index = 0; index < 1000; index++) { SecurityIdentifier identifier = GetSecurityIdentifier(); String text = identifier == null ? "(none)" : identifier.Value; Console.WriteLine(text); } Console.ReadKey(); } 
0
source

Source: https://habr.com/ru/post/1432797/


All Articles