利用 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;
}

image
替换为

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));
    }
}

image
不要漏掉常量替换
image
修复 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;
    }
}

image
这里提供一个修改后的Cases.dll

posted @ 2025-07-07 19:32  geyee  阅读(8)  评论(0)    收藏  举报