HearthSim / UnityPack

Python deserialization library for Unity3D Asset format
https://hearthsim.info/
MIT License
720 stars 153 forks source link

struct.error: unpack requires a buffer of 3714449519 bytes #92

Open sebastientromp opened 4 years ago

sebastientromp commented 4 years ago

When running unityextract with ./bin/unityextract --audio -o out/audio2 /d/Games/Hearthstone/Data/Win/*.unity3d, I have the following stack trace:

Traceback (most recent call last):
  File "./bin/unityextract", line 159, in <module>
    main()
  File "./bin/unityextract", line 155, in main
    exit(app.run())
  File "./bin/unityextract", line 57, in run
    self.handle_asset(asset)
  File "./bin/unityextract", line 83, in handle_asset
    if obj.type not in self.handle_formats:
  File "C:\Users\Daedin\AppData\Local\Programs\Python\Python36\lib\site-packages\unitypack-0.9.0-py3.6.egg\unitypack\object.py", line 30, in type
    script = self.read()["m_Script"]
  File "C:\Users\Daedin\AppData\Local\Programs\Python\Python36\lib\site-packages\unitypack-0.9.0-py3.6.egg\unitypack\object.py", line 84, in read
    return self.read_value(self.type_tree, BinaryReader(BytesIO(object_buf)))
  File "C:\Users\Daedin\AppData\Local\Programs\Python\Python36\lib\site-packages\unitypack-0.9.0-py3.6.egg\unitypack\object.py", line 149, in read_value
    result[child.name] = self.read_value(child, buf)
  File "C:\Users\Daedin\AppData\Local\Programs\Python\Python36\lib\site-packages\unitypack-0.9.0-py3.6.egg\unitypack\object.py", line 149, in read_value
    result[child.name] = self.read_value(child, buf)
  File "C:\Users\Daedin\AppData\Local\Programs\Python\Python36\lib\site-packages\unitypack-0.9.0-py3.6.egg\unitypack\object.py", line 118, in read_value
    result = buf.read_string(size)
  File "C:\Users\Daedin\AppData\Local\Programs\Python\Python36\lib\site-packages\unitypack-0.9.0-py3.6.egg\unitypack\utils.py", line 70, in read_string
    ret = struct.unpack(self.endian + "%is" % (size), self.read(size))[0]
struct.error: unpack requires a buffer of 3714449519 bytes

This looked similar to https://github.com/HearthSim/UnityPack/issues/23, and I tried to re-clone unitypack and reinstall from scratch, but the issue still persists.

Do you have any idea how to fix this?

sebastientromp commented 4 years ago

I can reproduce using only the gameobjects0 asset:

./bin/unityextract --audio -o out/audio /d/Games/Hearthstone/Data/Win/gameobjects0.unity3d
nanoNago commented 4 years ago

Seeing the same in another Unity project. It appears that although the asset metadata is parsed correctly, the type/tree information and/or the actual object reading function is not functioning correctly, and the actual data of the object is not correctly understood.

Haven't discovered the root cause yet, but I'm looking into it (very slowly). If anyone wants to get in touch to debug and discuss improvements, I'd love to get in touch so we can make some improvements to unitypack.

sebastientromp commented 4 years ago

I don't have knowledge of how Unity assets or unitypack works, but I'm willing to help debug if there is anything I can do

nanoNago commented 4 years ago

Looks like this is probably the result of #8. In my case, I'm looking at format=17 objects, but the "built in" structure definitions that unitypack ships with appears to be format=15; and there are some discrepancies that cause issues. Appears to be a known thing.

Unfortunately, my knowledge of Unity is kind of minimal, I just like to tinker with RE'ing formats. I'm not sure what a "good" solution here would look like, but I'm like 99% sure that any trace people are seeing that results from object.py read() can probably be fixed by focusing on #8.

sebastientromp commented 4 years ago

Good to know :) While debugging I think the format was format=17, though it was a few weeks ago so I'm not 100% sure.

sebastientromp commented 4 years ago

This looks solved now. So either one of the recent commits fixed it, or the last Hearthstone update did