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

ArgumentNullException in AT3 preview 3 #106

Open
gabriel-so opened this issue Apr 27, 2023 · 7 comments
Open

ArgumentNullException in AT3 preview 3 #106

gabriel-so opened this issue Apr 27, 2023 · 7 comments

Comments

@gabriel-so
Copy link

Hi, I'm using the preview 3 of the AT3, so far bundle reading/writing is neat!

But now I'm working on reading/writing assets files in an il2cpp game, and I'm getting an ArgumentNullException when getting the baseField for a MonoBehavior.

I followed the pages from the wiki correctly, loaded the tpk file (got it from the latest build in the link mentioned in the wiki), then used the Cpp2Il package and loaded it into the AssetsManager.

Here's the relevant part of the stack trace:

   in System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
   in LibCpp2IL.Metadata.Il2CppMetadata.GetCustomAttributeData(Il2CppImageDefinition imageDef, Int32 customAttributeIndex, UInt32 token)
   in AssetsTools.NET.Cpp2IL.Cpp2IlTempGenerator.GetAttributeNamesOnField(Il2CppImageDefinition image, Il2CppFieldDefinition field)
   in AssetsTools.NET.Cpp2IL.Cpp2IlTempGenerator.GetAcceptableFields(TypeDefWithSelfRef typeDef, Int32 availableDepth)
   in AssetsTools.NET.Cpp2IL.Cpp2IlTempGenerator.ReadTypes(TypeDefWithSelfRef type, Int32 availableDepth)
   in AssetsTools.NET.Cpp2IL.Cpp2IlTempGenerator.RecursiveTypeLoad(TypeDefWithSelfRef type, List`1 templateFields, Int32 availableDepth, Boolean isRecursiveCall)
   in AssetsTools.NET.Cpp2IL.Cpp2IlTempGenerator.GetTemplateField(AssetTypeTemplateField baseField, String assemblyName, String nameSpace, String className, UnityVersion unityVersion)
   in AssetsTools.NET.Extra.AssetsManager.GetTemplateBaseField(AssetsFileInstance inst, AssetsFileReader reader, Int64 absByteStart, Int32 typeId, UInt16 scriptIndex, AssetReadFlags readFlags)
   in AssetsTools.NET.Extra.AssetsManager.GetTemplateBaseField(AssetsFileInstance inst, AssetFileInfo info, AssetReadFlags readFlags)
   in AssetsTools.NET.Extra.AssetsManager.GetBaseField(AssetsFileInstance inst, AssetFileInfo info, AssetReadFlags readFlags)

I tried to debug it but no success so far.

@nesrak1
Copy link
Owner

nesrak1 commented Apr 27, 2023

This exception is in LibCpp2IL so the issue probably lies there and not something in AssetsTools.NET. I'm planning on upgrading the Cpp2IL version soon so that it (hopefully) fixes problems like these, but the nightly Cpp2IL versions aren't on nuget so I can't just click update and call it a day.

@gabriel-so
Copy link
Author

Thanks for the answer, I'm gonna try and see if I get some workaround in the meantime.

@nesrak1
Copy link
Owner

nesrak1 commented Apr 28, 2023

For now, you can use cpp2il or il2cppdumper through command line to produce dummy dlls. Then you can use the MonoCecil package on that directory.

@gabriel-so
Copy link
Author

I followed your suggestion but in a slightly different way. I'm using the cpp2il c# api to generate the dummy dlls during runtime of my application, and then I load them with the MonoCecilTempGenerator. But then I get an EndOfStreamException when trying to get the basefield:

in System.IO.__Error.EndOfFile()
in System.IO.BinaryReader.FillBuffer(Int32 numBytes)
in System.IO.BinaryReader.ReadInt32()
in AssetsTools.NET.AssetTypeTemplateField.ReadType(AssetsFileReader reader, AssetTypeValueField valueField, RefTypeManager refMan)
in AssetsTools.NET.AssetTypeTemplateField.ReadType(AssetsFileReader reader, AssetTypeValueField valueField, RefTypeManager refMan)
in AssetsTools.NET.AssetTypeTemplateField.ReadType(AssetsFileReader reader, AssetTypeValueField valueField, RefTypeManager refMan)
in AssetsTools.NET.AssetTypeTemplateField.MakeValue(AssetsFileReader reader, RefTypeManager refMan)
in AssetsTools.NET.Extra.AssetsManager.GetBaseField(AssetsFileInstance inst, AssetFileInfo info, AssetReadFlags readFlags)

What is weird though, is that UABEA works fine with the DLLs that were generated by my cpp2il call. And as I saw in UABEA's source code, it's also using the MonoCecil package to do so. What am I missing? Is there any trick?

@gabriel-so gabriel-so reopened this May 2, 2023
@nesrak1
Copy link
Owner

nesrak1 commented May 2, 2023

There shouldn't be any trick. It should work the same since UABEA is basically using preview 3 AT.NET as well. (That's assuming you toggled CPP2IL off in the main window.) You could try adding a print statement to ReadType to see what fields it's trying to read and compare that with UABEA. You might find somehow that UABEA read more/less fields than what you see in AT.NET.

@gabriel-so
Copy link
Author

Thanks for the tips! I was able to find out that my code was missing to tell cpp2il to restore custom attributes, which caused several fields not being read into the templates. Now this workflow with cpp2il generation works fine!

@Albeoris
Copy link

For now, you can use cpp2il or il2cppdumper through command line to produce dummy dlls. Then you can use the MonoCecil package on that directory.

Thank you! Works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants