SamboyCoding / Cpp2IL

Work-in-progress tool to reverse unity's IL2CPP toolchain.
MIT License
1.6k stars 187 forks source link

Emit Full Method Signatures in Call Analysis #173

Closed ds5678 closed 7 months ago

ds5678 commented 1 year ago

The Member field of CallsAttribute and CalledByAttribute currently just contains the member's name. Specifying the full signature would be better for removing ambiguity.

For example, instead of:

[Calls(Type = typeof(Path), Member = "Combine")]

It could be:

[Calls(Type = typeof(Path), Member = "Combine(System.String, System.String)")]

Or:

[Calls(Type = typeof(Path), Member = "Combine", MemberTypes = new[] { typeof(string), typeof(string) } )]

The Type?[] MemberTypes proposal has the advantage of succinctness and clicking in decompilers. It should be enough for most cases. However, it cannot cover all scenarios. For example, the following code is legal:

public unsafe static class Test
{
    public static void Stuff(out int value) => value = default;
    public static void Stuff(int value) { }
    public static void Stuff(int* value) { }
    public static void Stuff(delegate* unmanaged[Cdecl]<void> value) { }
}

in, out, and ref can't be used so using Type? parameters inevitably creates an ambiguity. To iterate over the possibilities:

A string encoding is the only way to remove all ambiguity. However, that is overly verbose and less useful. For the vast majority of cases, using an array of typeof will suffice.

A specified return type is not necessary for removing ambiguity.

Due to the complexity and questionable usefulness of string method signatures, I consider the Type?[] MemberTypes proposal to be the superior design.

Alternative names might be MemberParameters, MemberParameterTypes, or ParameterTypes.