• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SamboyCoding / Cpp2IL / 15052278841

15 May 2025 06:16PM UTC coverage: 34.038% (-0.4%) from 34.453%
15052278841

push

github

SamboyCoding
Support injecting anything
* Nested types
* Events
* Properties
* Assemblies

Support additional metadata in injected assemblies

Make setter for TypeAnalysisContext::OverrideBaseType public

TypeAnalysisContext::InterfaceContexts as list rather than array

Fix sign bug

Support generic parameters on type contexts and method contexts

Make GenericParameterTypeAnalysisContext instances unique

Revert change to Il2CppGenericParameter::Index

Use attributes to determine if injected methods are static
* Also add hide by sig attribute for injected constructors

Support overrides on injected methods

In ControlFlowGraphOutputFormat, exclude injected assemblies

Ensure injected assemblies can't delete existing assemblies

Backing field on .NET Standard for injected method overrides

Implement requested change

1774 of 6622 branches covered (26.79%)

Branch coverage included in aggregate %.

147 of 196 new or added lines in 27 files covered. (75.0%)

53 existing lines in 2 files now uncovered.

4155 of 10797 relevant lines covered (38.48%)

188267.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.49
/Cpp2IL.Core/Model/Contexts/AssemblyAnalysisContext.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Reflection;
5
using Cpp2IL.Core.Extensions;
6
using Cpp2IL.Core.Utils;
7
using LibCpp2IL.BinaryStructures;
8
using LibCpp2IL.Metadata;
9

10
namespace Cpp2IL.Core.Model.Contexts;
11

12
/// <summary>
13
/// Represents a single Assembly that was converted using IL2CPP.
14
/// </summary>
15
public class AssemblyAnalysisContext : HasCustomAttributesAndName
16
{
17
    /// <summary>
18
    /// The raw assembly metadata, such as its name, version, etc.
19
    /// </summary>
20
    public Il2CppAssemblyDefinition? Definition { get; set; }
3,053,043✔
21

22
    /// <summary>
23
    /// The analysis context objects for all types contained within the assembly, including those nested within a parent type.
24
    /// </summary>
25
    public List<TypeAnalysisContext> Types = [];
1,099✔
26

27
    /// <summary>
28
    /// The analysis context objects for all types contained within the assembly which are not nested within a parent type.
29
    /// </summary>
30
    public IEnumerable<TypeAnalysisContext> TopLevelTypes => Types.Where(t => t.DeclaringType == null);
14,840✔
31

32
    /// <summary>
33
    /// The code gen module for this assembly.
34
    ///
35
    /// Null prior to 24.2
36
    /// </summary>
37
    public Il2CppCodeGenModule? CodeGenModule;
38

39
    public virtual Version Version
40
    {
41
        get
42
        {
43
            //handle __Generated assembly on v29, which has a version of 0.0.-1.-1
44
            return Definition is null || Definition.AssemblyName.build < 0
210!
45
                ? new(0,0,0,0)
210✔
46
                : new(Definition.AssemblyName.major, Definition.AssemblyName.minor, Definition.AssemblyName.build, Definition.AssemblyName.revision);
210✔
47
        }
48
    }
49

50
    public virtual uint HashAlgorithm => Definition?.AssemblyName.hash_alg ?? default;
210!
51

52
    public virtual uint Flags => Definition?.AssemblyName.flags ?? default;
210!
53

54
    public virtual string? Culture => Definition?.AssemblyName.Culture;
210!
55

NEW
56
    public virtual byte[]? PublicKeyToken => Definition?.AssemblyName.PublicKeyToken;
×
57

58
    public virtual byte[]? PublicKey => Definition?.AssemblyName.PublicKey;
210!
59

60
    protected override int CustomAttributeIndex => Definition?.CustomAttributeIndex ?? -1;
882!
61

62
    public override AssemblyAnalysisContext CustomAttributeAssembly => this;
2,412✔
63

64
    private readonly Dictionary<string, TypeAnalysisContext> TypesByName = new();
1,099✔
65

66
    private readonly Dictionary<Il2CppTypeDefinition, TypeAnalysisContext> TypesByDefinition = new();
1,099✔
67

68
    public override string DefaultName => Definition?.AssemblyName.Name ?? throw new($"Injected assemblies should override {nameof(DefaultName)}");
425!
69

70
    protected override bool IsInjected => Definition is null;
1,098✔
71

72
    /// <summary>
73
    /// Get assembly name without the extension and with any invalid path characters or elements removed.
74
    /// </summary>
NEW
75
    public string CleanAssemblyName => MiscUtils.CleanPathElement(Name);
×
76

77
    public string ModuleName
78
    {
79
        get
80
        {
81
            var moduleName = Definition?.Image.Name ?? Name;
210!
82
            if (moduleName == "__Generated")
210!
NEW
83
                moduleName += ".dll"; //__Generated doesn't have a .dll extension in the metadata but it is still of course a DLL
×
84
            return moduleName;
210✔
85
        }
86
    }
87

88
    public AssemblyAnalysisContext(Il2CppAssemblyDefinition? assemblyDefinition, ApplicationAnalysisContext appContext) : base(assemblyDefinition?.Token ?? 0, appContext)
1,099✔
89
    {
90
        if (assemblyDefinition is null)
1,099✔
91
            return;
1✔
92

93
        Definition = assemblyDefinition;
1,098✔
94

95
        if (AppContext.MetadataVersion >= 24.2f)
1,098✔
96
            CodeGenModule = AppContext.Binary.GetCodegenModuleByName(Definition.Image.Name!);
1,098✔
97

98
        InitCustomAttributeData();
1,098✔
99

100
        foreach (var il2CppTypeDefinition in Definition.Image.Types!)
154,704✔
101
        {
102
            var typeContext = new TypeAnalysisContext(il2CppTypeDefinition, this);
76,254✔
103
            Types.Add(typeContext);
76,254✔
104
            TypesByName[il2CppTypeDefinition.FullName!] = typeContext;
76,254✔
105
            TypesByDefinition[il2CppTypeDefinition] = typeContext;
76,254✔
106
        }
107

108
        foreach (var type in Types)
154,704✔
109
        {
110
            if (type.Definition!.NestedTypeCount < 1)
76,254✔
111
                continue;
112

113
            type.NestedTypes = type.Definition.NestedTypes!.Select(n => GetTypeByFullName(n.FullName!) ?? throw new($"Unable to find nested type by name {n.FullName}"))
23,205!
114
                .Peek(t => t.DeclaringType = type)
16,788✔
115
                .ToList();
6,417✔
116
        }
117
    }
1,098✔
118

119
    public TypeAnalysisContext InjectType(string ns, string name, TypeAnalysisContext? baseType, TypeAttributes typeAttributes = TypeAnalysisContext.DefaultTypeAttributes)
120
    {
121
        var ret = new InjectedTypeAnalysisContext(this, ns, name, baseType, typeAttributes);
336✔
122
        InjectType(ret);
336✔
123
        return ret;
336✔
124
    }
125

126
    internal void InjectType(InjectedTypeAnalysisContext ret)
127
    {
128
        Types.Add(ret);
379✔
129
        TypesByName[ret.FullName] = ret;
379✔
130
    }
379✔
131

132
    public TypeAnalysisContext? GetTypeByFullName(string fullName) => TypesByName.TryGetValue(fullName, out var typeContext) ? typeContext : null;
17,392✔
133

134
    public TypeAnalysisContext? GetTypeByDefinition(Il2CppTypeDefinition typeDefinition) => TypesByDefinition.TryGetValue(typeDefinition, out var typeContext) ? typeContext : null;
2,334,277!
135

NEW
136
    public override string ToString() => "Assembly: " + Name;
×
137
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc