ntdll/NtQueryEaFile.ps1
function NtQueryEaFile { <# .SYNOPSIS The NtQueryEaFile routine returns information about extended-attribute (EA) values for a file. .NOTES Author: Jared Atkinson (@jaredcatkinson) License: BSD 3-Clause Required Dependencies: PSReflect, IO_STATUS_BLOCK (Structure) Optional Dependencies: None (func ntdll NtQueryEaFile ([UInt32]) @( [IntPtr], #_In_ HANDLE FileHandle $IO_STATUS_BLOCK.MakeByRefType(), #_Out_ PIO_STATUS_BLOCK IoStatusBlock [IntPtr], #_Out_ PVOID Buffer [UInt32], #_In_ ULONG Length [bool], #_In_ BOOLEAN ReturnSingleEntry [IntPtr], #_In_opt_ PVOID EaList [UInt32], #_In_ ULONG EaListLength [IntPtr], #_In_opt_ PULONG EaIndex [bool] #_In_ BOOLEAN RestartScan ) -EntryPoint NtQueryEaFile) .LINK https://msdn.microsoft.com/en-us/library/windows/hardware/ff961907(v=vs.85).aspx .EXAMPLE #> param ( [Parameter(Mandatory = $true)] [IntPtr] $FileHandle ) # Create an Instance of the IO_STATUS_BLOCK structure $IoStatusBlock = [Activator]::CreateInstance($IO_STATUS_BLOCK) # Make the return buffer max size $Buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(0xFFFF) # Call NtQueryEaFile $SUCCESS = $Ntdll::NtQueryEaFile($FileHandle, [ref]$IoStatusBlock, $Buffer, 0xFFFF, $true, [IntPtr]::Zero, 0, [IntPtr]::Zero, $false); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error() if($SUCCESS -eq 0) # NT_SUCCESS { # We found an extended Attribute # Cast the buffer to an instance of the FILE_FULL_EA_INFORMATION structure $FileFullEaInformation = $Buffer -as $FILE_FULL_EA_INFORMATION # Retrieve the name of the Extended Attribute $NameOffset = [IntPtr]::Add($buffer, 8) $Name = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($NameOffset, $FileFullEaInformation.EaNameLength) # Retrieve the contents of the Extended Attribute from the EaValueLength Pointer $ValueOffset = [IntPtr]::Add($NameOffset, $FileFullEaInformation.EaNameLength + 1) $Value = New-Object -TypeName byte[]($FileFullEaInformation.EaValueLength) [System.Runtime.InteropServices.Marshal]::Copy($ValueOffset, $Value, 0, $Value.Length) $obj = New-Object -TypeName psobject $obj | Add-Member -MemberType NoteProperty -Name Name -Value $Name $obj | Add-Member -MemberType NoteProperty -Name Value -Value $Value $obj | Add-Member -MemberType NoteProperty -Name ValueAsString -Value ([System.Text.Encoding]::ASCII.GetString($Value)) $obj | Add-Member -MemberType NoteProperty -Name NextEntryOffset -Value $FileFullEaInformation.NextEntryOffset $obj | Add-Member -MemberType NoteProperty -Name Flags -Value $FileFullEaInformation.Flags Write-Output $obj } elseif($SUCCESS -eq 3221225554) # STATUS_NO_EAS_ON_FILE { # File has no Extended Attribute } else # There was an error { throw "[NtQueryEaFile] Error: $(([ComponentModel.Win32Exception] $LastError).Message)" } # Free the memory page allocated for our return buffer [System.Runtime.InteropServices.Marshal]::FreeHGlobal($Buffer) } |