-
Notifications
You must be signed in to change notification settings - Fork 106
Description
Il2CppInterop version: 1.4.6-ci.579+9d4599dc78d69ede49a2ee96a1ccf41eec02db5b
Example of a method: Dictionary<string, object>.Add(string key, object value)
When a boxed bool is passed as the second argument and later retrieved(with this[string key]), the pointer to it ends up getting shifted 16 bytes forward, which causes even a .ToString() call to crash
The problem seems to be here in the decompilation of the generated Add method:
ref TValue val2;
if (!typeof(TValue).IsValueType)
{
object obj2 = value;
System.IntPtr intPtr2;
if (!(obj2 is string))
{
intPtr2 = IL2CPP.Il2CppObjectBaseToPtr(obj2 as Il2CppObjectBase);
val2 = intPtr2;
if (intPtr2 != (System.IntPtr)0 && IL2CPP.il2cpp_class_is_valuetype(IL2CPP.il2cpp_object_get_class(intPtr2)))
{
intPtr2 = IL2CPP.il2cpp_object_unbox(intPtr2);
val2 = intPtr2;
}
}
else
{
intPtr2 = IL2CPP.ManagedStringToIl2Cpp(obj2 as string);
val2 = intPtr2;
}
}
else
{
val2 = ref value;
}The correct behavior in this case is to bypass that call to IL2CPP.il2cpp_object_unbox
A quick and dirty fix is to just temporarily overwrite the class pointer of the object passed as the argument, like this:
unsafe {
// The class pointer is the first field in every il2cpp object struct
*(IntPtr*)targetObject.Pointer.ToPointer() = Il2CppClassPointerStore<string>.NativeClassPtr;;
}With that hack, Dictionary behaves as it should, returning a valid boxed object
I'm not sure what the purpose of that unboxing is, but it is pretty clearly the incorrect behavior in this case