Skip to content

Commit 75a62f3

Browse files
authored
Fix FindGetTypeInfoFromTypeDefinitionIndex for Unity games built with IL2CPP Master (#60)
1 parent ba8fbf9 commit 75a62f3

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

Il2CppInterop.Runtime/Injection/InjectorHelpers.cs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,32 @@ private static d_GetTypeInfoFromTypeDefinitionIndex FindGetTypeInfoFromTypeDefin
276276
if (imageGetTypeXrefs.Count() > 1 && UnityVersionHandler.IsMetadataV29OrHigher)
277277
{
278278
// (Kasuromi): metadata v29 introduces handles and adds extra calls, a check for unity versions might be necessary in the future
279-
280-
// Second call after obtaining handle, if there are any more calls in the future - correctly index into it if issues occur
281-
var getTypeInfoFromHandle = XrefScannerLowLevel.JumpTargets(imageGetType).Last();
282-
// Two calls, second one (GetIndexForTypeDefinitionInternal) is inlined
283-
getTypeInfoFromTypeDefinitionIndex = XrefScannerLowLevel.JumpTargets(getTypeInfoFromHandle).Single();
284-
285-
// Xref scanner is sometimes confused about getTypeInfoFromHandle so we walk all the thunks until we hit the big method we need
286-
while (XrefScannerLowLevel.JumpTargets(getTypeInfoFromTypeDefinitionIndex).Count() == 1)
279+
280+
Logger.Instance.LogTrace($"imageGetTypeXrefs.Length: {imageGetTypeXrefs.Length}");
281+
282+
// If the game is built as IL2CPP Master, GetAssemblyTypeHandle is inlined, xrefs length is 3 and it's the first function call,
283+
// if not, it's the last call.
284+
var getTypeInfoFromHandle = imageGetTypeXrefs.Length == 2 ? imageGetTypeXrefs.Last() : imageGetTypeXrefs.First();
285+
286+
Logger.Instance.LogTrace($"getTypeInfoFromHandle: {getTypeInfoFromHandle:X2}");
287+
288+
var getTypeInfoFromHandleXrefs = XrefScannerLowLevel.JumpTargets(getTypeInfoFromHandle).ToArray();
289+
290+
// If getTypeInfoFromHandle xrefs is not a single call, it's the function we want, if not, we keep xrefing until we find it
291+
if (getTypeInfoFromHandleXrefs.Length != 1)
292+
{
293+
getTypeInfoFromTypeDefinitionIndex = getTypeInfoFromHandle;
294+
Logger.Instance.LogTrace($"Xrefs length was not 1, getTypeInfoFromTypeDefinitionIndex: {getTypeInfoFromTypeDefinitionIndex:X2}");
295+
}
296+
else
287297
{
288-
getTypeInfoFromTypeDefinitionIndex = XrefScannerLowLevel.JumpTargets(getTypeInfoFromTypeDefinitionIndex).Single();
298+
// Two calls, second one (GetIndexForTypeDefinitionInternal) is inlined
299+
getTypeInfoFromTypeDefinitionIndex = getTypeInfoFromHandleXrefs.Single();
300+
// Xref scanner is sometimes confused about getTypeInfoFromHandle so we walk all the thunks until we hit the big method we need
301+
while (XrefScannerLowLevel.JumpTargets(getTypeInfoFromTypeDefinitionIndex).ToArray().Length == 1)
302+
{
303+
getTypeInfoFromTypeDefinitionIndex = XrefScannerLowLevel.JumpTargets(getTypeInfoFromTypeDefinitionIndex).Single();
304+
}
289305
}
290306
}
291307
}

0 commit comments

Comments
 (0)