利用 dnSpy 修复 offvis 中的 cases.dll 的 DIFAT 的定位逻辑

和修复目录的逻辑类似,修复 DIFAT 数组不能正确反应非连续的 DIFAT 扇区的情况(代码在使用 DIFAT(用于定位 FAT 表本身的索引)时, 假设了 DIFAT 扇区是连续的,没有进行 Seek。)

Data.Seek(this.GetSectorOffset(this.OLESSHeader.DifatSect1.SectorNumber.Value.Value));
		this.DiFAT = new List<SECTOR>();
		this.DiFATSectors = new List<SECTOR>();
		uint num4 = this.OLESSHeader.DiFat[108].SectorNumber.Value.GetValueOrDefault(0U);

		for (uint num5 = 0U; num5 < this.OLESSHeader.NumDifatSects.Value.GetValueOrDefault(0U); num5 += 1U)
		{
			for (ulong num6 = 0UL; num6 < num2 - 1UL; num6 += 1UL)
			{
				SECTOR sector = new SECTOR(Data);
				this.DiFAT.Add(sector);
				num4 += 1U;
				if (sector.SectorNumber.Value != null)
				{
					uint? value3 = sector.SectorNumber.Value;
					uint num7 = 4294967290U;
					if (value3.GetValueOrDefault() <= num7 & value3 != null)
					{
						value3 = sector.SectorNumber.Value;
						num7 = num4;
						if (!(value3.GetValueOrDefault() == num7 & value3 != null))
						{
							base.AddParsingNote(ParsingNoteType.Error, "This OLESS file has not been de-fragmented - this file may fail to parse as expected.");
						}
					}
				}
			}
			SECTOR sector2 = new SECTOR(Data);
			this.DiFATSectors.Add(sector2);
			if (sector2.SectorNumber.Value != null)
			{
				uint? value4 = sector2.SectorNumber.Value;
				uint num8 = 4294967290U;
				if (value4.GetValueOrDefault() <= num8 & value4 != null)
				{
					value4 = sector2.SectorNumber.Value;
					num8 = this.OLESSHeader.DifatSect1.SectorNumber.Value.GetValueOrDefault(0U) + num5 + 1U;
					if (!(value4.GetValueOrDefault() == num8 & value4 != null))
					{
						base.AddParsingNote(ParsingNoteType.Error, "This OLESS file has not been de-fragmented - this file may fail to parse as expected.");
					}
				}
			}
		}

也有可能是类似下面的

Data.Seek(GetSectorOffset(OLESSHeader.DifatSect1.SectorNumber.Value.Value));
				DiFAT = new List<SECTOR>();
				DiFATSectors = new List<SECTOR>();
				uint num4 = OLESSHeader.DiFat[108].SectorNumber.Value ?? 0;
				for (uint num5 = 0u; num5 < (OLESSHeader.NumDifatSects.Value ?? 0); num5++)
				{
					for (ulong num6 = 0uL; num6 < num2 - 1; num6++)
					{
						SECTOR sECTOR = new SECTOR(Data);
						DiFAT.Add(sECTOR);
						num4++;
						if (sECTOR.SectorNumber.Value.HasValue)
						{
							uint? value = sECTOR.SectorNumber.Value;
							if (value.GetValueOrDefault() <= 4294967290u && value.HasValue && sECTOR.SectorNumber.Value != num4)
							{
								AddParsingNote(ParsingNoteType.Error, "This OLESS file has not been de-fragmented - this file may fail to parse as expected.");
							}
						}
					}
					SECTOR sECTOR2 = new SECTOR(Data);
					DiFATSectors.Add(sECTOR2);
					if (sECTOR2.SectorNumber.Value.HasValue)
					{
						uint? value2 = sECTOR2.SectorNumber.Value;
						if (value2.GetValueOrDefault() <= 4294967290u && value2.HasValue && sECTOR2.SectorNumber.Value != (OLESSHeader.DifatSect1.SectorNumber.Value ?? 0) + num5 + 1)
						{
							AddParsingNote(ParsingNoteType.Error, "This OLESS file has not been de-fragmented - this file may fail to parse as expected.");
						}
					}
				}

image
for 修改为 while

uint num5 = this.OLESSHeader.DifatSect1.SectorNumber.Value.GetValueOrDefault(0U);
while (num5 <4294967292u)
{
	if (!Data.Seek(GetSectorOffset(num5)))
	{
		AddParsingNote(ParsingNoteType.Error, "Failed to seek to DIFAT sector " + num5 + ". This file may need to be defragmented or it may be corrupt.");
		break;
	}
	//num2通常是128,即 512/4
	for (ulong num6 = 0UL; num6 < num2-1UL ;num6+=1UL)
	{
		SECTOR sector =new SECTOR(Data);
		this.DiFAT.Add(sector);
		num4+=1U;
		if (sector.SectorNumber.Value.HasValue)
		{ 
			uint? value3 = sector.SectorNumber.Value;
			if (value3.GetValueOrDefault() <= 4294967290u && value3.HasValue && sector.SectorNumber.Value != num4)
				{
					AddParsingNote(ParsingNoteType.Error, "This OLESS file has not been de-fragmented - this file may fail to parse as expected.");
				}

		}

	}
/*
Data 是一个 DataInByteArray 类型的对象。您可以把它理解为一个文件流的封装器。

来源: 在 OLESSDataFile 类的构造函数 public OLESSDataFile(DataInByteArray Data) 中,Data 作为参数被传入。它包含了被解析文件的全部字节内容。
 功能: 这个对象内部维护着一个指向当前读取位置的指针。当你调用 new SECTOR(Data) 时,SECTOR 的构造函数会从 Data 对象的当前指针位置读取4个字节,并将其解析为一个32位的无符号整数(即扇区索引)。读取完成后,Data 对象内部的指针会自动向前移动4个字节。
 核心作用: 整个解析过程都共享并操作这同一个 Data 对象,通过 Seek 来跳转,通过 Read 来获取数据,模拟了对文件流的读写操作。
 被更新为当前DIFAT扇区最后4个字节所指向的下一个DIFAT扇区的索引或为终止符(如 0xFFFFFFFE)
 */
	SECTOR sector2 = new SECTOR(Data);
	this.DiFATSectors.Add(sector2);
    num5 = sector2.SectorNumber.Value.Value;

}

image

下一篇文章修复 FAT 的。

posted @ 2025-07-07 18:40  geyee  阅读(5)  评论(0)    收藏  举报