Skip to content

Commit

Permalink
Implementing LibraryImports instead of DllImports for improved perfor…
Browse files Browse the repository at this point in the history
…mance (#433)

Fixed CA1838 in the CryptoAPI class.
Changed theCertGetNameStringW to use LibraryImport.
Changed CryptDecodeObject in Opus class to use LibraryImport.
Changed WinVerifyTrust in WinTrust class to use LibraryImport.
No DllImport exists in the code anymore.
  • Loading branch information
HotCakeX authored Dec 1, 2024
1 parent a9833e6 commit afe8fbf
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 60 deletions.
4 changes: 2 additions & 2 deletions AppControl Manager/Logic/AllCertificatesGrabber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public static List<AllFileSigners> GetAllFileSigners(string FilePath)
// Call WinVerifyTrust to verify trust on the file
WinTrust.WinVerifyTrustResult verifyTrustResult = WinTrust.WinVerifyTrust(
IntPtr.Zero,
WinTrust.GenericWinTrustVerifyActionGuid,
ref WinTrust.GenericWinTrustVerifyActionGuid,
winTrustDataPointer
);

Expand Down Expand Up @@ -314,7 +314,7 @@ public static List<AllFileSigners> GetAllFileSigners(string FilePath)

// Convert TrustedData back to pointer and call WinVerifyTrust to close the structure
Marshal.StructureToPtr(TrustedData, winTrustDataPointer, false);
_ = WinTrust.WinVerifyTrust(IntPtr.Zero, WinTrust.GenericWinTrustVerifyActionGuid, winTrustDataPointer);
_ = WinTrust.WinVerifyTrust(IntPtr.Zero, ref WinTrust.GenericWinTrustVerifyActionGuid, winTrustDataPointer);
}

// Free memory allocated to winTrustDataPointer
Expand Down
80 changes: 46 additions & 34 deletions AppControl Manager/Logic/Crypt32CertCN.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
using System;
using System.Runtime.InteropServices;
using System.Text;

#pragma warning disable CA1838 // Avoid 'StringBuilder' parameters for P/Invoke methods

namespace WDACConfig
{
public static class CryptoAPI
public static partial class CryptoAPI
{
// Importing function from crypt32.dll to access certificate information
// https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringa
[DllImport("crypt32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CertGetNameString(
IntPtr pCertContext, // the handle property of the certificate object
// https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringw
[LibraryImport("crypt32.dll", EntryPoint = "CertGetNameStringW", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)]
private static partial int CertGetNameString(
IntPtr pCertContext, // The handle property of the certificate object
int dwType,
int dwFlags,
IntPtr pvTypePara,
StringBuilder pszNameString,
[Out] char[] pszNameString,
int cchNameString
);

Expand All @@ -25,42 +21,58 @@ int cchNameString
public const int CERT_NAME_ATTR_TYPE = 3; // Display type for attributes
public const int CERT_NAME_ISSUER_FLAG = 0x1; // Flag indicating that the issuer name should be retrieved

// Define a helper method to get the name string
/// <summary>
/// The main method of the class to get the name string
/// </summary>
/// <param name="pCertContext"></param>
/// <param name="dwType"></param>
/// <param name="pvTypePara"></param>
/// <param name="isIssuer"></param>
/// <returns></returns>
public static string GetNameString(IntPtr pCertContext, int dwType, string? pvTypePara, bool isIssuer)
{
// Allocate a buffer for the name string, setting it big to handle longer names if needed
// Allocate a buffer for the name string
const int bufferSize = 1024;
StringBuilder nameString = new(bufferSize);
char[] nameBuffer = new char[bufferSize];

// Convert the pvTypePara to a pointer if needed
IntPtr pvTypeParaPtr = IntPtr.Zero;
if (!string.IsNullOrEmpty(pvTypePara))

try
{
// Using Unicode encoding for better compatibility
pvTypeParaPtr = Marshal.StringToHGlobalUni(pvTypePara);
}

// Set flags to retrieve issuer name if needed
int flags = isIssuer ? CERT_NAME_ISSUER_FLAG : 0;
if (!string.IsNullOrEmpty(pvTypePara))
{
// Using Unicode encoding for better compatibility
pvTypeParaPtr = Marshal.StringToHGlobalUni(pvTypePara);
}

// Call the CertGetNameString function to get the name string
bool result = CertGetNameString(
pCertContext,
dwType,
flags,
pvTypeParaPtr,
nameString,
nameString.Capacity
);
// Set flags to retrieve issuer name if needed
int flags = isIssuer ? CERT_NAME_ISSUER_FLAG : 0;

// Call the CertGetNameString function to get the name string
int result = CertGetNameString(
pCertContext,
dwType,
flags,
pvTypeParaPtr,
nameBuffer,
nameBuffer.Length
);

// Return the name string or an empty string if failed
return result > 0 ? new string(nameBuffer, 0, result - 1) : string.Empty; // Exclude null terminator

// Free the pointer if allocated
if (pvTypeParaPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(pvTypeParaPtr);
}
finally
{
// Free the pointer if allocated
if (pvTypeParaPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(pvTypeParaPtr);
}

// Return the name string or an empty string if failed
return result ? nameString.ToString() : string.Empty;
}
}
}
}
29 changes: 13 additions & 16 deletions AppControl Manager/Logic/GetOpusData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,25 @@
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;

#pragma warning disable SYSLIB1054

namespace WDACConfig
{
public static class Opus
public static partial class Opus
{
internal static class Crypt32
internal static partial class Crypt32
{

// More info: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecodeobject
[DllImport("crypt32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CryptDecodeObject(
uint dwCertEncodingType, // Specifies the encoding type used in the encoded message
IntPtr lpszStructType, // Pointer to a null-terminated ANSI string that identifies the type of the structure to be decoded
[In] byte[] pbEncoded, // Pointer to a buffer that contains the encoded structure
uint cbEncoded, // Size, in bytes, of the pbEncoded buffer
uint dwFlags, // Flags that modify the behavior of the function
[Out] IntPtr pvStructInto, // Pointer to a buffer that receives the decoded structure
ref uint pcbStructInfo // Pointer to a variable that specifies the size, in bytes, of the pvStructInfo buffer
);


[LibraryImport("crypt32.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool CryptDecodeObject(
uint dwCertEncodingType, // Specifies the encoding type used in the encoded message
IntPtr lpszStructType, // Pointer to a null-terminated ANSI string that identifies the type of the structure to be decoded
[In] byte[] pbEncoded, // Pointer to a buffer that contains the encoded structure
uint cbEncoded, // Size, in bytes, of the pbEncoded buffer
uint dwFlags, // Flags that modify the behavior of the function
IntPtr pvStructInto, // Pointer to a buffer that receives the decoded structure
ref uint pcbStructInfo // Pointer to a variable that specifies the size, in bytes, of the pvStructInfo buffer
);
}

// More info about this at the end of the code
Expand Down
12 changes: 4 additions & 8 deletions AppControl Manager/Logic/Types And Definitions/WinTrust.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Runtime.InteropServices;

#pragma warning disable SYSLIB1054

namespace WDACConfig
{
// This class contains all of the WinTrust related functions and codes
Expand Down Expand Up @@ -113,17 +111,15 @@ public enum WinVerifyTrustResult : uint
// Constants related to WinTrust
internal const uint StateActionVerify = 1;
internal const uint StateActionClose = 2;
internal static readonly Guid GenericWinTrustVerifyActionGuid = new("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}");

internal static Guid GenericWinTrustVerifyActionGuid = new("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}");

// External method declarations for WinVerifyTrust and WTHelperProvDataFromStateData
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]

// https://learn.microsoft.com/en-us/windows/win32/api/wintrust/nf-wintrust-winverifytrust
[LibraryImport("wintrust.dll", EntryPoint = "WinVerifyTrust")]
// Set to return a WinVerifyTrustResult enum
internal static extern WinVerifyTrustResult WinVerifyTrust(
internal static partial WinVerifyTrustResult WinVerifyTrust(
IntPtr hwnd,
[MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID,
ref Guid pgActionID,
IntPtr pWVTData);

// https://learn.microsoft.com/en-us/windows/win32/api/wintrust/nf-wintrust-wthelperprovdatafromstatedata
Expand Down

0 comments on commit afe8fbf

Please sign in to comment.