Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: SerializedFile writing alignment issues + missing data #1276

Closed
DaXcess opened this issue Mar 30, 2024 · 2 comments · Fixed by #1365
Closed

[Bug]: SerializedFile writing alignment issues + missing data #1276

DaXcess opened this issue Mar 30, 2024 · 2 comments · Fixed by #1365
Labels
bug Something isn't working

Comments

@DaXcess
Copy link

DaXcess commented Mar 30, 2024

Are you on the latest version of AssetRipper?

Yes, I'm on the latest alpha-build of AssetRipper.

Which release are you using?

Windows x64

Which game did this occur on?

No response

Which Unity version did this occur on?

2022.3.9f1

Is the game Mono or IL2Cpp?

Mono

Describe the issue.

I've been using AssetRipper as a library to read/write certain assets (mostly configuration) within a game, and I noticed that the resulting files came out corrupt/invalid.

Misalignment issues

To be specific: there are alignment issues within the SerializedFile class that misaligns data when writing. One place it fails is at GetNewObjectInfoArray:

static ObjectInfo[] GetNewObjectInfoArray(ObjectInfo[]? objects)
{
if (objects is null)
{
return Array.Empty<ObjectInfo>();
}
ObjectInfo[] newObjects = new ObjectInfo[objects.Length];
Array.Copy(objects, newObjects, objects.Length);
long byteStart = 0;
for (int i = 0; i < newObjects.Length; i++)
{
ref ObjectInfo objectInfo = ref newObjects[i];
objectInfo.ByteStart = byteStart;
objectInfo.ByteSize = objectInfo.ObjectData?.Length ?? 0;
byteStart += objectInfo.ByteSize;
byteStart += 3 - (byteStart % 4);//Object data must always be aligned.
}
return newObjects;
}

where the following code:

byteStart += 3 - (byteStart % 4);

should actually be

byteStart = (byteStart + 7) & ~7;

since object data must be aligned on an 8 byte boundary.

Another thing that is now misaligned is the object data written by WriteObjectData:

static void WriteObjectData(SerializedWriter writer, ObjectInfo[] objects)
{
foreach (ObjectInfo objectInfo in objects)
{
if (objectInfo.ObjectData is not null)
{
writer.Write(objectInfo.ObjectData);
}
AlignStream(writer);
}
}

Since AlignStream only aligns on 4 byte boundaries, even though object data should be aligned at 8 byte boundaries.

Lastly, the last misalignment happens right before writing the object data. After inspecting numerous SerializedFiles it appears that the first object must be aligned on a 16 byte boundary, making the following code not aligned properly:

AlignStream(writer);//Object data must always be aligned.

Missing ScriptTypes

When reading a SerializedFile, one of the types of data that is being read are the ScriptTypes. The reading is going through normally, however when writing a SerializedFile, this property is forgotten and not written to the resulting output, causing it to emit corrupt files.

When fixing this on my end it all seems to work fine, however they have only been tested on my specific Unity version, as that was the one I was using AssetRipper for.

Relevant log output

No response

@DaXcess DaXcess added the bug Something isn't working label Mar 30, 2024
Copy link

Thank you for submitting your first issue here. Please be sure you have uploaded your AssetRipper.log file. It is in the same folder as the exe file. :)

@ds5678
Copy link
Collaborator

ds5678 commented Mar 30, 2024

I'm honestly surprised that it worked at all for you. Writing these files was a work in progress feature that got deprioritized. 😅

In regards to the 8-byte alignment, make a pull request. I also want details about how you know that 8 is required instead of 4.

The missing (unimplemented) script types should be a separate issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants