How to use Windows API AuditEnumerateCategories function in PowerShell?

一世执手 提交于 2020-07-22 21:39:27

问题


I want get the current Advanced Security Audit Policy using PowerShell. I could use auditpol.exe, but its ouput is different per OS language, which makes it difficult to parse.

The settings are stored in a REG_NONE value in HKEY_Local_Machine\Security\Policy\PolAdtEv. I could try to parse the value with the help of that unofficial structure table. My preferred approach, however, is to use the Windows API function AuditQuerySystemPolicy of advapi32.dll.

With the great help of this article, I created a Type in PowerShell as follows.

$MemberDefinition = @'
[DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool AuditEnumerateCategories(
        out IntPtr ppAuditCategoriesArray, 
        out uint pCountReturned);

[DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool AuditLookupCategoryName(
        ref Guid pAuditCategoryGuid, 
        out StringBuilder ppszCategoryName);

[DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool AuditEnumerateSubCategories(
        ref Guid pAuditCategoryGuid, 
        bool bRetrieveAllSubCategories, 
        out IntPtr ppAuditSubCategoriesArray, 
        out uint pCountReturned);

[DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool AuditLookupSubCategoryName(
        ref Guid pAuditSubCategoryGuid, 
        out StringBuilder ppszSubCategoryName);

[DllImport("advapi32.dll")]
    public static extern void AuditFree(
        IntPtr buffer);

[DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool AuditQuerySystemPolicy(
        Guid pSubCategoryGuids, 
        uint PolicyCount, 
        out IntPtr ppAuditPolicy);
'@

$Advapi32 = Add-Type -MemberDefinition $MemberDefinition -Name 'Advapi32' -Namespace 'Win32' -UsingNamespace System.Text -PassThru

The Type is created successfuly, but I fail with the first step - to get the GUIDs of all audit categories. I have issues with the different types. I tried for example

$guid = [Guid].MakeByRefType()
$count = [IntPtr]::Zero
[Win32.Advapi32]::AuditEnumerateCategories([ref]$guid, [ref]$count)
# Exception calling "AuditEnumerateCategories" with 2 Arguments: "The value "System.Guid&" of the type "System.RuntimeType" cannot be coverted to "System.IntPtr".

I also tried to change the AuditEnumerateCategories definition output from IntPtr to Guid. The output of ppAuditCategoriesArray is

A pointer to a single buffer that contains both an array of pointers to GUID structures and the structures themselves.

Unfortunately I have no idea how to handle that in PowerShell.


回答1:


Take up a Marshal.PtrToStructure Method (.NET). For instance, PtrToStructure(IntPtr, Type) marshals data from an unmanaged block of memory to a newly allocated managed object of the specified type, see the following commented code snippet:

### (unchanged)
### $MemberDefinition =  …
### $Advapi32 = Add-Type … 

$guid  = [System.Int64]::MinValue            ### or ### [System.Int64]0
$count = [System.Int32]::MaxValue            ### or ### [System.Int64]0

$aux = [Win32.Advapi32]::AuditEnumerateCategories([ref]$guid, [ref]$count)

$guidArr = @()                               ### array to store GUIDs

$guidPtr = [int64]$guid                      ### pointer to next GUID
$guidOff = [System.Runtime.InteropServices.Marshal]::SizeOf([type][guid])
$ppszCategoryName = [System.Text.StringBuilder]::new()

for ( $i=0; $i -lt $count; $i++ ) {
    $guidAux = [System.Runtime.InteropServices.Marshal]::
                      PtrToStructure( [System.IntPtr]$guidPtr,[type][guid] )
    $guidArr += $guidAux           ### update array of GUIDs for future use
    $guidPtr += $guidOff           ### shift pointer to next GUID

    ### debugging: try another method of [Win32.Advapi32] Runtime Type 
    $foo = [Win32.Advapi32]::AuditLookupCategoryName([ref]$guidAux,[ref]$ppszCategoryName)
    ### debugging: show partial results
    Write-Host $('{0} {1,4} {2,4}' -f $guidAux.Guid, 
                      $ppszCategoryName.Capacity, $ppszCategoryName.Length)
}


来源:https://stackoverflow.com/questions/46142190/how-to-use-windows-api-auditenumeratecategories-function-in-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!