UnityPy icon indicating copy to clipboard operation
UnityPy copied to clipboard

Segmentation fault when unpacking DXT5Crunched texture

Open na-ji opened this issue 2 years ago • 5 comments

Code

import os
import UnityPy

env = UnityPy.load("./my_asset_bundle")

for obj in env.objects:
    # process specific object types
    if obj.type.name in ["Texture2D", "Sprite"]:
        # parse the object data
        data = obj.read()

        # create destination path
        dest = os.path.join("./dest", data.name)

        # make sure that the extension is correct
        # you probably only want to do so with images/textures
        dest, _ = os.path.splitext(dest)
        dest = dest + ".png"

        img = data.image
        img.save(dest)

Error

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

This error is happening on the line img = data.image

Bug The image should be read successfully without crashing the whole script. When I checked m_TextureFormat attribute, the returned value was 29. I've tried with others tools like AssetRipper, and they can extract everything without issue. Also, I tried to disable the C-typetree reader, but the segmentation fault is still occurring.

To Reproduce my_asset_bundle.zip I zipped the file to make GitHub accepts it. You need to unzip it first.

  • Python version: 3.10.6
  • UnityPy version: 1.10.3
  • OS: macos Sonoma 14.0 on M1 Macbook pro

na-ji avatar Oct 20 '23 16:10 na-ji

This is a bit tricky to fix, as this is one of the kinds of segfaults that are a bit random and happen only under hard to reproduce conditions. (Or in other words, I can't reproduce the issue, but I see that it could happen due to potato code in dependencies)

Can you check where the segfault happens specifically, during de-crunching or during the texture parsing by PIL?

K0lb3 avatar Oct 22 '23 12:10 K0lb3

I've asked a colleague to test on his PC, and for him everything worked. He is on Windows while I'm on an M1 MacBook Pro. The difference might come from different OS + different architecture (arm vs amd). I will try to debug ASAP to tell you from which line it's coming.

PS: Sorry for the delay, I didn't get any notification.

na-ji avatar Nov 06 '23 15:11 na-ji

Can you check where the segfault happens specifically, during de-crunching or during the texture parsing by PIL?

The segfault happens during de-crunching on this line https://github.com/K0lb3/UnityPy/blob/99c240c88c4d35113dc7674a08904a9b21cf980c/UnityPy/export/Texture2DConverter.py#L128

na-ji avatar Nov 06 '23 21:11 na-ji

Thanks for the info.

And, well, this is pretty troublesome then, because the de-crunching is pure Unity code, so bug hunting it will be a nightmare. The only "simple" solution would be making a python wrapper for the Rust rewrite of the texture2ddecoder, which includes a rewrite of the crunch code. This version is memory safe for sure. It might take some time until I come around to this though.

K0lb3 avatar Nov 10 '23 08:11 K0lb3

Finished soon™️ image

K0lb3 avatar Nov 22 '23 22:11 K0lb3