Harden-Sysvol/Private/FileHandlers.psm1
2024-11-18 11:52:18 +01:00

981 lines
33 KiB
PowerShell

# FileHandlers.psm1
#region FonctionDetect
function Get-OthersContent {
param (
[string]$filepath,
[string[]]$patterns
)
$results = @()
try {
$findmatch = Select-String -Path $filepath -Pattern $patterns -AllMatches
foreach ($match in $findmatch) {
$patternMatch = $match.pattern -replace '\\b',''
[string]$word= $match.line.Replace($patternMatch,'')
if (-not([string]::IsNullOrEmpty(($word -replace '^[\s=:"]+').Trim()))){
switch ($patternMatch) {
'(?:[0-9]{1,3}\.){3}[0-9]{1,3}' { $patternMatch = 'IPv4' }
'[a-fA-F0-9]{32}' { $patternMatch = 'MD5' }
'[a-fA-F0-9]{40}' { $patternMatch = 'SHA-1' }
'[a-fA-F0-9]{64}' { $patternMatch = 'SHA-256' }
default {
switch -Wildcard ($patternMatch) {
'net *' { $patternMatch = 'Commande Net User' }
default { $patternMatch = $patternMatch }
}
}
}
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $patternMatch
Reason = $match.Line
}
$results += $result
}
}
} catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'error'
Reason = $_.Exception.Message
}
$results = $result
}
return $results
}
function Get-DocxContent {
param (
[string]$filepath,
[string[]]$patterns
)
$results = @()
Import-Module PSWriteOffice
try {
$document = Get-OfficeWord -FilePath $filepath -ReadOnly
$n = 0
foreach ($pattern in $patterns) {
$pattern = $pattern -replace '\\b', ''
[string]$findtext = $document.Find($pattern) | Select-Object text -First 2
if ($findtext) {
if ($n -le '1') {
foreach ($text in $findtext) {
$n++
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $pattern
Reason = $text
}
$results += $result
}
} elseif ($n -gt '1') {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $pattern
Reason = "at least " + $n + " characters found"
}
$results += $result
break }
}
}
Close-OfficeWord -Document $document
}
catch { $result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'error'
Reason = $_
}
$results = $result
}
$results
}
function Get-XlsxContent {
param (
[string]$filepath,
[string[]]$patterns
)
$results = @()
Import-Module PSWriteOffice
try {
$excel = Get-OfficeExcel -FilePath $filepath
$n = 0
foreach ($pattern in $patterns) {
$pattern = $pattern -replace '\\b', ''
[string]$findtext = $excel.Search($pattern, [System.Globalization.CompareOptions]::IgnoreCase, $false) | Select-Object value -First 2
if ($findtext) {
if ($n -le '2') {
foreach ($text in $findtext) {
$n++
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $pattern
Reason = $text
}
$results += $result
}
} else {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $pattern
Reason = "at least " + $n + " characters found"
}
$results += $result
break }
}
}
$excel.Dispose()
}
catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'error'
Reason = $_
}
$results = $result
}
$results
}
function Get-DocContent {
param (
[string]$filepath,
[string[]]$patterns,
[string]$wordinstalled
)
$results = @()
if ($wordinstalled -eq $false) {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'requires_check'
Reason = 'Word is not installed'
}
$results += $result
} else {
$wordApp = New-Object -ComObject Word.Application
$wordApp.Visible = $false
try {
$document = $wordApp.Documents.Open($filepath, [ref]$null, [ref]$true)
$n = 0
foreach ($pattern in $patterns) {
$pattern = $pattern -replace '\\b', ''
$find = $document.Content.Find | Select-Object -First 1
$find.Text = $pattern
$find.Forward = $true
$find.Wrap = 1 # wdFindContinue
$find.Execute() | Out-Null
if ($find.Found) {
if ($n -le '2') {
$n++
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $pattern
Reason = "at least " + $n + " characters found"
}
$results = $result
} else { break }
}
}
$document.Close([ref]$false)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($document) | Out-Null
} catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'error'
Reason = $_.Exception.Message
}
$results = $result
} finally {
$wordApp.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($wordApp) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
}
$results
}
function Get-XlsContent {
param (
[string]$filePath,
[string[]]$patterns,
[string]$excelInstalled
)
$results = @()
if ($excelInstalled -eq $false) {
$result = [PSCustomObject]@{
FilePath = $filePath
pattern = 'requires_check'
Reason = 'Excel is not installed'
}
$results += $result
} else {
$excelApp = New-Object -ComObject Excel.Application
$excelApp.Visible = $false
try {
$workbook = $excelApp.Workbooks.Open($filePath, [ref]$null, [ref]$true)
$n = 0
foreach ($pattern in $patterns) {
$pattern = $pattern -replace '\\b', ''
foreach ($sheet in $workbook.Sheets) {
$cells = $sheet.Cells.Find($pattern)
if ($null -ne $cells) {
if ($n -le '2') {
$n++
$result = [PSCustomObject]@{
FilePath = $filePath
pattern = $pattern
Reason = "at least " + $n + " characters found"
}
$results = $result
} else { break }
}
}
}
$workbook.Close([ref]$false)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook) | Out-Null
} catch {
$result = [PSCustomObject]@{
FilePath = $filePath
pattern = 'error'
Reason = $_.Exception.Message
}
$results = $result
} finally {
$excelApp.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelApp) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
}
$results
}
function Get-PPTContent {
param (
[string]$filepath,
[string[]]$patterns,
[string]$wordinstalled
)
$results = @()
if ($wordinstalled -eq $false) {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'requires_check'
Reason = 'Office is not installed'
}
$results += $result
}
else {
try {
$MSPPT = New-Object -ComObject powerpoint.application
$PRES = $MSPPT.Presentations.Open($filepath, $true, $true, $false)
$n = 0
foreach($Slide in $PRES.Slides) {
foreach ($Shape in $Slide.Shapes) {
if ($Shape.HasTextFrame -eq "-1") {
$text = $Shape.TextFrame.TextRange.Text
foreach ($pattern in $patterns) {
$pattern = $pattern -replace '\\b', ''
if ($text -match $pattern) {
if ($n -le '2') {
$n++
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $pattern
Reason = "at least " + $n + " characters found"
}
$results = $result
} else { break }
}
}
}
}
}
$MSPPT.PresentationClose
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($MSPPT) | Out-Null
} catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'error'
Reason = $_.Exception.Message
}
$results = $result
} finally {
$MSPPT.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($MSPPT) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
}
$results
}
function Get-OdsContent {
param (
[string]$filePath,
[string[]]$patterns
)
$results = @()
# Open ODS file
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($filePath)
# Extract contenant
$contentXmlEntry = $zip.Entries | Where-Object { $_.FullName -eq "content.xml" }
$reader = [System.IO.StreamReader]::new($contentXmlEntry.Open())
$contentXml = $reader.ReadToEnd()
$reader.Close()
$zip.Dispose()
# Analys file XML
[xml]$xmlContent = $contentXml
# Read text XML
$textContent = $xmlContent.'document-content'.InnerText
$n = 0
foreach ($pattern in $patterns) {
$pattern = $pattern -replace '\\b', ''
if ($textContent -match $pattern) {
if ($n -le '2') {
$n++
$result = [PSCustomObject]@{
FilePath = $filePath
Pattern = $pattern
Reason = "at least " + $n + " characters found"
}
$results = $result
}
}
}
$results
}
function Get-Pdfcontent {
param (
[string]$filepath,
[string[]]$patterns
)
$results = @()
Import-Module PSWritePDF
try {
$text = (Convert-PDFToText -FilePath $filepath) -join "`n"
$n = 0
foreach ($pattern in $passwordPatterns) {
if ($text -match $pattern) {
if ($n -le '2') {
$n++
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = $pattern
Reason = "at least " + $n + " characters found"
}
$results = $result
} else { break }
}
}
}
catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'error'
Reason = $_.Exception.Message
}
$results = $result
}
$results
}
function Get-Xmlcontent {
param (
[string]$filepath,
[string[]]$patterns
)
$results = @()
$xmlContent = Get-Content -Path $filepath -Raw
if ($xmlContent -match 'cpassword') {
$xml = [xml]$xmlContent
# Check for cpassword
$cpasswords = @()
if ($xml.Groups.User) {
$cpasswords = $xml | Select-Xml "/Groups/User/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
} elseif ($xml.NTServices.NTService) {
$cpasswords = $xml | Select-Xml "/NTServices/NTService/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
} elseif ($xml.ScheduledTasks.Task) {
$cpasswords = $xml | Select-Xml "/ScheduledTasks/Task/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
} elseif ($xml.DataSources.DataSource) {
$cpasswords = $xml | Select-Xml "/DataSources/DataSource/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
} elseif ($xml.Printers.SharedPrinter) {
$cpasswords = $xml | Select-Xml "/Printers/SharedPrinter/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
} elseif ($xml.Drives.Drive) {
$cpasswords = $xml | Select-Xml "/Drives/Drive/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
}
if ($cpasswords) {
$result = [PSCustomObject]@{
FilePath = $filepath
Pattern = 'cpassword'
Reason = $cpasswords
}
$results += $result
}
}
elseif ($xmlContent -match 'DefaultUserName') {
$xml = [xml]$xmlContent
# Check for AutoLogon
$userName = ""
$password = ""
foreach ($registry in $xml.RegistrySettings.Registry) {
if ($registry.Properties.name -eq "DefaultUserName") {
$userName = $registry.Properties.value
}
if ($registry.Properties.name -eq "DefaultPassword") {
$password = $registry.Properties.value
}
}
$result = [PSCustomObject]@{
FilePath = $filepath
Pattern = 'AutoLogon'
Reason = "$userName : $password"
}
$results += $result
}
else {
$xml = [xml]$xmlContent
foreach ($pattern in $patterns) {
$findmatches = $xmlContent | Select-String -Pattern $pattern
foreach ($match in $findmatches) {
switch ($pattern) {
'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b' { $pattern = 'IPv4' }
'\b[a-fA-F0-9]{32}\b' { $pattern = 'MD5' }
'\b[a-fA-F0-9]{40}\b' { $pattern = 'SHA-1' }
'\b[a-fA-F0-9]{64}\b' { $pattern = 'SHA-256' }
default {
switch -Wildcard ($pattern) {
'net *' { $pattern = 'Commande Net User' }
default { $pattern = $pattern }
}
}
}
$result = [PSCustomObject]@{
FilePath = $filepath
Pattern = $pattern
Reason = $match.Matches.Value
}
$results += $result
}
}
}
$results
}
function Get-Executablescontent {
param (
[string]$filepath
)
$results = @()
if ($filepath -notlike '*.jar') {
$signature = Get-AuthenticodeSignature -FilePath $filepath
if ($signature.Status -ne 'Valid') {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = "NotSigned"
Reason = 'File is Not Signed'
}
$results = $result
}
} else {
$isSigned = $false
try {
$zip = [System.IO.Compression.ZipFile]::OpenRead($filepath)
foreach ($entry in $zip.Entries) {
if ($entry.FullName -like "META-INF/*.SF") {
$isSigned = $true
break
}
}
$zip.Dispose()
} catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'error'
Reason = $_.Exception.Message
}
$results = $result
}
if (!$isSigned) {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = "NotSigned"
Reason = "Jar file not signed"
}
$results = $result
}
}
$results
}
function Get-Zipprotectedbypass {
param (
[string]$filepath,
[string]$zipinstalled
)
$extension = [System.IO.Path]::GetExtension($filePath).TrimStart('.')
if ($extension -eq "zip" ) {
try {
$zip = [System.IO.Compression.ZipFile]::OpenRead($filepath)
foreach ($entry in $zip.Entries) {
$stream = $entry.Open()
[byte[]]$buffer = New-Object byte[] 10
$stream.Read($buffer, 0, $buffer.Length) | Out-Null
$stream.Close()
break
}
$zip.Dispose()
return $null
}
catch {
if ($_.Exception.Message -match "(Read|Block|Password|Encrypted)") {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Zip protected'
Reason = 'File protected by password'
}
return $result
} else {
Write-Host "Erreur inattendue : $_"
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Zip check error'
Reason = 'Error to read zip : $_'
}
return $result
}
}
} elseif ($zipinstalled) {
$sevenZipPath = $zipinstalled + "7z.exe"
$output = & "$sevenZipPath" t "$filepath" -pBadPasswordConf 2>&1
if ($output -match "Wrong password") {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Zip protected'
Reason = 'File protected by password'
}
return $result
}
}
}
function Get-Requiredcheckcontent {
param (
[string]$filepath
)
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'check required'
Reason = 'Binary does not match'
}
return $result
}
function Get-CertifsContent {
param (
[string]$filePath
)
$results = @()
try {
# Try to load certificat with class .NET X509Certificate2
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($filePath)
if (!$cert.Thumbprint) { $result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Certificate Empty'
Reason = 'Certificate without Thumbprint'
}
$results = $result }
if ($cert.PrivateKey) { $result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Certificate private key'
Reason = 'certificate with exportable private key'
}
$results += $result }
$cert.Dispose()
}
catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Protected Certificate'
Reason = ($_.Exception.Message).split(":").split("`n")[1].Trim()
}
$results = $result
}
return $results
}
function Get-P7bCertContent {
param (
[string]$filePath
)
$results = @()
try {
# Create certificate collection contenant P7B ou P7C
$certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$certCollection.Import($filePath)
# browse all certificate present in P7B/P7C
foreach ($cert in $certCollection) {
if (!$cert.Thumbprint) {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Certificate Empty'
Reason = 'Certificate without Thumbprint'
}
$results += $result
}
if ($cert.PrivateKey) {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Certificate private key'
Reason = 'certificate with exportable private key'
}
$results += $result
}
$cert.Dispose()
}
}
catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Protected Certificate'
Reason = $_.Exception.Message
}
$results = $result
}
return $results
}
function Get-HiddenFilesInImage {
param (
[string]$filePath
)
$fileInfo = Get-Item $filePath
$fileSizeMB = [math]::Round($fileInfo.Length / 1MB, 2)
# Skip file more than 4 Mo
if ($fileSizeMB -gt 4) {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Large size'
Reason = "File ignored: (size: $fileSizeMB MB)"
}
return $result
}
try {
# read binary and convert file to Hexa
$fileBytes = [System.IO.File]::ReadAllBytes($filePath)
$fileHex = [BitConverter]::ToString($fileBytes) -replace '-'
$magicNumbers = [ordered]@{
"MSI" = "D0CF11E0A1B11AE1" # MSI or office
"RAR" = "526172211A0700"; # RAR file
"ZIP" = "504B0304"; # ZIP file
"7z" = "377ABCAF271C"; # 7z file
"EXE" = "4D5A"; # EXE file (MZ header)
}
foreach ($key in $magicNumbers.Keys) {
$magicNumber = $magicNumbers[$key]
$currentIndex = 0
if ($fileHex -match $magicNumber) {
if ($key -eq "EXE") {
while ($fileHex.IndexOf($magicNumber, $currentIndex) -ne -1) {
$startIndex = $fileHex.IndexOf($magicNumber, $currentIndex)
# Extract the part after the Magic Number (limited to 400 bytes after)
$remainingHex = $fileHex.Substring($startIndex + $magicNumber.Length, [Math]::Min(200 * 2, $fileHex.Length - ($startIndex + $magicNumber.Length)))
# Check for the presence of the special string "0000004000" in this range
if ($remainingHex -match "0000004000") {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Suspicious Image'
Reason = "EXE file with '0000004000' string detected"
}
return $result
}
# Continue the search from the next index
$currentIndex = $startIndex + $magicNumber.Length
}
}
elseif ($key -eq "ZIP") {
# Find the index where the ZIP file starts
$startIndex = $fileHex.IndexOf($magicNumber, $currentIndex) / 2 # Divide by 2 because each hexadecimal represents 2 characters
# Extract the ZIP bytes starting from this index
$zipBytes = $fileBytes[$startIndex..($fileBytes.Length - 1)]
$tempDir = [System.IO.Path]::GetTempPath()
$fileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($filePath)
$tempZipPath = [System.IO.Path]::Combine($tempDir, "$fileNameWithoutExtension.zip")
[System.IO.File]::WriteAllBytes($tempZipPath, $zipBytes)
# Read the ZIP file and list the files
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($tempZipPath)
# List the files inside the ZIP
$fileNames = $zip.Entries | Select-Object -ExpandProperty FullName
$fileNames | ForEach-Object { Write-Host "File in ZIP: $_" }
$zip.Dispose()
# Delete the temporary file
Remove-Item $tempZipPath
# Return the result
$result = [PSCustomObject]@{
FilePath = $filePath
Pattern = 'Suspicious Image'
Reason = "ZIP detected in pictures. Containing: $($fileNames -join ', ')"
}
return $result
}
else {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Suspicious Image'
Reason = "File $key detected in the image"
}
return $result
}
}
}
}
catch {
$result = [PSCustomObject]@{
FilePath = $filepath
pattern = 'Error'
Reason = "Details : $_"
}
return $result
}
}
#endregion FonctionDetect
# Add other functions for different file types...
function Get-CompressedFileType {
param (
[string]$filePath,
[object[]]$detectedType
)
# More check fot DOCX, XLSX, ODT, ODS ou JAR PPTX zip
if ($detectedType -contains "docx" -or $detectedType -contains "jar") {
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($filePath)
$fileNames = $zip.Entries | Select-Object -ExpandProperty FullName
if ($fileNames -contains "word/document.xml") {
$detectedType = "docx"
}
elseif ($fileNames -contains "xl/workbook.xml") {
$detectedType = "xlsx"
}
elseif ($fileNames -contains "ppt/presentation.xml") {
$detectedType = "pptx"
}
elseif ($fileNames -contains "visio/document.xml") {
$detectedType = "vsdx"
}
elseif ($fileNames -contains "content.xml") {
$mimetypeEntry = $zip.Entries | Where-Object { $_.FullName -eq "mimetype" }
if ($mimetypeEntry -ne $null) {
$reader = [System.IO.StreamReader]::new($mimetypeEntry.Open())
$mimetype = $reader.ReadToEnd()
$reader.Close()
switch ($mimetype) {
"application/vnd.oasis.opendocument.spreadsheet" {
$detectedType = "ods"
}
"application/vnd.oasis.opendocument.text" {
$detectedType = "odt"
}
"application/vnd.oasis.opendocument.presentation" {
$detectedType = "odp"
}
"application/vnd.oasis.opendocument.text-template" {
$detectedType = "ott"
}
}
}
}
elseif ($fileNames -contains "META-INF/MANIFEST.MF") {
$detectedType = "jar"
}
else { $detectedType = "others" }
$zip.Dispose()
}
catch {
$detectedType = "requires_check"
}
}
elseif ($detectedType -contains "doc") {
$a = [System.IO.File]::ReadAllBytes($filePath)
$content = [System.Text.Encoding]::ASCII.GetString($a)
if ($content.Contains("Word.Document")) {
$detectedType = "doc"
} elseif ($content.Contains("MSI") -or $content.Contains("Installer")) {
$detectedType = "msi"
} elseif ($content.Contains("Excel") ) {
$detectedType = "xls"
} elseif ($content.Contains("PowerPoint")) {
$detectedType = "ppt"
} elseif ($content.Contains("Microsoft Visio")) {
$detectedType = "vsd"
} else {
#check for db files
$offsetBytes = [System.IO.File]::ReadAllBytes($filePath)[1024..1050]
$offsetAscii = [System.Text.Encoding]::ASCII.GetString($offsetBytes).Trim()
$filteredAscii = ($offsetAscii -split '').Where{ $_ -match '[A-Za-z ]' } -join ''
if ($filteredAscii -replace '\s+', ' ' -eq "Root Entry") {
$detectedType = "db"
}
else {
$detectedType = "others"
}
}
}
return $detectedType
}
function Get-FileType {
param (
[string]$filePath,
[object]$jsonContent
)
$detectedType = "others"
$extension = [System.IO.Path]::GetExtension($filePath).TrimStart('.')
$fileHeaderHex = [System.IO.File]::ReadAllBytes($filePath)[0..16] | ForEach-Object { "{0:X2}" -f $_ }
$fileHeaderHex = ($fileHeaderHex -join '').Trim()
if ($fileHeaderHex.Length -eq 0) {
return "empty"
}
$matchFound = $false
foreach ($entry in $jsonContent.magic_numbers) {
if ($matchFound) { break }
foreach ($expectedMagic in $entry.magic) {
if ($matchFound) { break }
if ($expectedMagic.Length -le $fileHeaderHex.Length) {
$difference = Compare-Object -ReferenceObject $expectedMagic -DifferenceObject ($fileHeaderHex.Substring(0, $expectedMagic.Length)) -SyncWindow 0
if ($difference.Count -eq 0) {
if ($entry.offset) {
foreach ($offsetItem in $entry.offset) {
$offsetPosition = $expectedOffsetValue = $null
$offsetPosition = $offsetItem[0]
$expectedOffsetValue = $offsetItem[1]
$lastpostition = $offsetPosition + ($expectedOffsetValue.Length/2)-1
$CustomfileHeaderHex = [System.IO.File]::ReadAllBytes($filePath)[$offsetPosition..$lastpostition] | ForEach-Object { "{0:X2}" -f $_ }
$specificBytes = ($CustomfileHeaderHex -join '').Trim()
if ($specificBytes -eq $expectedOffsetValue) {
if ($extension -notin $entry.extensions) {
$detectedType = 'requires_check'
} else {
$detectedType = $extension
}
$matchFound = $true
break
}
}
}
else {
if ($extension -notin $entry.extensions) {
$detectedType = 'requires_check'
}
else {
if ($entry.extensions -contains "docx" -or $entry.extensions -contains "doc") {
$detectedType = Get-CompressedFileType -filePath $filePath -detectedType $entry.extensions
}
if ($detectedType -eq "others" -and $extension -in $entry.extensions) {
$detectedType = $extension
} elseif ($detectedType -ne $extension -and $detectedType -ne "others") {
$detectedType = 'requires_check'
}
}
$matchFound = $true
break
}
}
}
}
}
if ($detectedType -eq 'others' -and $extension -in $jsonContent.magic_numbers.extensions) {
$detectedType = 'requires_check'
}
if ($detectedType -eq "others") {
$firstLine = Get-Content -Path $filePath -TotalCount 1
if ($firstLine -match '^<\?xml') {
$detectedType = "xml"
}
}
return $detectedType
}