Skip to content

Conversation

@Steve-xmh
Copy link

@Steve-xmh Steve-xmh commented Dec 7, 2025

When a parameter is a reference of Il2CppSystem.ValueType, the generated code doesn't correctly unboxed, which will let the game or program got a wrong pointer and crash the program. This issue is trying to fix that by calling il2cpp_object_unbox to get actual reference pointer of the value.

Only tested on my mod of Taiko no Tatsujin - Rhythm Festival Steam PC version. I don't have enough time for further testing so I don't know whether it will break something or not.

Old interop code generated:

[CallerCount(3)]
[CachedScanResults(RefRangeStart = 51506, RefRangeEnd = 51509, XrefRangeStart = 51500, XrefRangeEnd = 51506, MetadataInitTokenRva = 0, MetadataInitFlagRva = 0)]
public unsafe bool GetCurrentOnpu([In] ref GameDrawInfo drawInfo, int prefabType, ref OnpuBase onpu)
{
  IL2CPP.Il2CppObjectBaseToPtrNotNull((Il2CppObjectBase) this);
  System.IntPtr* numPtr1 = stackalloc System.IntPtr[3];
  // Still not an actual pointer
  numPtr1[0] = IL2CPP.Il2CppObjectBaseToPtrNotNull((Il2CppObjectBase) drawInfo);
  *(System.IntPtr*) ((System.IntPtr) numPtr1 + checked (new System.IntPtr(1) * sizeof (System.IntPtr))) = (System.IntPtr) &prefabType;
  System.IntPtr num1 = (System.IntPtr) numPtr1 + checked (new System.IntPtr(2) * sizeof (System.IntPtr));
  System.IntPtr ptr = IL2CPP.Il2CppObjectBaseToPtr((Il2CppObjectBase) onpu);
  System.IntPtr* numPtr2 = &ptr;
  *(System.IntPtr*) num1 = (System.IntPtr) numPtr2;
  System.IntPtr exc;
  System.IntPtr num2 = IL2CPP.il2cpp_runtime_invoke(OnpuPlayer.NativeMethodInfoPtr_GetCurrentOnpu_Private_Boolean_byref_GameDrawInfo_Int32_byref_OnpuBase_0, IL2CPP.Il2CppObjectBaseToPtrNotNull((Il2CppObjectBase) this), (void**) numPtr1, ref exc);
  Il2CppInterop.Runtime.Il2CppException.RaiseExceptionIfNecessary(exc);
  ref OnpuBase local = ref onpu;
  System.IntPtr pointer = ptr;
  OnpuBase onpuBase = pointer == System.IntPtr.Zero ? (OnpuBase) null : new OnpuBase(pointer);
  local = onpuBase;
  return *(bool*) IL2CPP.il2cpp_object_unbox(num2);
}

New interop code generated:

[CallerCount(3)]
[CachedScanResults(RefRangeStart = 51506, RefRangeEnd = 51509, XrefRangeStart = 51500, XrefRangeEnd = 51506, MetadataInitTokenRva = 0, MetadataInitFlagRva = 0)]
public unsafe bool GetCurrentOnpu([In] ref GameDrawInfo drawInfo, int prefabType, ref OnpuBase onpu)
{
  IL2CPP.Il2CppObjectBaseToPtrNotNull((Il2CppObjectBase) this);
  System.IntPtr* numPtr1 = stackalloc System.IntPtr[3];
  // Unbox here
  numPtr1[0] = IL2CPP.il2cpp_object_unbox(IL2CPP.Il2CppObjectBaseToPtrNotNull((Il2CppObjectBase) drawInfo));
  *(System.IntPtr*) ((System.IntPtr) numPtr1 + checked (new System.IntPtr(1) * sizeof (System.IntPtr))) = (System.IntPtr) &prefabType;
  System.IntPtr num1 = (System.IntPtr) numPtr1 + checked (new System.IntPtr(2) * sizeof (System.IntPtr));
  System.IntPtr ptr = IL2CPP.Il2CppObjectBaseToPtr((Il2CppObjectBase) onpu);
  System.IntPtr* numPtr2 = &ptr;
  *(System.IntPtr*) num1 = (System.IntPtr) numPtr2;
  System.IntPtr exc;
  System.IntPtr num2 = IL2CPP.il2cpp_runtime_invoke(OnpuPlayer.NativeMethodInfoPtr_GetCurrentOnpu_Private_Boolean_byref_GameDrawInfo_Int32_byref_OnpuBase_0, IL2CPP.Il2CppObjectBaseToPtrNotNull((Il2CppObjectBase) this), (void**) numPtr1, ref exc);
  Il2CppInterop.Runtime.Il2CppException.RaiseExceptionIfNecessary(exc);
  ref OnpuBase local = ref onpu;
  System.IntPtr pointer = ptr;
  OnpuBase onpuBase = pointer == System.IntPtr.Zero ? (OnpuBase) null : new OnpuBase(pointer);
  local = onpuBase;
  return *(bool*) IL2CPP.il2cpp_object_unbox(num2);
}

The il2cpp method signature from IDA as reference:

bool OnpuPlayer__GetCurrentOnpu(
        OnpuPlayer_o *this,
        Blittables_GameDrawInfo_o *drawInfo,
        int32_t prefabType,
        OnpuBase_o **onpu,
        const MethodInfo *method);

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

Successfully merging this pull request may close these issues.

1 participant