利用 dnSpy 修复 offvis 中的 cases.dll 的 FAT 和 MiniFAT 的定位逻辑
将
this.FAT = new List<SECTOR>();
ulong num7;
if (num2 * (ulong)this.OLESSHeader.NumFatSects.Value.Value > (Data.Length - Data.CurrentPosition) / num * num2)
{
num7 = (Data.Length - Data.CurrentPosition) / num * num2;
}
else
{
num7 = num2 * (ulong)this.OLESSHeader.NumFatSects.Value.Value;
}
ulong num8 = 0UL;
while (num8 < num7 && Data.HasDataLeftToRead)
{
SECTOR sector3 = new SECTOR(Data);
this.FAT.Add(sector3);
if (sector3.SectorNumber.Value != null)
{
uint? value4 = sector3.SectorNumber.Value;
uint num9 = 4294967290U;
if (value4.GetValueOrDefault() <= num9 & value4 != null)
{
uint? value5 = sector3.SectorNumber.Value;
long num10 = (long)this.FAT.Count;
if ((ulong)value5.GetValueOrDefault() != (ulong)num10 || value5 == null)
{
base.AddParsingNote(ParsingNoteType.Error, "This OLESS file has not been de-fragmented - this file may fail to parse as expected.");
}
}
}
num8 += 1UL;
}

替换为
List<SECTOR> list = new List<SECTOR>();
for (int i = 0; i < this.OLESSHeader.DiFat.Count; i++)
{
if ((ulong?)this.OLESSHeader.DiFat[i].SectorNumber.Value < (ulong?)4294967292uL)
{
list.Add(this.OLESSHeader.DiFat[i]);
}
}
if (this.DiFAT != null)
{
list.AddRange(this.DiFAT);
}
// 修正:2. 遍历索引列表,对每个扇区进行独立的 Seek 和读取
this.FAT = new List<SECTOR>();
foreach (SECTOR item in list)
{
if (!Data.Seek(GetSectorOffset(item.SectorNumber.Value.Value)))
{
AddParsingNote(ParsingNoteType.Error, "Failed to seek to FAT sector " + item.SectorNumber.Value.Value);
continue;
}
for (ulong num7 = 0uL; num7 < num2; num7++)
{
if (!Data.HasDataLeftToRead)
{
break;
}
this.FAT.Add(new SECTOR(Data));
}
}

不要漏掉常量替换

修复 Mini Fat
uint? value5 = this.OLESSHeader.MiniFatSect1.SectorNumber.Value;
if ((ulong)value5.GetValueOrDefault() < (ulong)-4 && value5 != null)
{
Data.Seek(this.GetSectorOffset(this.OLESSHeader.MiniFatSect1.SectorNumber.Value.Value));
ulong num9;
if (num2 * (ulong)this.OLESSHeader.NumMiniFatSects.Value.Value > (Data.Length - Data.CurrentPosition) / num * num2)
{
num9 = (Data.Length - Data.CurrentPosition) / num * num2;
}
else
{
num9 = num2 * (ulong)this.OLESSHeader.NumMiniFatSects.Value.Value;
}
this.MiniFAT = new List<SECTOR>();
ulong num10 = 0UL;
while (num10 < num9 && Data.HasDataLeftToRead)
{
this.MiniFAT.Add(new SECTOR(Data));
num10 += 1UL;
}
}
修改为
uint? value5 = this.OLESSHeader.MiniFatSect1.SectorNumber.Value;
if ((ulong?)value5.GetValueOrDefault() < (ulong?)4294967292uL)
{
this.MiniFAT = new List<SECTOR>();
// 1. 获取MiniFAT流的第一个扇区号
uint? sectorNumber = this.OLESSHeader.MiniFatSect1.SectorNumber.Value;
// 2. 开始循环,只要当前扇区号有效,就一直追踪
while (sectorNumber.HasValue && sectorNumber.Value < 4294967292u)
{
// 3. (正确) 对每一个MiniFAT扇区都执行Seek操作
if (!Data.Seek(GetSectorOffset(sectorNumber.Value)))
{
AddParsingNote(ParsingNoteType.Error, "Failed to seek to MiniFAT sector " + sectorNumber.Value);
break;
}
// 4. 读取当前扇区内的所有条目
for (ulong i = 0; i < num2; i++)
{
if (!Data.HasDataLeftToRead) break;
this.MiniFAT.Add(new SECTOR(Data));
}
// 安全检查,防止索引越界
if (sectorNumber.Value >= this.FAT.Count)
{
AddParsingNote(ParsingNoteType.Error, "MiniFAT sector chain is invalid, pointing to a sector beyond the FAT's size.");
break;
}
// 5. (正确) 查询我们已经正确构建的主FAT,找到下一个MiniFAT扇区的索引
sectorNumber = this.FAT[(int)sectorNumber.Value].SectorNumber.Value;
}
}

这里提供一个修改后的Cases.dll
浙公网安备 33010602011771号