Search Issue Tracker

Fixed

Fixed in 2021.3.32f1, 2022.3.14f1, 2023.2.0b16, 2023.3.0a12, 2024.1.0a1

Votes

9

Found in

2021.3.29f1

2022.3.7f1

2023.1.8f1

2023.2.0b4

2023.3.0a3

2024.1.0a1

Issue ID

UUM-46346

Regression

No

[IL2CPP] [Android] Player crashes (il2cpp::os::Image::GetImageUUID) when libil2cpp.so is modified

--

-

Reproduction steps:
1. Open the attached project "ReproProj"
2. Open the “/Assets/Scenes/SampleScene.unity” Scene
3. Export the project to the “GradleProject” folder
4. Use Android Studio to open the project and build it
5. In Unity Editor Click "Tools -> Modify libil2cpp.so"
6. Click Run in Android Studio and observe the Player

Expected result: The Player launches successfully and continues to run
Actual result: Player crashes at launch

Reproducible with: 2021.3.29f1, 2022.3.7f1, 2023.1.8f1, 2023.2.0b4

Reproducible with devices:
VLNQA00332, Samsung Galaxy XCover4 (SM-G390F), Android 9, CPU: Exynos 7 Quad 7570, GPU: Mali-T720
VLNQA00325, Samsung Galaxy Note10 (SM-N970F), Android 12, CPU: Exynos 9 (9825), GPU: Mali-G76
VLNQA00318, Oneplus OnePlus 7 Pro (GM1913), Android 11, CPU: Snapdragon 855 SM8150, GPU: Adreno (TM) 640
VLNQA00231, Samsung Galaxy A5(2017) (SM-A520F), Android 8.0.0, CPU: Exynos 7 Octa 7880, GPU: Mali-T830
VLNQA00231, Huawei HUAWEI Mate 20 Pro (LYA-L29), Android 9, CPU: HiSilicon Kirin 980, GPU: Mali-G76

Testing environment: Windows 10 Enterprise 21H2

  1. Resolution Note (fix version 2022.3.14f1):

    I'm adding a comment here on the bug, but it applies directly to the 2022.3 port because we cannot verify that the bug is fixed in that version.

    The problem is with the user code in the project for step 5: "Modify libil2cpp.so". That code emits some invalid data to the libil2cpp.so file, specifically giving us an elf here with a n_descsz field that is 131 bytes long. This means that the code does an unaligned read, which causes a crash on ARMv7 chips.

    This code was not modified for this bug fix, and it is correct, assuming that we have valid data in the libil2cpp.so file.

    So although we cannot verify this on 2022.3, we have verified the fix on other versions, and the crash is unrelated to the user's issue. Instead, the new crash is related to this bug in the code that tries to trigger the crash.

Comments (3)

  1. WNP78

    Sep 22, 2023 21:10

    I've tracked down the error to in libil2cpp/os/Posix/Image.cpp, method GetELFImageBuildID(). The issue is with the expression "phdr[i].p_offset + imageBase" on lines 84 and 86. This is not the correct way to get the memory location of that section. The correct way to do this is described in a UNIX stackexchange post:

    "How to tell whether the p_vaddr in ELF program header is the real memory address or is just an offset from the shared library base address?" (I cannot give the direct link as it is forbidden by this comment section)

    Making edits to libil2cpp on our disk and re-exporting has fixed the issue for us, showing that this is the cause of the issue. In our case, the trigger was google automatic integrity protection modifying the libil2cpp.so file. Comparing the files pre and post google AIP, we see that google does not modify at all the contents of the PT_NOTE section that contains the build ID, or any other note section. However, it does relocate it in the file. In the unmodified library, the p_offset and the p_vaddr are the same. This is why it works, despite the code incorrectly using p_offset. After google edits the .so, it is relocated and p_offset is no longer equal to p_vaddr.

    Swapping p_offset to p_vaddr was enough to stop the crashes for us. As stated in the stackexchange I linked earlier, in some cases you may also have to subtract the offset of the lowest PT_LOAD section. In our case this always turned out to be zero, so we're good for now, but to stop this coming up again in the future it shouldn't be difficult to factor that in as well. I'll include below some example code (I'm not super versed in C++ so don't take my word for it, do your own research etc):

    // find lowest PT_LOAD section offset
    uint32_t lowest_pt_load = -1;

    for (int i = 0; i < ehdr->e_phnum; i++)
    {
    if (phdr[i].p_type == PT_LOAD && phdr[i].p_vaddr < lowest_pt_load)
    {
    lowest_pt_load = phdr[i].p_vaddr;
    }
    }

    if (lowest_pt_load == -1) { lowest_pt_load = 0; }

    and these 3 lines in the loop:

    size_t nhdr_ptr = phdr[i].p_vaddr + imageBase - lowest_pt_load;
    int j = 0;
    while (nhdr_ptr < imageBase + phdr[i].p_vaddr - lowest_pt_load + phdr[i].p_memsz)

  2. Andrew-Garrison

    Sep 22, 2023 14:46

    We recently started having the same issue and it is impacting many of our Google Play users. We believe it started happening after we started using Google's Automatic Integrity Protection.

  3. i9mobile

    Sep 18, 2023 18:22

    I'm getting a lot of "[libil2cpp.so] Image.cpp - il2cpp::eek:s::Image::GetELFImageBuildID()" crashes..

    https://forum.unity.com/threads/libil2cpp-so-il2cpp-os-image-getelfimagebuildid.1454485

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.