查看原文
其他

Win10 又带着Bug来了!部分 FLAC 格式音乐文件损坏,已发布紧急更新修复

小雪 看雪学苑 2022-05-03

他来了,他来了,他又带着bug走来了!

5月底,微软发布的一份最新文档,称修复了一个令众多用户苦恼的问题。Win10 文件管理器中存在一个 Bug,可使部分 FLAC 格式音频文件损坏。(好家伙,无损变全损,这我可受不住)

微软称,在 Win10 2004 及以上版本中,如果使用文件管理器修改 FLAC 音频文件的元数据,比如标题、艺术家或者其他音频元数据,将使 FLAC 文件损坏,无法播放。

部分 FLAC 文件开头会包含 ID3 帧头,其中包含歌手、标题、专辑名称、年代、风格等信息。


而在 Win10 2004 及以上版本中,文件资源管理器会忽略 ID3 帧头,因为它默认判定 FLAC 文件使用 4 字节 fLaC 开头。因此当用户使用文件资源管理器修改 FLAC 文件的元数据时,就会把 ID3 帧头覆盖掉,从而破坏原有的 FLAC 文件结构,使音乐播放器无法正常识别。

该bug影响多个Windows 10版本(Home、Pro、Enterprise、Education、Pro Education和Pro for工作站)和版本2004和版本20H2。

微软已针对该 Bug 发布了紧急修复更新,在 KB5003214 更新中,微软确认已修复该问题,大家安装即可。



1. 打开notepad,并输入下方内容
# Copyright 2021 Microsoft
# This script will repair a FLAC file that has been corrupted by Media Foundation in reference to KB5003430.
# Refer to KB5003430 for further information
param(
[parameter(Mandatory=$true,
HelpMessage="The path to the FLAC file that has been corrupted by Media Foundation",
ValueFromRemainingArguments=$true)]
[ValidateScript({ -not [String]::IsNullOrEmpty($_) -and (Test-Path $_) })]
[String]$File
)
# We need to back up the current file incase we have any errors
$FileDirectory = Split-Path -Resolve $File
$Filename = Split-Path -Leaf -Resolve $File
$FullPath = Join-Path -Resolve $FileDirectory $Filename
$Filename = [String]::Format("Backup_{0:yyyyMMdd_hhmmss}_{1}", [DateTime]::Now, $Filename)
$BackupLocation = Join-Path $FileDirectory $Filename
Write-Output "Microsoft FLAC Repair Tool. This tool will repair a FLAC audio file that was corrupted when editing its details."
Write-Output "Affected File: $FullPath"
Write-Output "A backup of the file will be made: $BackupLocation"
Write-Output "Do you wish to continue?"
$choice=$host.ui.PromptForChoice("Fixing FLAC Script", "Do you wish to continue", ('&Yes', '&No'), 1)
function ParseStreamInfoMetadataBlock([System.IO.FileStream]$stream)
{
$blockType = $stream.ReadByte()
$lastBlock = ($blockType -shr 7) -ne 0
$blockType = $blockType -band 0x7F
if ($blockType -ne 0)
{
return $false
}
$blockSize = (($stream.ReadByte() -shl 16) -bor ($stream.ReadByte() -shl 8) -bor $stream.ReadByte())
if ($blockSize -lt 34)
{
return $false
}
$minAudioBlockSize = ($stream.ReadByte() -shl 8) -bor $stream.ReadByte()
$maxAudioBlockSize = ($stream.ReadByte() -shl 8) -bor $stream.ReadByte()
if ($minAudioBlockSize -lt 16 -or $maxAudioBlockSize -lt 16)
{
return $false
}
$minFrameSize = (($stream.ReadByte() -shl 16) -bor ($stream.ReadByte() -shl 8) -bor $stream.ReadByte())
$maxFrameSize = (($stream.ReadByte() -shl 16) -bor ($stream.ReadByte() -shl 8) -bor $stream.ReadByte())
$sampleInfo = (($stream.ReadByte() -shl 24) -bor ($stream.ReadByte() -shl 16) -bor ($stream.ReadByte() -shl 8) -bor $stream.ReadByte())
$sampleRate = $sampleInfo -shr 12
$channelCount = (($sampleInfo -shr 9) -band 0x7) + 1
$bitsPerSample = (($sampleInfo -shr 4) -band 0x1F) + 1
[UInt64]$sampleCount = (($stream.ReadByte() -shl 24) -bor ($stream.ReadByte() -shl 16) -bor ($stream.ReadByte() -shl 8) -bor $stream.ReadByte())
$sampleCount = (([UInt64]$sampleInfo -band 0xF) -shl 32) -bor $sampleCount
$MD5HashBytes = New-Object byte[] 16
$stream.Read($MD5HashBytes, 0, $MD5HashBytes.Length)
$MD5Hash = [Guid]($MD5HashBytes)
if ($sampleRate -eq 0)
{
return $false
}
# Passing these checks means that we likely have a stream info header and can rebuild the file
Write-Output "File Stream Information"
Write-Output "Sample Rate: $sampleRate"
Write-Output "Audio Channels: $channelCount"
Write-Output "Sample Depth: $bitsPerSample"
Write-Output "MD5 Audio Sample Hash: $MD5Hash"
return $true
}
if ($choice -eq 0)
{
Copy-Item $FullPath -Destination $BackupLocation -Force
$stream = [System.IO.File]::Open($FullPath, [System.IO.FileMode]::Open)
$stream.Seek(4, [System.IO.SeekOrigin]::Begin)
while ($stream.ReadByte() -eq 0) {}
# We now need to figure out where a valid FLAC metadata frame begins
# We are likely pointing to the last byte of the size member so we'll seek back 4 bytes and retry
$flacDataStartPosition = $stream.Position - 4
$stream.Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
while (-not(ParseStreamInfoMetadataBlock($stream)))
{
$flacDataStartPosition = $flacDataStartPosition + 1
$stream.Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
}
# Insert the start code
$stream.Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
if (Test-Path "$FullPath.tmp")
{
Remove-Item "$FullPath.tmp"
}
$fixedStream = [System.IO.File]::Open("$FullPath.tmp", [System.IO.FileMode]::CreateNew)
[byte[]]$startCode = [char[]]('f', 'L', 'a', 'C');
$fixedStream.Write($startCode, 0, $startCode.Length)
$stream.CopyTo($fixedStream)
$stream.Close()
$fixedStream.Close()
Move-Item -Force "$FullPath.tmp" $FullPath
}

2. 点击保存,将文件保存为 FixFlacFiles.ps1,保存类型设置为(*.txt)
3. 在Windows资源管理器中找到保存的PowerShell脚本,然后单击使用PowerShell运行」
4. 在弹出的对话框中,输入不可播放的fLAC文件的文件名,然后点击「enter」






推荐文章++++

苹果M1芯片被曝"无害"漏洞

ETC 诈骗又双叒叕来了!老司机速看

黑客攻击来袭,多个日本政府部门的敏感数据泄露

警惕!iOS与macOS设备仍然存在WebKit漏洞!

* 美国研发“无法破解”的芯片,真的无人攻破吗?

新西兰医疗系统遭遇史上最大的网络攻击







公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com




球分享

球点赞

球在看



戳“阅读原文”一起来充电吧!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存