Fixed various pointer problems

This commit is contained in:
mm00
2025-03-12 19:56:34 +01:00
parent ba61ea59f9
commit a7337dd1d6

View File

@@ -49,7 +49,14 @@ public class Reader {
/// </summary> /// </summary>
/// <param name="memAddr">memory address in current system endianness</param> /// <param name="memAddr">memory address in current system endianness</param>
/// <returns>A <see cref="Kaitai.BlendFile.FileBlock"/> object</returns> /// <returns>A <see cref="Kaitai.BlendFile.FileBlock"/> object</returns>
public FileBlock? GetBlock(long memAddr) => memBlocks.SkipWhile(x => x.Key < memAddr).FirstOrDefault().Value; public FileBlock? GetBlock(long memAddr)
{
var blocks = OrderedBlocks.Where(x =>
memAddr >= x.MemAddr.ToPointer() && memAddr < x.MemAddr.ToPointer() + x.LenBody);
return blocks.MaxBy(x => x.LenBody);
}
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="Reader"/> class /// Creates a new instance of the <see cref="Reader"/> class
@@ -59,6 +66,8 @@ public class Reader {
_path = path; _path = path;
} }
public List<FileBlock> OrderedBlocks;
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="Reader"/> class /// Creates a new instance of the <see cref="Reader"/> class
/// </summary> /// </summary>
@@ -82,8 +91,17 @@ public class Reader {
var file = new KaitaiStream(_path); var file = new KaitaiStream(_path);
var blend = new Kaitai.BlendFile(file); var blend = new Kaitai.BlendFile(file);
Console.WriteLine($"Start offset: 0x{blend.Blocks[0].MemAddr.ToPointer():X}");
OrderedBlocks = blend.Blocks.OrderBy(x => x.MemAddr.ToPointer()).ToList();
var startAddr = OrderedBlocks.Skip(1).SkipWhile(x => x.Code != "DNA1").First().MemAddr.ToPointer();
var endAddr = OrderedBlocks.Last().MemAddr.ToPointer();
Console.WriteLine($"Start offset: 0x{startAddr:X}");
Console.WriteLine($"End offset: 0x{endAddr:X}");
Console.WriteLine($"Size in MB: {((endAddr - startAddr) / 1024 / 1024)}");
bool isLe = blend.Hdr.Endian == Endian.Le; bool isLe = blend.Hdr.Endian == Endian.Le;
//TODO: two blocks somehow have the same mem address... this sounds wrong. //TODO: two blocks somehow have the same mem address... this sounds wrong.
blend.Blocks.ForEach(block => memBlocks.TryAdd(block.MemAddr.ToMemAddr(isLe), block)); blend.Blocks.ForEach(block => memBlocks.TryAdd(block.MemAddr.ToMemAddr(isLe), block));
@@ -130,6 +148,9 @@ public class Reader {
// get the pointer value // get the pointer value
var addr = GetBlockFieldDataOffset(obj.Key.Item1, f.GetCustomAttribute<DNAFieldAttribute>()!.OriginalIndex, var addr = GetBlockFieldDataOffset(obj.Key.Item1, f.GetCustomAttribute<DNAFieldAttribute>()!.OriginalIndex,
fieldInfo); fieldInfo);
// dereference the pointer
addr = pointers.GetValueOrDefault(addr);
if (addr == IntPtr.Zero) continue; // null pointer
// get the object that the pointer is pointing to if we've already converted it // get the object that the pointer is pointing to if we've already converted it
var newobj = objects.GetValueOrDefault((addr, f.FieldType)); var newobj = objects.GetValueOrDefault((addr, f.FieldType));
if (newobj != null) if (newobj != null)
@@ -140,7 +161,6 @@ public class Reader {
if (newobj != null) { if (newobj != null) {
FillObject(addr, ref newobj, f.FieldType.GetFields()); FillObject(addr, ref newobj, f.FieldType.GetFields());
f.SetValue(obj.Value, newobj); f.SetValue(obj.Value, newobj);
Objects.Add((addr, f.FieldType), newobj);
} // should never happen } // should never happen
else throw new NotSupportedException($"Type \"{f.FieldType}\" is unknown"); else throw new NotSupportedException($"Type \"{f.FieldType}\" is unknown");
} }
@@ -298,6 +318,7 @@ public class Reader {
for (int i = 0; i < arrayAttribute.Size; i += 8) { for (int i = 0; i < arrayAttribute.Size; i += 8) {
var itemData = new byte[8]; var itemData = new byte[8];
Array.Copy(data, i, itemData, 0, 8); Array.Copy(data, i, itemData, 0, 8);
if(itemData.ToPointer() == IntPtr.Zero) continue;
object? cellData = ActivateInstance(type); object? cellData = ActivateInstance(type);
FillObject(itemData.ToPointer(), ref cellData, type.GetFields()); FillObject(itemData.ToPointer(), ref cellData, type.GetFields());