Skip to content

Commit ddf4f59

Browse files
authored
Call Analysis Processing Layer (#164)
1 parent 53ed393 commit ddf4f59

File tree

9 files changed

+468
-9
lines changed

9 files changed

+468
-9
lines changed

Cpp2IL.Core/CorePlugin/AttributeAnalysisProcessingLayer.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Linq;
33
using Cpp2IL.Core.Api;
44
using Cpp2IL.Core.Model.Contexts;
@@ -7,7 +7,7 @@ namespace Cpp2IL.Core.CorePlugin;
77

88
public class AttributeAnalysisProcessingLayer : Cpp2IlProcessingLayer
99
{
10-
public override string Name => "CustomAttribute Analyser";
10+
public override string Name => "CustomAttribute Analyzer";
1111
public override string Id => "attributeanalyzer";
1212

1313
public override void Process(ApplicationAnalysisContext appContext, Action<int, int>? progressCallback = null)
@@ -38,4 +38,4 @@ private void AnalyzeAndRaise(HasCustomAttributes toAnalyze, ref int count, int t
3838
count++;
3939
progressCallback?.Invoke(count, total);
4040
}
41-
}
41+
}

Cpp2IL.Core/CorePlugin/CallAnalysisProcessingLayer.cs

+299
Large diffs are not rendered by default.

Cpp2IL.Core/CorePlugin/Cpp2IlCorePlugin.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ public override void OnLoad()
4747

4848
ProcessingLayerRegistry.Register<AttributeAnalysisProcessingLayer>();
4949
ProcessingLayerRegistry.Register<AttributeInjectorProcessingLayer>();
50+
ProcessingLayerRegistry.Register<CallAnalysisProcessingLayer>();
5051
ProcessingLayerRegistry.Register<StableRenamingProcessingLayer>();
5152
ProcessingLayerRegistry.Register<DeobfuscationMapProcessingLayer>();
5253

5354
var elapsed = DateTime.Now - start;
5455
Logger.VerboseNewline($"Core plugin loaded in {elapsed.Ticks} ticks ({elapsed.TotalMilliseconds}ms)", "Core Plugin");
5556
}
56-
}
57+
}

Cpp2IL.Core/Il2CppApiFunctions/BaseKeyFunctionAddresses.cs

+50-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22
using System.Diagnostics.CodeAnalysis;
33
using System.Linq;
44
using Cpp2IL.Core.Logging;
@@ -51,6 +51,13 @@ public abstract class BaseKeyFunctionAddresses
5151

5252
private ApplicationAnalysisContext _appContext = null!; //Always initialized before used
5353

54+
private readonly HashSet<ulong> resolvedAddresses = new();
55+
56+
public bool IsKeyFunctionAddress(ulong address)
57+
{
58+
return address != 0 && resolvedAddresses.Contains(address);
59+
}
60+
5461
private void FindExport(string name, out ulong ptr)
5562
{
5663
Logger.Verbose($"\tLooking for Exported {name} function...");
@@ -105,6 +112,7 @@ public void Find(ApplicationAnalysisContext applicationAnalysisContext)
105112
AttemptInstructionAnalysisToFillGaps();
106113

107114
FindThunks();
115+
InitializeResolvedAddresses();
108116
}
109117

110118
protected void TryGetInitMetadataFromException()
@@ -283,5 +291,45 @@ private void FindThunks()
283291
protected virtual void Init(ApplicationAnalysisContext context)
284292
{
285293
}
294+
295+
private void InitializeResolvedAddresses()
296+
{
297+
resolvedAddresses.Clear();
298+
resolvedAddresses.Add(il2cpp_codegen_initialize_method);
299+
resolvedAddresses.Add(il2cpp_codegen_initialize_runtime_metadata);
300+
resolvedAddresses.Add(il2cpp_vm_metadatacache_initializemethodmetadata);
301+
resolvedAddresses.Add(il2cpp_runtime_class_init_export);
302+
resolvedAddresses.Add(il2cpp_runtime_class_init_actual);
303+
resolvedAddresses.Add(il2cpp_object_new);
304+
resolvedAddresses.Add(il2cpp_vm_object_new);
305+
resolvedAddresses.Add(il2cpp_codegen_object_new);
306+
resolvedAddresses.Add(il2cpp_array_new_specific);
307+
resolvedAddresses.Add(il2cpp_vm_array_new_specific);
308+
resolvedAddresses.Add(SzArrayNew);
309+
resolvedAddresses.Add(il2cpp_type_get_object);
310+
resolvedAddresses.Add(il2cpp_vm_reflection_get_type_object);
311+
resolvedAddresses.Add(il2cpp_resolve_icall);
312+
resolvedAddresses.Add(InternalCalls_Resolve);
313+
314+
resolvedAddresses.Add(il2cpp_string_new);
315+
resolvedAddresses.Add(il2cpp_vm_string_new);
316+
resolvedAddresses.Add(il2cpp_string_new_wrapper);
317+
resolvedAddresses.Add(il2cpp_vm_string_newWrapper);
318+
resolvedAddresses.Add(il2cpp_codegen_string_new_wrapper);
319+
320+
resolvedAddresses.Add(il2cpp_value_box);
321+
resolvedAddresses.Add(il2cpp_vm_object_box);
322+
323+
resolvedAddresses.Add(il2cpp_object_unbox);
324+
resolvedAddresses.Add(il2cpp_vm_object_unbox);
325+
326+
resolvedAddresses.Add(il2cpp_raise_exception);
327+
resolvedAddresses.Add(il2cpp_vm_exception_raise);
328+
resolvedAddresses.Add(il2cpp_codegen_raise_exception);
329+
330+
resolvedAddresses.Add(il2cpp_vm_object_is_inst);
331+
332+
resolvedAddresses.Add(AddrPInvokeLookup);
333+
}
286334
}
287-
}
335+
}

Cpp2IL.Core/Model/CustomAttributes/CustomAttributeTypeParameter.cs

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ public class CustomAttributeTypeParameter : BaseCustomAttributeParameter
1212
{
1313
public Il2CppType? Type;
1414

15+
public CustomAttributeTypeParameter(Il2CppType? type, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
16+
{
17+
Type = type;
18+
}
19+
1520
public CustomAttributeTypeParameter(AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
1621
{
1722
}

Cpp2IL.Core/Utils/MiscUtils.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.Linq;
@@ -284,6 +284,14 @@ public static bool BitsAreEqual(this BitArray first, BitArray second)
284284
return !areDifferent;
285285
}
286286

287+
public static void ExecuteSerial<T>(IEnumerable<T> enumerable, Action<T> what)
288+
{
289+
foreach (var item in enumerable)
290+
{
291+
what(item);
292+
}
293+
}
294+
287295
public static void ExecuteParallel<T>(IEnumerable<T> enumerable, Action<T> what)
288296
{
289297
bool F2(T t)

Cpp2IL.sln

+8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cpp2IL.Plugin.BuildReport",
3636
EndProject
3737
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cpp2IL.Plugin.OrbisPkg", "Cpp2IL.Plugin.OrbisPkg\Cpp2IL.Plugin.OrbisPkg.csproj", "{A621899A-564D-4CD0-97AC-097EBABA5ACD}"
3838
EndProject
39+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{51C7C919-3561-4630-827C-7FF8173AF665}"
40+
ProjectSection(SolutionItems) = preProject
41+
docs\CallAnalyzer.md = docs\CallAnalyzer.md
42+
EndProjectSection
43+
EndProject
3944
Global
4045
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4146
Debug|Any CPU = Debug|Any CPU
@@ -86,6 +91,9 @@ Global
8691
GlobalSection(SolutionProperties) = preSolution
8792
HideSolutionNode = FALSE
8893
EndGlobalSection
94+
GlobalSection(NestedProjects) = preSolution
95+
{51C7C919-3561-4630-827C-7FF8173AF665} = {46226B08-22BA-455E-8B99-F496E90EDCBC}
96+
EndGlobalSection
8997
GlobalSection(ExtensibilityGlobals) = postSolution
9098
SolutionGuid = {E9A45B2C-AAEF-4D66-ADD6-7DD234DA3F39}
9199
EndGlobalSection

LibCpp2IL/Reflection/LibCpp2IlReflection.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Concurrent;
1+
using System.Collections.Concurrent;
22
using System.Collections.Generic;
33
using System.Diagnostics.CodeAnalysis;
44
using System.Linq;
@@ -185,6 +185,8 @@ public static int GetPropertyIndexFromProperty(Il2CppPropertyDefinition property
185185

186186
switch (fullName)
187187
{
188+
case "System.Int32":
189+
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_I4];
188190
case "System.String":
189191
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_STRING];
190192
case "System.Void":
@@ -207,4 +209,4 @@ public static int GetPropertyIndexFromProperty(Il2CppPropertyDefinition property
207209
return null;
208210
}
209211
}
210-
}
212+
}

docs/CallAnalyzer.md

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Call Analyzer
2+
3+
This processing layer analyzes method instructions for calls to other methods and emits attributes based on that.
4+
5+
For this processor, 8 new attributes are injected:
6+
```cs
7+
using System;
8+
namespace Cpp2ILInjected.CallAnalysis;
9+
10+
/// <summary>
11+
/// This method's instructions have been deduplicated by the compiler, and it shares its address with other methods.
12+
/// </summary>
13+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
14+
public sealed class DeduplicatedMethodAttribute : Attribute
15+
{
16+
}
17+
18+
/// <summary>
19+
/// A problem was encountered while analyzing this method's instructions.
20+
/// </summary>
21+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
22+
public sealed class CallAnalysisFailedAttribute : Attribute
23+
{
24+
}
25+
26+
/// <summary>
27+
/// This method has no instructions to analyze and is not abstract nor an interface declaration.
28+
/// </summary>
29+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
30+
public sealed class CallAnalysisNotSupportedAttribute : Attribute
31+
{
32+
}
33+
34+
/// <summary>
35+
/// This method is called from the method specified.
36+
/// </summary>
37+
/// <remarks>
38+
/// This attribute is not emitted if there are a large amount of callers.
39+
/// </remarks>
40+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
41+
public sealed class CalledByAttribute : Attribute
42+
{
43+
public Type Type;
44+
45+
public string Member;
46+
}
47+
48+
/// <summary>
49+
/// This method calls the method specified.
50+
/// </summary>
51+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
52+
public sealed class CallsAttribute : Attribute
53+
{
54+
public Type Type;
55+
56+
public string Member;
57+
}
58+
59+
/// <summary>
60+
/// The number of direct calls to this method.
61+
/// </summary>
62+
/// <remarks>
63+
/// This attribute is similar in form and function to the one generated by <see href="https://github.com/knah/Il2CppAssemblyUnhollower">Unhollower</see>.
64+
/// </remarks>
65+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
66+
public sealed class CallerCountAttribute : Attribute
67+
{
68+
public int Count;
69+
}
70+
71+
/// <summary>
72+
/// This method calls at least one deduplicated method.
73+
/// </summary>
74+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
75+
public sealed class CallsDeduplicatedMethodsAttribute : Attribute
76+
{
77+
public int Count;
78+
}
79+
80+
/// <summary>
81+
/// This method calls at least one unknown method.
82+
/// </summary>
83+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
84+
public sealed class CallsUnknownMethodsAttribute : Attribute
85+
{
86+
public int Count;
87+
}
88+
```

0 commit comments

Comments
 (0)