iNNOKENTIY21
Silver Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору UTF-16LE Код: ($Unsafe = New-Object -TypeName System.CodeDom.Compiler.CompilerParameters).CompilerOptions = '/unsafe' if (!('FileStreamSearcher' -as [type])) { Add-Type -CompilerParameters $Unsafe -TypeDefinition @' using Microsoft.Win32.SafeHandles; using System; using System.IO; using System.Collections.Generic; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security.Permissions; public class FileStreamSearcher { [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] public sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid { private SafeFindHandle() : base(true) { } protected override bool ReleaseHandle() { return FindClose(handle); } [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static extern bool FindClose(IntPtr handle); } private const int ERROR_HANDLE_EOF = 38; private enum StreamInfoLevels { FindStreamInfoStandard = 0 } [DllImport("kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto, SetLastError = true)] private static extern SafeFindHandle FindFirstStreamW( string lpFileName, StreamInfoLevels InfoLevel, [In, Out, MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_STREAM_DATA lpFindStreamData, uint dwFlags ); [DllImport("kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool FindNextStreamW( SafeFindHandle hndFindFile, [In, Out, MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_STREAM_DATA lpFindStreamData ); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private class WIN32_FIND_STREAM_DATA { public long StreamSize; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 296)] public string cStreamName; } private static IEnumerable<string> GetStreamsEntries(string entries) { if (entries == null) throw new ArgumentNullException("entries"); WIN32_FIND_STREAM_DATA findStreamData = new WIN32_FIND_STREAM_DATA(); SafeFindHandle handle = FindFirstStreamW(entries, StreamInfoLevels.FindStreamInfoStandard, findStreamData, 0); if (!handle.IsInvalid) { try { do { yield return entries + findStreamData.cStreamName; } while (FindNextStreamW(handle, findStreamData)); int lastError = Marshal.GetLastWin32Error(); if (lastError != ERROR_HANDLE_EOF) throw new Exception("lastError"); } finally { handle.Dispose(); } } } private static IEnumerable<string> GetStreamsDirectoryEntries(string path) { foreach (string entries in Directory.EnumerateFileSystemEntries(path)) { foreach (var stream in GetStreamsEntries(entries)) { yield return stream; } } } public static IEnumerable<string> GetStreams(string path, bool recurse = false) { if (!File.Exists(path)) { if (Directory.Exists(path) & recurse) { return GetStreamsDirectoryEntries(path); } } return GetStreamsEntries(path); } } '@ } <# ПРОВЕРКА #> # Создание временной папки $path = New-Item -ItemType Directory -Path $env:TEMP -Name ([System.Guid]::NewGuid().Guid) # Добавление потоков Add-Content $path -Stream 'secretStream1' -Value ('Secret Information 1: ' + $path.Parent) Add-Content $path -Stream 'secretStream2' -Value ('Secret Information 2: ' + $path.Name) # Получение потоков $streams = try {[FileStreamSearcher]::GetStreams($path.FullName)} catch {} # Вывод данных из потоков foreach ($stream in $streams) { "`nПоток: $($stream)" Get-Content ($stream) } # Удаление временной папки Remove-Item $path <# --- ПРОВЕРКА --- #> # FindFirstStreamW function | Microsoft Docs — https://docs.microsoft.com/ru-ru/windows/desktop/api/fileapi/nf-fileapi-findfirststreamw # FindNextStreamW function | Microsoft Docs — https://docs.microsoft.com/ru-ru/windows/desktop/api/fileapi/nf-fileapi-findnextstreamw # c# - NTFS Alternate Data Streams - .NET - Stack Overflow — https://stackoverflow.com/questions/604960/ntfs-alternate-data-streams-net/7988352#7988352 | |