是否有办法确定Powershell中指定的文件是否在任何位置包含指定的字节数组?
类似:
fgrep --binary-files=binary "$data" "$filepath"
当然,我可以编写一个简单的实现:
function posOfArrayWithinArray {
param ([byte[]] $arrayA, [byte[]]$arrayB)
if ($arrayB.Length -ge $arrayA.Length) {
foreach ($pos in 0..($arrayB.Length - $arrayA.Length)) {
if ([System.Linq.Enumerable]::SequenceEqual(
$arrayA,
[System.Linq.Enumerable]::Skip($arrayB, $pos).Take($arrayA.Length)
)) {return $pos}
}
}
-1
}
function posOfArrayWithinFile {
param ([byte[]] $array, [string]$filepath)
posOfArrayWithinArray $array (Get-Content $filepath -AsByteStream)
}
// They return position or -1, but simple $false/$true are also enough for me.
—但它[缓慢。
function Get-BinaryText {
# converts the bytes of a file to a string that has a
# 1-to-1 mapping back to the file's original bytes.
# Useful for performing binary regular expressions.
Param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ValidateScript( { Test-Path $_ -PathType Leaf } )]
[Alias('FullName','FilePath')]
[string]$Path
)
$Stream = New-Object System.IO.FileStream -ArgumentList $Path, 'Open', 'Read'
# Note: Codepage 28591 returns a 1-to-1 char to byte mapping
$Encoding = [Text.Encoding]::GetEncoding(28591)
$StreamReader = New-Object System.IO.StreamReader -ArgumentList $Stream, $Encoding
$BinaryText = $StreamReader.ReadToEnd()
$Stream.Dispose()
$StreamReader.Dispose()
return $BinaryText
}
# enter the byte array to search for here
# for demo, I'll use 'SearchMe' in bytes
[byte[]]$searchArray = 83,101,97,114,99,104,77,101
# create a regex from the $searchArray bytes
# 'SearchMe' --> '\x53\x65\x61\x72\x63\x68\x4D\x65'
$searchString = ($searchArray | ForEach-Object { '\x{0:X2}' -f $_ }) -join ''
$regex = [regex]$searchString
# read the file as binary string
$binString = Get-BinaryText -Path 'D:\test.bin'
# use regex to return the 0-based starting position of the search string
# return -1 if not found
$found = $regex.Match($binString)
if ($found.Success) { $found.Index } else { -1}