예제 #1
0
        internal static List <GlobalIdentifier> MapGlobalIdentifiers(Il2CppMetadata metadata, PE.PE cppAssembly)
        {
            //Classes
            var ret = metadata.metadataUsageDic[1]
                      .Select(kvp => new { kvp, type = cppAssembly.types[kvp.Value] })
                      .Select(t => new GlobalIdentifier
            {
                Name           = Utils.GetTypeName(metadata, cppAssembly, t.type, true),
                Offset         = cppAssembly.metadataUsages[t.kvp.Key],
                IdentifierType = GlobalIdentifier.Type.TYPE
            }).ToList();

            //Idx 2 is exactly the same thing
            ret.AddRange(metadata.metadataUsageDic[2]
                         .Select(kvp => new { kvp, type = cppAssembly.types[kvp.Value] })
                         .Select(t => new GlobalIdentifier
            {
                Name           = Utils.GetTypeName(metadata, cppAssembly, t.type, true),
                Offset         = cppAssembly.metadataUsages[t.kvp.Key],
                IdentifierType = GlobalIdentifier.Type.TYPE
            })
                         );

            //Methods is idx 3
            //Don't @ me, i prefer LINQ to foreach loops.
            //But that said this could be optimised to less t-ing
            ret.AddRange(metadata.metadataUsageDic[3]
                         .Select(kvp => new { kvp, method = metadata.methodDefs[kvp.Value] })
                         .Select(t => new { t.kvp, t.method, type = metadata.typeDefs[t.method.declaringType] })
                         .Select(t => new { t.kvp, t.method, typeName = Utils.GetTypeName(metadata, cppAssembly, t.type) })
                         .Select(t => new { t.kvp, methodName = t.typeName + "." + metadata.GetStringFromIndex(t.method.nameIndex) + "()" })
                         .Select(t => new GlobalIdentifier
            {
                IdentifierType = GlobalIdentifier.Type.METHOD,
                Name           = t.methodName,
                Offset         = cppAssembly.metadataUsages[t.kvp.Key]
            })
                         );

            //Fields is idx 4
            ret.AddRange(metadata.metadataUsageDic[4]
                         .Select(kvp => new { kvp, fieldRef = metadata.fieldRefs[kvp.Value] })
                         .Select(t => new { t.kvp, t.fieldRef, type = cppAssembly.types[t.fieldRef.typeIndex] })
                         .Select(t => new { t.type, t.kvp, t.fieldRef, typeDef = metadata.typeDefs[t.type.data.classIndex] })
                         .Select(t => new { t.type, t.kvp, fieldDef = metadata.fieldDefs[t.typeDef.firstFieldIdx + t.fieldRef.fieldIndex] })
                         .Select(t => new { t.kvp, fieldName = Utils.GetTypeName(metadata, cppAssembly, t.type, true) + "." + metadata.GetStringFromIndex(t.fieldDef.nameIndex) })
                         .Select(t => new GlobalIdentifier
            {
                IdentifierType = GlobalIdentifier.Type.FIELD,
                Name           = t.fieldName,
                Offset         = cppAssembly.metadataUsages[t.kvp.Key]
            })
                         );

            //Literals
            ret.AddRange(metadata.metadataUsageDic[5]
                         .Select(kvp => new GlobalIdentifier
            {
                IdentifierType = GlobalIdentifier.Type.LITERAL,
                Offset         = cppAssembly.metadataUsages[kvp.Key],
                Name           = $"{metadata.GetStringLiteralFromIndex(kvp.Value)}"
            })
                         );

            foreach (var kvp in metadata.metadataUsageDic[6]) //kIl2CppMetadataUsageMethodRef
            {
                var methodSpec = cppAssembly.methodSpecs[kvp.Value];
                var methodDef  = metadata.methodDefs[methodSpec.methodDefinitionIndex];
                var typeDef    = metadata.typeDefs[methodDef.declaringType];
                var typeName   = Utils.GetTypeName(metadata, cppAssembly, typeDef);
                if (methodSpec.classIndexIndex != -1)
                {
                    var classInst = cppAssembly.genericInsts[methodSpec.classIndexIndex];
                    typeName += Utils.GetGenericTypeParams(metadata, cppAssembly, classInst);
                }

                var methodName = typeName + "." + metadata.GetStringFromIndex(methodDef.nameIndex) + "()";
                if (methodSpec.methodIndexIndex != -1)
                {
                    var methodInst = cppAssembly.genericInsts[methodSpec.methodIndexIndex];
                    methodName += Utils.GetGenericTypeParams(metadata, cppAssembly, methodInst);
                }

                ret.Add(new GlobalIdentifier
                {
                    Name           = methodName,
                    IdentifierType = GlobalIdentifier.Type.METHOD,
                    Offset         = cppAssembly.metadataUsages[kvp.Key]
                });
            }

            return(ret);
        }