mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
接入obfuz->2.0
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 067341936b8cb2242be3bdc83f3ca3cd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,118 @@
|
||||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.PolymorphicWriter;
|
||||
using HybridCLR.Editor;
|
||||
using Obfuz;
|
||||
using Obfuz.Settings;
|
||||
using Obfuz.Unity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obfuz4HybridCLR
|
||||
{
|
||||
public static class ObfuscateUtil
|
||||
{
|
||||
public static string PackageName { get; } = "com.code-philosophy.obfuz4hybridclr";
|
||||
|
||||
public static string TemplatePathInPackage => $"Packages/{PackageName}/Templates~";
|
||||
|
||||
public static bool AreSameDirectory(string path1, string path2)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dir1 = new DirectoryInfo(path1);
|
||||
var dir2 = new DirectoryInfo(path2);
|
||||
|
||||
return dir1.FullName.TrimEnd('\\') == dir2.FullName.TrimEnd('\\');
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ObfuscateHotUpdateAssemblies(BuildTarget target, string outputDir)
|
||||
{
|
||||
string hotUpdateDllPath = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
|
||||
|
||||
AssemblySettings assemblySettings = ObfuzSettings.Instance.assemblySettings;
|
||||
ObfuscationProcess.ValidateReferences(hotUpdateDllPath, new HashSet<string>(assemblySettings.GetAssembliesToObfuscate()), new HashSet<string>(assemblySettings.GetObfuscationRelativeAssemblyNames()));
|
||||
var assemblySearchPaths = new List<string>
|
||||
{
|
||||
hotUpdateDllPath,
|
||||
};
|
||||
if (AreSameDirectory(hotUpdateDllPath, outputDir))
|
||||
{
|
||||
throw new Exception($"hotUpdateDllPath:{hotUpdateDllPath} can't be same to outputDir:{outputDir}");
|
||||
}
|
||||
Obfuscate(target, assemblySearchPaths, outputDir);
|
||||
foreach (string hotUpdateAssemblyName in SettingsUtil.HotUpdateAssemblyNamesExcludePreserved)
|
||||
{
|
||||
string srcFile = $"{hotUpdateDllPath}/{hotUpdateAssemblyName}.dll";
|
||||
string dstFile = $"{outputDir}/{hotUpdateAssemblyName}.dll";
|
||||
// only copy non obfuscated assemblies
|
||||
if (File.Exists(srcFile) && !File.Exists(dstFile))
|
||||
{
|
||||
File.Copy(srcFile, dstFile, true);
|
||||
Debug.Log($"[CompileAndObfuscateDll] Copy nonObfuscated assembly {srcFile} to {dstFile}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Obfuscate(BuildTarget target, List<string> assemblySearchPaths, string obfuscatedAssemblyOutputPath)
|
||||
{
|
||||
var obfuzSettings = ObfuzSettings.Instance;
|
||||
|
||||
var assemblySearchDirs = assemblySearchPaths;
|
||||
ObfuscatorBuilder builder = ObfuscatorBuilder.FromObfuzSettings(obfuzSettings, target, true);
|
||||
builder.InsertTopPriorityAssemblySearchPaths(assemblySearchDirs);
|
||||
builder.CoreSettingsFacade.obfuscatedAssemblyOutputPath = obfuscatedAssemblyOutputPath;
|
||||
|
||||
foreach (var assemblySearchDir in builder.CoreSettingsFacade.assemblySearchPaths)
|
||||
{
|
||||
if (AreSameDirectory(assemblySearchDir, obfuscatedAssemblyOutputPath))
|
||||
{
|
||||
throw new Exception($"assemblySearchDir:{assemblySearchDir} can't be same to ObfuscatedAssemblyOutputPath:{obfuscatedAssemblyOutputPath}");
|
||||
}
|
||||
}
|
||||
|
||||
Obfuscator obfuz = builder.Build();
|
||||
obfuz.Run();
|
||||
}
|
||||
|
||||
public static void GeneratePolymorphicDll(string originalDllPath, string outputDllPath)
|
||||
{
|
||||
ModuleDef oldMod = ModuleDefMD.Load(originalDllPath);
|
||||
var obfuzSettings = ObfuzSettings.Instance;
|
||||
|
||||
var opt = new NewDllModuleWriterOptions(oldMod)
|
||||
{
|
||||
MetadataWriter = new PolymorphicMetadataWriter(obfuzSettings.polymorphicDllSettings.codeGenerationSecretKey),
|
||||
};
|
||||
PolymorphicModuleWriter writer = new PolymorphicModuleWriter(oldMod, opt);
|
||||
writer.Write(outputDllPath);
|
||||
Debug.Log($"GeneratePolymorphicDll {originalDllPath} => {outputDllPath}");
|
||||
}
|
||||
|
||||
public static void GeneratePolymorphicCodes(string libil2cppDir)
|
||||
{
|
||||
PolymorphicDllSettings settings = ObfuzSettings.Instance.polymorphicDllSettings;
|
||||
if (!settings.enable)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("Polymorphic code generation is disabled in Obfuz settings.");
|
||||
return;
|
||||
}
|
||||
var options = new PolymorphicCodeGenerator.Options
|
||||
{
|
||||
GenerationSecretKey = settings.codeGenerationSecretKey,
|
||||
Libil2cppDir = libil2cppDir,
|
||||
TemplateDir = ObfuscateUtil.TemplatePathInPackage,
|
||||
DisableLoadStandardDll = settings.disableLoadStandardDll,
|
||||
};
|
||||
var generator = new PolymorphicCodeGenerator(options);
|
||||
generator.Generate();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7f5fe18513bcdd4c8960d908e88402e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Obfuz4HybridCLR.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:2373f786d14518f44b0f475db77ba4de",
|
||||
"GUID:66e09fc524ec6594b8d6ca1d91aa1a41"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3743e71edcd5bd8499007797ef02cbfb
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52d353fb8d6d94c4aa03452a2cd9773f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using dnlib.DotNet.PolymorphicWriter;
|
||||
using HybridCLR.Editor.Template;
|
||||
|
||||
public class PolymorphicCodeGenerator
|
||||
{
|
||||
public class Options
|
||||
{
|
||||
public string GenerationSecretKey { get; set; }
|
||||
|
||||
public string Libil2cppDir { get; set; }
|
||||
|
||||
public string TemplateDir { get; set; }
|
||||
|
||||
public bool DisableLoadStandardDll { get; set; } = true;
|
||||
}
|
||||
|
||||
private readonly string _libil2cppDir;
|
||||
private readonly string _metadataDir;
|
||||
private readonly string _templateDir;
|
||||
|
||||
private readonly string _generationSecretKey;
|
||||
private readonly bool _disableLoadStandardImage;
|
||||
|
||||
private readonly PolymorphicMetadataWriter writer;
|
||||
|
||||
public PolymorphicCodeGenerator(Options options)
|
||||
{
|
||||
_libil2cppDir = options.Libil2cppDir;
|
||||
_metadataDir = Path.Combine(_libil2cppDir, "hybridclr", "metadata");
|
||||
_templateDir = options.TemplateDir;
|
||||
|
||||
_generationSecretKey = options.GenerationSecretKey;
|
||||
_disableLoadStandardImage = options.DisableLoadStandardDll;
|
||||
|
||||
writer = new PolymorphicMetadataWriter(_generationSecretKey);
|
||||
}
|
||||
|
||||
private void CopyMetadataReaderHeader()
|
||||
{
|
||||
string srcFile = $"{_templateDir}/MetadataReader.h.tpl";
|
||||
string dstFile = $"{_metadataDir}/MetadataReader.h";
|
||||
File.Copy(srcFile, dstFile, true);
|
||||
UnityEngine.Debug.Log($"Copy MetadataReader header from {srcFile} to {dstFile}");
|
||||
}
|
||||
|
||||
private void GeneratePolymorphicDefs()
|
||||
{
|
||||
string tplFile = $"{_templateDir}/PolymorphicDefs.h.tpl";
|
||||
var frr = new FileRegionReplace(File.ReadAllText(tplFile, Encoding.UTF8));
|
||||
var lines = new List<string>();
|
||||
lines.Add($"#define POLYMORPHIC_IMAGE_SIGNATURE \"{writer.ImageSignature}\"");
|
||||
lines.Add($"\tconstexpr uint32_t kPolymorphicImageVersion = {writer.FormatVersion};");
|
||||
lines.Add($"\tconstexpr uint32_t kFormatVariantVersion = {writer.FormatVariant};");
|
||||
string codes = string.Join("\n", lines);
|
||||
frr.Replace("POLYMORPHIC_DEFINES", codes);
|
||||
|
||||
string outputFile = $"{_metadataDir}/PolymorphicDefs.h";
|
||||
frr.Commit(outputFile);
|
||||
}
|
||||
|
||||
private void GeneratePolymorphicDatas()
|
||||
{
|
||||
string tplFile = $"{_templateDir}/PolymorphicDatas.h.tpl";
|
||||
var frr = new FileRegionReplace(File.ReadAllText(tplFile, Encoding.UTF8));
|
||||
List<string> lines = new List<string>();
|
||||
var sb = new StringBuilder();
|
||||
foreach (var type in writer.GetPolymorphicTypes())
|
||||
{
|
||||
var polymorphicType = writer.GetPolymorphicClassDef(type);
|
||||
lines.Add($"\tstruct {type.Name}");
|
||||
lines.Add("\t{");
|
||||
foreach (var field in polymorphicType.Fields)
|
||||
{
|
||||
lines.Add($"\t\t{field.fieldWriter.CppTypeName} {field.name};");
|
||||
}
|
||||
|
||||
lines.Add("\t\tvoid Read(MetadataReader& reader)");
|
||||
lines.Add("\t\t{");
|
||||
|
||||
foreach (var field in polymorphicType.Fields)
|
||||
{
|
||||
lines.Add($"\t\t\t{field.fieldWriter.GetMarshalCode(field.name, "reader")};");
|
||||
}
|
||||
lines.Add("\t\t}");
|
||||
lines.Add("\t};");
|
||||
lines.Add("");
|
||||
}
|
||||
|
||||
string codes = string.Join("\n", lines);
|
||||
frr.Replace("POLYMORPHIC_DATA", codes);
|
||||
|
||||
|
||||
string outputFile = $"{_metadataDir}/PolymorphicDatas.h";
|
||||
frr.Commit(outputFile);
|
||||
}
|
||||
|
||||
private void GeneratePolymorphicRawImageHeader()
|
||||
{
|
||||
string tplFile = $"{_templateDir}/PolymorphicRawImage.h.tpl";
|
||||
var frr = new FileRegionReplace(File.ReadAllText(tplFile, Encoding.UTF8));
|
||||
|
||||
|
||||
var tableMetaInfoMap = TableMetaInfos.tableMetaInfos.ToDictionary(t => "Raw" + t.csharpTypeName + "Row");
|
||||
List<string> lines = new List<string>();
|
||||
foreach (Type rowType in writer.GetPolymorphicTableRowTypes())
|
||||
{
|
||||
TableMetaInfo table = tableMetaInfoMap[rowType.Name];
|
||||
|
||||
lines.Add($"\t\tvirtual Tb{table.cppTypeName} Read{table.cppTypeName}(uint32_t rawIndex) override;");
|
||||
}
|
||||
|
||||
frr.Replace("READ_TABLES_OVERRIDES", string.Join("\n", lines));
|
||||
|
||||
string outputFile = $"{_metadataDir}/PolymorphicRawImage.h";
|
||||
frr.Commit(outputFile);
|
||||
}
|
||||
|
||||
private void GeneratePolymorphicRawImageSource()
|
||||
{
|
||||
string tplFile = $"{_templateDir}/PolymorphicRawImage.cpp.tpl";
|
||||
var frr = new FileRegionReplace(File.ReadAllText(tplFile, Encoding.UTF8));
|
||||
|
||||
var tableMetaInfoMap = TableMetaInfos.tableMetaInfos.ToDictionary(t => "Raw" + t.csharpTypeName + "Row");
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
|
||||
foreach (Type rowType in writer.GetAllTableRowTypes())
|
||||
{
|
||||
TableMetaInfo table = tableMetaInfoMap[rowType.Name];
|
||||
PolymorphicClassDef polymorphicClassDef = writer.CreateTableRowClassDefForCodeGeneration(rowType);
|
||||
lines.Add("\t\t{");
|
||||
lines.Add($"\t\t\tauto& table = _tableRowMetas[(int)TableType::{table.cppEnumName}];");
|
||||
foreach (var fieldDef in polymorphicClassDef.Fields)
|
||||
{
|
||||
FieldMetaInfo field = table.fields.First(f => f.csharpName == fieldDef.name);
|
||||
lines.Add($"\t\t\ttable.push_back({{{field.cppRowSize}}});");
|
||||
}
|
||||
lines.Add("\t\t}");
|
||||
}
|
||||
string codes = string.Join("\n", lines);
|
||||
frr.Replace("TABLE_ROW_METADS", codes);
|
||||
}
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
foreach (Type rowType in writer.GetPolymorphicTableRowTypes())
|
||||
{
|
||||
TableMetaInfo table = tableMetaInfoMap[rowType.Name];
|
||||
PolymorphicClassDef polymorphicClassDef = writer.CreateTableRowClassDefForCodeGeneration(rowType);
|
||||
|
||||
lines.Add($"\tTb{table.cppTypeName} PolymorphicRawImage::Read{table.cppTypeName}(uint32_t rawIndex)");
|
||||
lines.Add("\t{");
|
||||
lines.Add($"\t\tIL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::{table.cppEnumName}).rowNum);");
|
||||
lines.Add($"\t\tconst byte* rowPtr = GetTableRowPtr(TableType::{table.cppEnumName}, rawIndex);");
|
||||
lines.Add($"\t\tauto& rowSchema = GetRowSchema(TableType::{table.cppEnumName});");
|
||||
lines.Add($"\t\tTb{table.cppTypeName} data;");
|
||||
for (int i = 0; i < polymorphicClassDef.Fields.Count; i++)
|
||||
{
|
||||
var fieldDef = polymorphicClassDef.Fields[i];
|
||||
FieldMetaInfo field = table.fields.First(f => f.csharpName == fieldDef.name);
|
||||
lines.Add($"\t\tdata.{field.cppName} = ReadColumn(rowPtr, rowSchema[{i}]);");
|
||||
}
|
||||
lines.Add("\t\treturn data;");
|
||||
lines.Add("\t}");
|
||||
}
|
||||
|
||||
frr.Replace("READ_TABLES_IMPLEMENTATIONS", string.Join("\n", lines));
|
||||
}
|
||||
string outputFile = $"{_metadataDir}/PolymorphicRawImage.cpp";
|
||||
frr.Commit(outputFile);
|
||||
}
|
||||
|
||||
private void GenerateRawImageInit()
|
||||
{
|
||||
string tplFile = $"{_metadataDir}/Image.cpp";
|
||||
var frr = new FileRegionReplace(File.ReadAllText(tplFile, Encoding.UTF8));
|
||||
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
lines.Add(@"#include ""PolymorphicRawImage.h""");
|
||||
|
||||
frr.Replace("INCLUDE_RAW_IMAGE_HEADERS", string.Join("\n", lines));
|
||||
}
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
|
||||
lines.Add("\t\tif (std::strncmp((const char*)imageData, \"CODEPHPY\", 8) == 0)");
|
||||
lines.Add("\t\t{");
|
||||
lines.Add("\t\t\t_rawImage = new PolymorphicRawImage();");
|
||||
lines.Add("\t\t}");
|
||||
lines.Add("\t\telse");
|
||||
lines.Add("\t\t{");
|
||||
if (_disableLoadStandardImage)
|
||||
{
|
||||
lines.Add("\t\t\treturn LoadImageErrorCode::UNKNOWN_IMAGE_FORMAT;");
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.Add("\t\t\t_rawImage = new RawImage();");
|
||||
}
|
||||
lines.Add("\t\t}");
|
||||
lines.Add("\t\treturn LoadImageErrorCode::OK;");
|
||||
|
||||
frr.Replace("INIT_RAW_IMAGE", string.Join("\n", lines));
|
||||
}
|
||||
|
||||
|
||||
frr.Commit(tplFile);
|
||||
}
|
||||
|
||||
public void Generate()
|
||||
{
|
||||
CopyMetadataReaderHeader();
|
||||
GeneratePolymorphicDefs();
|
||||
GeneratePolymorphicDatas();
|
||||
GeneratePolymorphicRawImageHeader();
|
||||
GeneratePolymorphicRawImageSource();
|
||||
GenerateRawImageInit();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b66b21680bfc8744682ea6536aa2ec77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,300 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
class FieldMetaInfo {
|
||||
public readonly string csharpName;
|
||||
public readonly string cppName;
|
||||
public readonly string cppRowSize;
|
||||
public FieldMetaInfo(string csharpName, string cppName, string cppRowSize) {
|
||||
this.csharpName = csharpName;
|
||||
this.cppName = cppName;
|
||||
this.cppRowSize = cppRowSize;
|
||||
}
|
||||
|
||||
public FieldMetaInfo(string csharpName, string cppRowSize) : this(csharpName, csharpName.Substring(0, 1).ToLower() + csharpName.Substring(1), cppRowSize) {
|
||||
}
|
||||
}
|
||||
|
||||
class TableMetaInfo {
|
||||
public readonly string csharpTypeName;
|
||||
public readonly string cppTypeName;
|
||||
public readonly string cppEnumName;
|
||||
public readonly List<FieldMetaInfo> fields;
|
||||
|
||||
public TableMetaInfo(string csharpTypeName, string cppTypeName, string cppEnumName, List<FieldMetaInfo> fields) {
|
||||
this.csharpTypeName = csharpTypeName;
|
||||
this.cppTypeName = cppTypeName;
|
||||
this.cppEnumName = cppEnumName;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
|
||||
public TableMetaInfo(string csharpTypeName, List<FieldMetaInfo> fields) : this(csharpTypeName, csharpTypeName, csharpTypeName.ToUpper(), fields) {
|
||||
}
|
||||
}
|
||||
|
||||
class TableMetaInfos {
|
||||
public static readonly List<TableMetaInfo> tableMetaInfos = new List<TableMetaInfo> {
|
||||
new TableMetaInfo("Module", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Generation", "2"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Mvid", "ComputGUIDIndexByte()"),
|
||||
new FieldMetaInfo("EncId", "ComputGUIDIndexByte()"),
|
||||
new FieldMetaInfo("EncBaseId", "ComputGUIDIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("TypeRef", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("ResolutionScope", "ComputTableIndexByte(TableType::MODULE, TableType::MODULEREF, TableType::ASSEMBLYREF, TableType::TYPEREF, TagBits::ResoulutionScope)"),
|
||||
new FieldMetaInfo("Name", "typeName", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Namespace", "typeNamespace", "ComputStringIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("TypeDef", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Flags", "4"),
|
||||
new FieldMetaInfo("Name", "typeName", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Namespace", "typeNamespace", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Extends", "ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)"),
|
||||
new FieldMetaInfo("FieldList", "ComputTableIndexByte(TableType::FIELD)"),
|
||||
new FieldMetaInfo("MethodList", "ComputTableIndexByte(TableType::METHOD)"),
|
||||
}),
|
||||
new TableMetaInfo("FieldPtr", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Field", "ComputTableIndexByte(TableType::FIELD)"),
|
||||
}),
|
||||
new TableMetaInfo("Field", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Flags", "2"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Signature", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("MethodPtr", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Method", "ComputTableIndexByte(TableType::METHOD)"),
|
||||
}),
|
||||
new TableMetaInfo("Method", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("RVA", "rva", "4"),
|
||||
new FieldMetaInfo("ImplFlags", "2"),
|
||||
new FieldMetaInfo("Flags", "2"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Signature", "ComputBlobIndexByte()"),
|
||||
new FieldMetaInfo("ParamList", "ComputTableIndexByte(TableType::PARAM)"),
|
||||
}),
|
||||
new TableMetaInfo("ParamPtr", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Param", "ComputTableIndexByte(TableType::PARAM)"),
|
||||
}),
|
||||
new TableMetaInfo("Param", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Flags", "2"),
|
||||
new FieldMetaInfo("Sequence", "2"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("InterfaceImpl", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Class", "classIdx", "ComputTableIndexByte(TableType::TYPEDEF)"),
|
||||
new FieldMetaInfo("Interface", "interfaceIdx", "ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)"),
|
||||
}),
|
||||
new TableMetaInfo("MemberRef", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Class", "classIdx", "ComputTableIndexByte(TableType::METHOD, TableType::MODULEREF, TableType::TYPEDEF, TableType::TYPEREF, TagBits::MemberRefParent)"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Signature", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("Constant", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Type", "1"),
|
||||
new FieldMetaInfo("Padding", "1"),
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(TableType::PARAM, TableType::FIELD, TableType::PROPERTY, TagBits::HasConstant)"),
|
||||
new FieldMetaInfo("Value", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("CustomAttribute", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(HasCustomAttributeAssociateTables, sizeof(HasCustomAttributeAssociateTables) / sizeof(TableType), TagBits::HasCustomAttribute)"),
|
||||
new FieldMetaInfo("Type", "ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::CustomAttributeType)"),
|
||||
new FieldMetaInfo("Value", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("FieldMarshal", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(TableType::FIELD, TableType::PARAM, TagBits::HasFieldMarshal)"),
|
||||
new FieldMetaInfo("NativeType", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("DeclSecurity", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Action", "2"),
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(TableType::TYPEDEF, TableType::METHOD, TableType::ASSEMBLY, TagBits::HasDeclSecurity)"),
|
||||
new FieldMetaInfo("PermissionSet", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("ClassLayout", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("PackingSize", "2"),
|
||||
new FieldMetaInfo("ClassSize", "4"),
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(TableType::TYPEDEF)"),
|
||||
}),
|
||||
new TableMetaInfo("FieldLayout", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("OffSet", "offset", "4"),
|
||||
new FieldMetaInfo("Field", "ComputTableIndexByte(TableType::FIELD)"),
|
||||
}),
|
||||
new TableMetaInfo("StandAloneSig", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Signature", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("EventMap", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(TableType::TYPEDEF)"),
|
||||
new FieldMetaInfo("EventList", "ComputTableIndexByte(TableType::EVENT)"),
|
||||
}),
|
||||
new TableMetaInfo("EventPtr", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Event", "ComputTableIndexByte(TableType::EVENT)"),
|
||||
}),
|
||||
new TableMetaInfo("Event", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("EventFlags", "2"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("EventType", "ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)"),
|
||||
}),
|
||||
new TableMetaInfo("PropertyMap", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(TableType::TYPEDEF)"),
|
||||
new FieldMetaInfo("PropertyList", "ComputTableIndexByte(TableType::PROPERTY)"),
|
||||
}),
|
||||
new TableMetaInfo("PropertyPtr", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Property", "ComputTableIndexByte(TableType::PROPERTY)"),
|
||||
}),
|
||||
new TableMetaInfo("Property", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("PropFlags", "flags", "2"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Type", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("MethodSemantics", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Semantic", "semantics", "2"),
|
||||
new FieldMetaInfo("Method", "ComputTableIndexByte(TableType::METHOD)"),
|
||||
new FieldMetaInfo("Association", "ComputTableIndexByte(TableType::EVENT, TableType::PROPERTY, TagBits::HasSemantics)"),
|
||||
}),
|
||||
new TableMetaInfo("MethodImpl", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Class", "classIdx", "ComputTableIndexByte(TableType::TYPEDEF)"),
|
||||
new FieldMetaInfo("MethodBody", "ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::MethodDefOrRef)"),
|
||||
new FieldMetaInfo("MethodDeclaration", "ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::MethodDefOrRef)"),
|
||||
}),
|
||||
new TableMetaInfo("ModuleRef", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("TypeSpec", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Signature", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("ImplMap", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("MappingFlags", "2"),
|
||||
new FieldMetaInfo("MemberForwarded", "ComputTableIndexByte(TableType::FIELD, TableType::METHOD, TagBits::MemberForwarded)"),
|
||||
new FieldMetaInfo("ImportName", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("ImportScope", "ComputTableIndexByte(TableType::MODULEREF)"),
|
||||
}),
|
||||
new TableMetaInfo("FieldRVA", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("RVA", "rva", "4"),
|
||||
new FieldMetaInfo("Field", "ComputTableIndexByte(TableType::FIELD)"),
|
||||
}),
|
||||
new TableMetaInfo("ENCLog","EncLog", "ENCLOG", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Token", "4"),
|
||||
new FieldMetaInfo("FuncCode", "4"),
|
||||
}),
|
||||
new TableMetaInfo("ENCMap", "EncMap", "ENCMAP", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Token", "4"),
|
||||
}),
|
||||
new TableMetaInfo("Assembly", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("HashAlgId", "4"),
|
||||
new FieldMetaInfo("MajorVersion", "2"),
|
||||
new FieldMetaInfo("MinorVersion", "2"),
|
||||
new FieldMetaInfo("BuildNumber", "2"),
|
||||
new FieldMetaInfo("RevisionNumber", "2"),
|
||||
new FieldMetaInfo("Flags", "4"),
|
||||
new FieldMetaInfo("PublicKey", "ComputBlobIndexByte()"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Locale", "ComputStringIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("AssemblyProcessor", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Processor", "4"),
|
||||
}),
|
||||
new TableMetaInfo("AssemblyOS", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("OSPlatformId", "osPlatformId", "4"),
|
||||
new FieldMetaInfo("OSMajorVersion", "osMajorVersion", "4"),
|
||||
new FieldMetaInfo("OSMinorVersion", "osMinorVersion", "4"),
|
||||
}),
|
||||
new TableMetaInfo("AssemblyRef", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("MajorVersion", "2"),
|
||||
new FieldMetaInfo("MinorVersion", "2"),
|
||||
new FieldMetaInfo("BuildNumber", "2"),
|
||||
new FieldMetaInfo("RevisionNumber", "2"),
|
||||
new FieldMetaInfo("Flags", "4"),
|
||||
new FieldMetaInfo("PublicKeyOrToken", "ComputBlobIndexByte()"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Locale", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("HashValue", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("AssemblyRefProcessor", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("AssemblyRef", "4"),
|
||||
new FieldMetaInfo("Processor", "ComputTableIndexByte(TableType::ASSEMBLYREF)"),
|
||||
}),
|
||||
new TableMetaInfo("AssemblyRefOS", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("OSPlatformId", "osPlatformId", "4"),
|
||||
new FieldMetaInfo("OSMajorVersion", "osMajorVersion", "4"),
|
||||
new FieldMetaInfo("OSMinorVersion", "osMinorVersion", "4"),
|
||||
new FieldMetaInfo("AssemblyRef", "ComputTableIndexByte(TableType::ASSEMBLYREF)"),
|
||||
}),
|
||||
new TableMetaInfo("File", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Flags", "4"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("HashValue", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("ExportedType", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Flags", "4"),
|
||||
new FieldMetaInfo("TypeDefId", "4"),
|
||||
new FieldMetaInfo("TypeName", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("TypeNamespace", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Implementation", "ComputTableIndexByte(TableType::FILE, TableType::EXPORTEDTYPE, TableType::ASSEMBLY, TagBits::Implementation)"),
|
||||
}),
|
||||
new TableMetaInfo("ManifestResource", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Offset", "4"),
|
||||
new FieldMetaInfo("Flags", "4"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Implementation", "ComputTableIndexByte(TableType::FILE, TableType::ASSEMBLYREF, TagBits::Implementation)"),
|
||||
}),
|
||||
new TableMetaInfo("NestedClass", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("NestedClass", "ComputTableIndexByte(TableType::TYPEDEF)"),
|
||||
new FieldMetaInfo("EnclosingClass", "ComputTableIndexByte(TableType::TYPEDEF)"),
|
||||
}),
|
||||
new TableMetaInfo("GenericParam", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Number", "2"),
|
||||
new FieldMetaInfo("Flags", "2"),
|
||||
new FieldMetaInfo("Owner", "ComputTableIndexByte(TableType::TYPEDEF, TableType::METHOD, TagBits::TypeOrMethodDef)"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("MethodSpec", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Method", "ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::MethodDefOrRef)"),
|
||||
new FieldMetaInfo("Instantiation", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("GenericParamConstraint", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Owner", "ComputTableIndexByte(TableType::GENERICPARAM)"),
|
||||
new FieldMetaInfo("Constraint", "ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)"),
|
||||
}),
|
||||
|
||||
new TableMetaInfo("Document", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Name", "ComputBlobIndexByte()"),
|
||||
new FieldMetaInfo("HashAlgorithm", "ComputGUIDIndexByte()"),
|
||||
new FieldMetaInfo("Hash", "ComputBlobIndexByte()"),
|
||||
new FieldMetaInfo("Language", "ComputGUIDIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("MethodDebugInformation", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Document", "ComputTableIndexByte(TableType::DOCUMENT)"),
|
||||
new FieldMetaInfo("SequencePoints", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("LocalScope", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Method", "ComputTableIndexByte(TableType::METHOD)"),
|
||||
new FieldMetaInfo("ImportScope", "ComputTableIndexByte(TableType::IMPORTSCOPE)"),
|
||||
new FieldMetaInfo("VariableList", "variables", "ComputTableIndexByte(TableType::LOCALVARIABLE)"),
|
||||
new FieldMetaInfo("ConstantList", "constants", "ComputTableIndexByte(TableType::LOCALCONSTANT)"),
|
||||
new FieldMetaInfo("StartOffset", "4"),
|
||||
new FieldMetaInfo("Length", "4"),
|
||||
}),
|
||||
new TableMetaInfo("LocalVariable", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Attributes", "2"),
|
||||
new FieldMetaInfo("Index", "2"),
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("LocalConstant", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Name", "ComputStringIndexByte()"),
|
||||
new FieldMetaInfo("Signature", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("ImportScope", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(TableType::IMPORTSCOPE)"),
|
||||
new FieldMetaInfo("Imports", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
new TableMetaInfo("StateMachineMethod", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("MoveNextMethod", "ComputTableIndexByte(TableType::METHOD)"),
|
||||
new FieldMetaInfo("KickoffMethod", "ComputTableIndexByte(TableType::METHOD)"),
|
||||
}),
|
||||
new TableMetaInfo("CustomDebugInformation", new List<FieldMetaInfo> {
|
||||
new FieldMetaInfo("Parent", "ComputTableIndexByte(HasCustomDebugInformation, sizeof(HasCustomDebugInformation) / sizeof(TableType), TagBits::HasCustomDebugInformation)"),
|
||||
new FieldMetaInfo("Kind", "ComputGUIDIndexByte()"),
|
||||
new FieldMetaInfo("Value", "ComputBlobIndexByte()"),
|
||||
}),
|
||||
};
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef98af767d086bd428f52503188789b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,164 @@
|
||||
using HybridCLR.Editor.Commands;
|
||||
using HybridCLR.Editor;
|
||||
using Obfuz.Settings;
|
||||
using Obfuz;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.IO;
|
||||
using HybridCLR.Editor.Link;
|
||||
using HybridCLR.Editor.Meta;
|
||||
using UnityEditor.Build;
|
||||
using HybridCLR.Editor.Installer;
|
||||
using HybridCLR.Editor.MethodBridge;
|
||||
using System.Linq;
|
||||
using Analyzer = HybridCLR.Editor.MethodBridge.Analyzer;
|
||||
using HybridCLR.Editor.Settings;
|
||||
using Obfuz.Utils;
|
||||
using FileUtil = Obfuz.Utils.FileUtil;
|
||||
using IAssemblyResolver = HybridCLR.Editor.Meta.IAssemblyResolver;
|
||||
using CombinedAssemblyResolver = HybridCLR.Editor.Meta.CombinedAssemblyResolver;
|
||||
using MetaUtil = HybridCLR.Editor.Meta.MetaUtil;
|
||||
using AssemblyCache = HybridCLR.Editor.Meta.AssemblyCache;
|
||||
using HybridCLR.Editor.AOT;
|
||||
using Analyzer2 = HybridCLR.Editor.AOT.Analyzer;
|
||||
|
||||
namespace Obfuz4HybridCLR
|
||||
{
|
||||
public static class PrebuildCommandExt
|
||||
{
|
||||
public static string GetObfuscatedHotUpdateAssemblyOutputPath(BuildTarget target)
|
||||
{
|
||||
return $"{ObfuzSettings.Instance.ObfuzRootDir}/{target}/ObfuscatedHotUpdateAssemblies";
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("HybridCLR/ObfuzExtension/GenerateAll")]
|
||||
public static void GenerateAll()
|
||||
{
|
||||
var installer = new InstallerController();
|
||||
if (!installer.HasInstalledHybridCLR())
|
||||
{
|
||||
throw new BuildFailedException($"You have not initialized HybridCLR, please install it via menu 'HybridCLR/Installer'");
|
||||
}
|
||||
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
|
||||
CompileDllCommand.CompileDll(target);
|
||||
Il2CppDefGeneratorCommand.GenerateIl2CppDef();
|
||||
GeneratePolymorphicCodesWhenEnable();
|
||||
LinkGeneratorCommand.GenerateLinkXml(target);
|
||||
StripAOTDllCommand.GenerateStripedAOTDlls(target);
|
||||
|
||||
string obfuscatedHotUpdateDllPath = GetObfuscatedHotUpdateAssemblyOutputPath(target);
|
||||
ObfuscateUtil.ObfuscateHotUpdateAssemblies(target, obfuscatedHotUpdateDllPath);
|
||||
GenerateMethodBridgeAndReversePInvokeWrapper(target, obfuscatedHotUpdateDllPath);
|
||||
GenerateAOTGenericReference(target, obfuscatedHotUpdateDllPath);
|
||||
}
|
||||
|
||||
[MenuItem("HybridCLR/ObfuzExtension/CompileAndObfuscateDll")]
|
||||
public static void CompileAndObfuscateDll()
|
||||
{
|
||||
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
|
||||
CompileDllCommand.CompileDll(target);
|
||||
|
||||
string obfuscatedHotUpdateDllPath = GetObfuscatedHotUpdateAssemblyOutputPath(target);
|
||||
ObfuscateUtil.ObfuscateHotUpdateAssemblies(target, obfuscatedHotUpdateDllPath);
|
||||
}
|
||||
|
||||
[MenuItem("HybridCLR/ObfuzExtension/GeneratePolymorphicCodes")]
|
||||
public static void GeneratePolymorphicCodes()
|
||||
{
|
||||
ObfuscateUtil.GeneratePolymorphicCodes($"{SettingsUtil.LocalIl2CppDir}/libil2cpp");
|
||||
}
|
||||
|
||||
private static void GeneratePolymorphicCodesWhenEnable()
|
||||
{
|
||||
PolymorphicDllSettings settings = ObfuzSettings.Instance.polymorphicDllSettings;
|
||||
if (!settings.enable)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("Polymorphic code generation is disabled.");
|
||||
return;
|
||||
}
|
||||
GeneratePolymorphicCodes();
|
||||
}
|
||||
|
||||
public static IAssemblyResolver CreateObfuscatedHotUpdateAssemblyResolver(BuildTarget target, List<string> obfuscatedHotUpdateAssemblies, string obfuscatedHotUpdateDllPath)
|
||||
{
|
||||
return new FixedSetAssemblyResolver(obfuscatedHotUpdateDllPath, obfuscatedHotUpdateAssemblies);
|
||||
}
|
||||
|
||||
public static IAssemblyResolver CreateObfuscatedHotUpdateAndAOTAssemblyResolver(BuildTarget target, List<string> hotUpdateAssemblies, List<string> assembliesToObfuscate, string obfuscatedHotUpdateDllPath)
|
||||
{
|
||||
return new CombinedAssemblyResolver(
|
||||
CreateObfuscatedHotUpdateAssemblyResolver(target, hotUpdateAssemblies.Intersect(assembliesToObfuscate).ToList(), obfuscatedHotUpdateDllPath),
|
||||
MetaUtil.CreateHotUpdateAssemblyResolver(target, hotUpdateAssemblies.Except(assembliesToObfuscate).ToList()),
|
||||
MetaUtil.CreateAOTAssemblyResolver(target)
|
||||
);
|
||||
}
|
||||
|
||||
public static void GenerateMethodBridgeAndReversePInvokeWrapper(BuildTarget target, string obfuscatedHotUpdateDllPath)
|
||||
{
|
||||
string aotDllDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
|
||||
List<string> aotAssemblyNames = Directory.Exists(aotDllDir) ?
|
||||
Directory.GetFiles(aotDllDir, "*.dll", SearchOption.TopDirectoryOnly).Select(Path.GetFileNameWithoutExtension).ToList()
|
||||
: new List<string>();
|
||||
if (aotAssemblyNames.Count == 0)
|
||||
{
|
||||
throw new Exception($"no aot assembly found. please run `HybridCLR/Generate/All` or `HybridCLR/Generate/AotDlls` to generate aot dlls before runing `HybridCLR/Generate/MethodBridge`");
|
||||
}
|
||||
AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateAOTAssemblyResolver(target), aotAssemblyNames);
|
||||
|
||||
var methodBridgeAnalyzer = new Analyzer(new Analyzer.Options
|
||||
{
|
||||
MaxIterationCount = Math.Min(20, SettingsUtil.HybridCLRSettings.maxMethodBridgeGenericIteration),
|
||||
Collector = collector,
|
||||
});
|
||||
|
||||
methodBridgeAnalyzer.Run();
|
||||
|
||||
List<string> hotUpdateDlls = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;
|
||||
var cache = new AssemblyCache(CreateObfuscatedHotUpdateAndAOTAssemblyResolver(target, hotUpdateDlls, ObfuzSettings.Instance.assemblySettings.GetAssembliesToObfuscate(), obfuscatedHotUpdateDllPath));
|
||||
|
||||
var reversePInvokeAnalyzer = new MonoPInvokeCallbackAnalyzer(cache, hotUpdateDlls);
|
||||
reversePInvokeAnalyzer.Run();
|
||||
|
||||
var calliAnalyzer = new CalliAnalyzer(cache, hotUpdateDlls);
|
||||
calliAnalyzer.Run();
|
||||
var pinvokeAnalyzer = new PInvokeAnalyzer(cache, hotUpdateDlls);
|
||||
pinvokeAnalyzer.Run();
|
||||
var callPInvokeMethodSignatures = pinvokeAnalyzer.PInvokeMethodSignatures;
|
||||
|
||||
string templateFile = $"{SettingsUtil.TemplatePathInPackage}/MethodBridge.cpp.tpl";
|
||||
string outputFile = $"{SettingsUtil.GeneratedCppDir}/MethodBridge.cpp";
|
||||
|
||||
var callNativeMethodSignatures = calliAnalyzer.CalliMethodSignatures.Concat(pinvokeAnalyzer.PInvokeMethodSignatures).ToList();
|
||||
|
||||
var generateMethodBridgeMethod = typeof(MethodBridgeGeneratorCommand).GetMethod("GenerateMethodBridgeCppFile", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
generateMethodBridgeMethod.Invoke(null, new object[] { methodBridgeAnalyzer.GenericMethods, reversePInvokeAnalyzer.ReversePInvokeMethods, callNativeMethodSignatures, templateFile, outputFile });
|
||||
|
||||
MethodBridgeGeneratorCommand.CleanIl2CppBuildCache();
|
||||
}
|
||||
|
||||
public static void GenerateAOTGenericReference(BuildTarget target, string obfuscatedHotUpdateDllPath)
|
||||
{
|
||||
var gs = SettingsUtil.HybridCLRSettings;
|
||||
List<string> hotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;
|
||||
|
||||
AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(
|
||||
CreateObfuscatedHotUpdateAndAOTAssemblyResolver(target, hotUpdateDllNames, ObfuzSettings.Instance.assemblySettings.GetAssembliesToObfuscate(), obfuscatedHotUpdateDllPath), hotUpdateDllNames);
|
||||
var analyzer = new Analyzer2(new Analyzer2.Options
|
||||
{
|
||||
MaxIterationCount = Math.Min(20, gs.maxGenericReferenceIteration),
|
||||
Collector = collector,
|
||||
});
|
||||
|
||||
analyzer.Run();
|
||||
|
||||
var writer = new GenericReferenceWriter();
|
||||
writer.Write(analyzer.AotGenericTypes.ToList(), analyzer.AotGenericMethods.ToList(), $"{Application.dataPath}/{gs.outputAOTGenericReferenceFile}");
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afc965e1afdfc8e47b8a70be7a93cf25
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Code Philosophy(代码哲学)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3036602f815e31341b4445f0e331b58e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,2 @@
|
||||
# obfuz4hybridclr
|
||||
obfuz4hybridclr is a obfuz extension for HybridCLR.
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ab25e7bb5a8e7d4fb3ba4614f2e3822
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include "MetadataUtil.h"
|
||||
|
||||
namespace hybridclr
|
||||
{
|
||||
namespace metadata
|
||||
{
|
||||
struct ByteSpan
|
||||
{
|
||||
const byte* data;
|
||||
uint32_t length;
|
||||
ByteSpan() : data(nullptr), length(0) {}
|
||||
ByteSpan(const byte* data, uint32_t length) : data(data), length(length) {}
|
||||
};
|
||||
|
||||
class MetadataReader
|
||||
{
|
||||
private:
|
||||
const byte* _data;
|
||||
public:
|
||||
MetadataReader(const byte* data) : _data(data) {}
|
||||
int16_t ReadInt16()
|
||||
{
|
||||
int16_t value = GetI2LittleEndian(_data);
|
||||
_data += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
bool ReadBool()
|
||||
{
|
||||
return *(_data++) != 0;
|
||||
}
|
||||
|
||||
uint8_t ReadUInt8()
|
||||
{
|
||||
return *(_data++);
|
||||
}
|
||||
|
||||
uint16_t ReadUInt16()
|
||||
{
|
||||
uint16_t value = GetU2LittleEndian(_data);
|
||||
_data += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
int32_t ReadInt32()
|
||||
{
|
||||
int32_t value = GetI4LittleEndian(_data);
|
||||
_data += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t ReadUInt32()
|
||||
{
|
||||
uint32_t value = GetU4LittleEndian(_data);
|
||||
_data += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
int64_t ReadInt64()
|
||||
{
|
||||
int64_t value = GetI8LittleEndian(_data);
|
||||
_data += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t ReadUInt64()
|
||||
{
|
||||
uint64_t value = GetU8LittleEndian(_data);
|
||||
_data += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
const byte* ReadFixedBytes(int32_t byteCount)
|
||||
{
|
||||
const byte* value = _data;
|
||||
_data += byteCount;
|
||||
return value;
|
||||
}
|
||||
|
||||
ByteSpan ReadBytes()
|
||||
{
|
||||
uint32_t byteCount = ReadUInt32();
|
||||
const byte* buffer = _data;
|
||||
_data += byteCount;
|
||||
return ByteSpan(buffer, byteCount);
|
||||
}
|
||||
|
||||
const byte* CurrentDataPtr() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
#include "MetadataReader.h"
|
||||
|
||||
namespace hybridclr
|
||||
{
|
||||
namespace metadata
|
||||
{
|
||||
//!!!{{POLYMORPHIC_DATA
|
||||
struct HeaderBaseData
|
||||
{
|
||||
uint32_t metadataSize;
|
||||
uint32_t sectionCount;
|
||||
const byte* dummyData;
|
||||
uint32_t metadataRva;
|
||||
uint32_t entryPointToken;
|
||||
void Read(MetadataReader& reader)
|
||||
{
|
||||
metadataSize = reader.ReadUInt32();
|
||||
sectionCount = reader.ReadUInt32();
|
||||
dummyData = reader.ReadFixedBytes(8);
|
||||
metadataRva = reader.ReadUInt32();
|
||||
entryPointToken = reader.ReadUInt32();
|
||||
}
|
||||
};
|
||||
|
||||
struct SectionData
|
||||
{
|
||||
uint32_t rva;
|
||||
uint32_t fileOffset;
|
||||
uint32_t virtualSize;
|
||||
uint32_t fileLength;
|
||||
void Read(MetadataReader& reader)
|
||||
{
|
||||
rva = reader.ReadUInt32();
|
||||
fileOffset = reader.ReadUInt32();
|
||||
virtualSize = reader.ReadUInt32();
|
||||
fileLength = reader.ReadUInt32();
|
||||
}
|
||||
};
|
||||
|
||||
struct MetadataHeaderBaseData
|
||||
{
|
||||
uint32_t signature;
|
||||
uint8_t reserved2;
|
||||
ByteSpan versionString;
|
||||
uint16_t majorVersion;
|
||||
uint16_t heapsCount;
|
||||
uint32_t reserved1;
|
||||
uint8_t storageFlags;
|
||||
uint16_t minorVersion;
|
||||
void Read(MetadataReader& reader)
|
||||
{
|
||||
signature = reader.ReadUInt32();
|
||||
reserved2 = reader.ReadUInt8();
|
||||
versionString = reader.ReadBytes();
|
||||
majorVersion = reader.ReadUInt16();
|
||||
heapsCount = reader.ReadUInt16();
|
||||
reserved1 = reader.ReadUInt32();
|
||||
storageFlags = reader.ReadUInt8();
|
||||
minorVersion = reader.ReadUInt16();
|
||||
}
|
||||
};
|
||||
|
||||
struct TablesHeapHeaderBaseData
|
||||
{
|
||||
uint64_t validMask;
|
||||
uint32_t reserved1;
|
||||
uint8_t streamFlags;
|
||||
uint8_t majorVersion;
|
||||
uint64_t sortedMask;
|
||||
uint8_t minorVersion;
|
||||
uint8_t log2Rid;
|
||||
void Read(MetadataReader& reader)
|
||||
{
|
||||
validMask = reader.ReadUInt64();
|
||||
reserved1 = reader.ReadUInt32();
|
||||
streamFlags = reader.ReadUInt8();
|
||||
majorVersion = reader.ReadUInt8();
|
||||
sortedMask = reader.ReadUInt64();
|
||||
minorVersion = reader.ReadUInt8();
|
||||
log2Rid = reader.ReadUInt8();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//!!!}}POLYMORPHIC_DATA
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "MetadataReader.h"
|
||||
|
||||
namespace hybridclr
|
||||
{
|
||||
namespace metadata
|
||||
{
|
||||
//!!!{{POLYMORPHIC_DEFINES
|
||||
#define POLYMORPHIC_IMAGE_SIGNATURE "CODEPHPY"
|
||||
constexpr uint32_t kPolymorphicImageVersion = 1;
|
||||
constexpr uint32_t kFormatVariantVersion = 0;
|
||||
|
||||
//!!!}}POLYMORPHIC_DEFINES
|
||||
|
||||
struct PolymorphicImageHeaderData
|
||||
{
|
||||
const byte* signature;
|
||||
uint32_t formatVersion;
|
||||
uint32_t formatVariant;
|
||||
void Read(MetadataReader& reader)
|
||||
{
|
||||
signature = reader.ReadFixedBytes(8);
|
||||
formatVersion = reader.ReadUInt32();
|
||||
formatVariant = reader.ReadUInt32();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,897 @@
|
||||
#include "PolymorphicRawImage.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "PolymorphicDefs.h"
|
||||
#include "PolymorphicDatas.h"
|
||||
|
||||
namespace hybridclr
|
||||
{
|
||||
namespace metadata
|
||||
{
|
||||
|
||||
struct RawSectionHeader
|
||||
{
|
||||
uint32_t fileOffset;
|
||||
uint32_t fileLength;
|
||||
uint32_t rva;
|
||||
uint32_t virtualSize;
|
||||
};
|
||||
|
||||
LoadImageErrorCode PolymorphicRawImage::LoadCLIHeader(uint32_t& entryPointToken, uint32_t& metadataRva, uint32_t& metadataSize)
|
||||
{
|
||||
if (_imageLength < 0x100)
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
|
||||
MetadataReader reader(_imageData);
|
||||
|
||||
PolymorphicImageHeaderData imageHeaderData = {};
|
||||
imageHeaderData.Read(reader);
|
||||
|
||||
const char* sig = (const char*)_imageData;
|
||||
if (std::strncmp((const char*)imageHeaderData.signature, POLYMORPHIC_IMAGE_SIGNATURE, sizeof(POLYMORPHIC_IMAGE_SIGNATURE) - 1))
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
if (imageHeaderData.formatVersion != kPolymorphicImageVersion)
|
||||
{
|
||||
return LoadImageErrorCode::UNSUPPORT_FORMAT_VERSION;
|
||||
}
|
||||
if (imageHeaderData.formatVariant != kFormatVariantVersion)
|
||||
{
|
||||
return LoadImageErrorCode::UNMATCH_FORMAT_VARIANT;
|
||||
}
|
||||
|
||||
//reader.ReadFixedBytes(polymorphic::kImageHeaderDummyDataSize); // Skip dummy data
|
||||
|
||||
PolymorphicHeaderBaseData headerBaseData = {};
|
||||
headerBaseData.Read(reader);
|
||||
|
||||
const size_t kEntryPointTokenOffset = 16;
|
||||
entryPointToken = headerBaseData.entryPointToken;
|
||||
metadataRva = headerBaseData.metadataRva;
|
||||
metadataSize = headerBaseData.metadataSize;
|
||||
|
||||
uint32_t sectionCount = headerBaseData.sectionCount;
|
||||
for (uint32_t i = 0; i < sectionCount; i++)
|
||||
{
|
||||
PolymorphicSectionData sectionData = {};
|
||||
sectionData.Read(reader);
|
||||
_sections.push_back({ sectionData.rva, sectionData.rva + sectionData.virtualSize, sectionData.fileOffset - sectionData.rva });
|
||||
}
|
||||
return LoadImageErrorCode::OK;
|
||||
}
|
||||
|
||||
LoadImageErrorCode PolymorphicRawImage::LoadStreamHeaders(uint32_t metadataRva, uint32_t metadataSize)
|
||||
{
|
||||
uint32_t metaOffset;
|
||||
if (!TranslateRVAToImageOffset(metadataRva, metaOffset))
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
if (metaOffset >= _imageLength)
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
|
||||
const byte* ptrMetaData = _imageData + metaOffset;
|
||||
MetadataReader reader(ptrMetaData);
|
||||
|
||||
PolymorphicMetadataHeaderBaseData metadataHeader = {};
|
||||
metadataHeader.Read(reader);
|
||||
if (metadataHeader.signature != 0x424A5342)
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
|
||||
uint16_t numStreamHeader = metadataHeader.heapsCount;
|
||||
const StreamHeader* ptrStreamHeaders = (const StreamHeader*)(reader.CurrentDataPtr());
|
||||
|
||||
const StreamHeader* curSH = ptrStreamHeaders;
|
||||
const size_t maxStreamNameSize = 16;
|
||||
for (int i = 0; i < numStreamHeader; i++)
|
||||
{
|
||||
//std::cout << "name:" << (char*)curSH->name << ", offset:" << curSH->offset << ", size:" << curSH->size << std::endl;
|
||||
|
||||
if (curSH->offset >= metadataSize)
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
CliStream* rs = nullptr;
|
||||
CliStream nonStandardStream;
|
||||
CliStream pdbStream;
|
||||
if (!std::strncmp(curSH->name, "#~", maxStreamNameSize))
|
||||
{
|
||||
rs = &_streamTables;
|
||||
}
|
||||
else if (!std::strncmp(curSH->name, "#Strings", maxStreamNameSize))
|
||||
{
|
||||
rs = &_streamStringHeap;
|
||||
}
|
||||
else if (!std::strncmp(curSH->name, "#US", maxStreamNameSize))
|
||||
{
|
||||
rs = &_streamUS;
|
||||
}
|
||||
else if (!std::strncmp(curSH->name, "#GUID", maxStreamNameSize))
|
||||
{
|
||||
rs = &_streamGuidHeap;
|
||||
if (curSH->size % 16 != 0)
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
}
|
||||
else if (!std::strncmp(curSH->name, "#Blob", maxStreamNameSize))
|
||||
{
|
||||
rs = &_streamBlobHeap;
|
||||
}
|
||||
else if (!std::strncmp(curSH->name, "#-", maxStreamNameSize))
|
||||
{
|
||||
rs = &nonStandardStream;
|
||||
}
|
||||
else if (!std::strncmp(curSH->name, "#Pdb", maxStreamNameSize))
|
||||
{
|
||||
rs = &pdbStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cerr << "unknown stream name:" << curSH->name << std::endl;
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
rs->data = ptrMetaData + curSH->offset;
|
||||
rs->size = curSH->size;
|
||||
rs->name = curSH->name;
|
||||
size_t sizeOfStream = 8 + (std::strlen(curSH->name) / 4 + 1) * 4;
|
||||
curSH = (const StreamHeader*)((byte*)curSH + sizeOfStream);
|
||||
}
|
||||
return LoadImageErrorCode::OK;
|
||||
}
|
||||
|
||||
LoadImageErrorCode PolymorphicRawImage::LoadTables()
|
||||
{
|
||||
MetadataReader reader(_streamTables.data);
|
||||
|
||||
PolymorphicTablesHeapHeaderBaseData heapHeader = {};
|
||||
heapHeader.Read(reader);
|
||||
|
||||
if (heapHeader.reserved1 != 0 || heapHeader.majorVersion != 2 || heapHeader.minorVersion != 0)
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
if ((heapHeader.streamFlags & ~0x7))
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
_4byteStringIndex = heapHeader.streamFlags & 0x1;
|
||||
_4byteGUIDIndex = heapHeader.streamFlags & 0x2;
|
||||
_4byteBlobIndex = heapHeader.streamFlags & 0x4;
|
||||
|
||||
uint64_t validMask = ((uint64_t)1 << TABLE_NUM) - 1;
|
||||
if (heapHeader.validMask & ~validMask)
|
||||
{
|
||||
return LoadImageErrorCode::BAD_IMAGE;
|
||||
}
|
||||
// sorted include not exist table, so check is not need.
|
||||
//if (heapHeader.sorted & ~validMask)
|
||||
//{
|
||||
// return LoadImageErrorCode::BAD_IMAGE;
|
||||
//}
|
||||
|
||||
uint32_t validTableNum = GetNotZeroBitCount(heapHeader.validMask);
|
||||
//std::cout << "valid table num:" << validTableNum << std::endl;
|
||||
//printf("#~ size:%0x\n", _streamTables.size);
|
||||
const uint32_t* tableRowNums = (uint32_t*)(reader.CurrentDataPtr());
|
||||
const byte* tableDataBegin = (const byte*)(tableRowNums + validTableNum);
|
||||
|
||||
{
|
||||
int curValidTableIndex = 0;
|
||||
for (int i = 0; i <= MAX_TABLE_INDEX; i++)
|
||||
{
|
||||
uint64_t mask = (uint64_t)1 << i;
|
||||
_tables[i] = {};
|
||||
if (heapHeader.validMask & mask)
|
||||
{
|
||||
uint32_t rowNum = tableRowNums[curValidTableIndex];
|
||||
_tables[i].rowNum = rowNum;
|
||||
++curValidTableIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BuildTableRowMetas();
|
||||
|
||||
int curValidTableIndex = 0;
|
||||
const byte* curTableData = tableDataBegin;
|
||||
for (int i = 0; i <= MAX_TABLE_INDEX; i++)
|
||||
{
|
||||
uint64_t mask = (uint64_t)1 << i;
|
||||
bool sorted = heapHeader.sortedMask & mask;
|
||||
if (heapHeader.validMask & mask)
|
||||
{
|
||||
uint32_t rowNum = tableRowNums[curValidTableIndex];
|
||||
uint32_t totalSize = 0;
|
||||
auto& table = _tableRowMetas[i];
|
||||
for (auto& col : table)
|
||||
{
|
||||
col.offset = totalSize;
|
||||
totalSize += col.size;
|
||||
}
|
||||
uint32_t metaDataRowSize = totalSize;
|
||||
//uint64_t offset = curTableData - _imageData;
|
||||
_tables[i] = { curTableData, metaDataRowSize, rowNum, true, sorted };
|
||||
curTableData += metaDataRowSize * rowNum;
|
||||
//std::cout << "table:" << i << " ," << curValidTableIndex << ", row_size:" << metaDataRowSize << ", row_num:" << rowNum << std::endl;
|
||||
//printf("table:[%d][%d] offset:%0llx row_size:%d row_count:%d\n", i, curValidTableIndex, offset, metaDataRowSize, rowNum);
|
||||
++curValidTableIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tables[i] = { nullptr, 0, 0, false, sorted };
|
||||
}
|
||||
}
|
||||
|
||||
return LoadImageErrorCode::OK;
|
||||
}
|
||||
|
||||
void PolymorphicRawImage::BuildTableRowMetas()
|
||||
{
|
||||
//!!!{{TABLE_ROW_METADS
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::MODULE];
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputGUIDIndexByte()});
|
||||
table.push_back({ComputGUIDIndexByte()});
|
||||
table.push_back({ComputGUIDIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::TYPEREF];
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputTableIndexByte(TableType::MODULE, TableType::MODULEREF, TableType::ASSEMBLYREF, TableType::TYPEREF, TagBits::ResoulutionScope)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::TYPEDEF];
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputTableIndexByte(TableType::FIELD)});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)});
|
||||
table.push_back({4});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::FIELDPTR];
|
||||
table.push_back({ComputTableIndexByte(TableType::FIELD)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::FIELD];
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::METHODPTR];
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::METHOD];
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({2});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputTableIndexByte(TableType::PARAM)});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::PARAMPTR];
|
||||
table.push_back({ComputTableIndexByte(TableType::PARAM)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::PARAM];
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({2});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::INTERFACEIMPL];
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF)});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::MEMBERREF];
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD, TableType::MODULEREF, TableType::TYPEDEF, TableType::TYPEREF, TagBits::MemberRefParent)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::CONSTANT];
|
||||
table.push_back({1});
|
||||
table.push_back({1});
|
||||
table.push_back({ComputTableIndexByte(TableType::PARAM, TableType::FIELD, TableType::PROPERTY, TagBits::HasConstant)});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::CUSTOMATTRIBUTE];
|
||||
table.push_back({ComputTableIndexByte(HasCustomAttributeAssociateTables, sizeof(HasCustomAttributeAssociateTables) / sizeof(TableType), TagBits::HasCustomAttribute)});
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::CustomAttributeType)});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::FIELDMARSHAL];
|
||||
table.push_back({ComputTableIndexByte(TableType::FIELD, TableType::PARAM, TagBits::HasFieldMarshal)});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::DECLSECURITY];
|
||||
table.push_back({2});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF, TableType::METHOD, TableType::ASSEMBLY, TagBits::HasDeclSecurity)});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::CLASSLAYOUT];
|
||||
table.push_back({4});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::FIELDLAYOUT];
|
||||
table.push_back({ComputTableIndexByte(TableType::FIELD)});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::STANDALONESIG];
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::EVENTMAP];
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF)});
|
||||
table.push_back({ComputTableIndexByte(TableType::EVENT)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::EVENTPTR];
|
||||
table.push_back({ComputTableIndexByte(TableType::EVENT)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::EVENT];
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({2});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::PROPERTYMAP];
|
||||
table.push_back({ComputTableIndexByte(TableType::PROPERTY)});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::PROPERTYPTR];
|
||||
table.push_back({ComputTableIndexByte(TableType::PROPERTY)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::PROPERTY];
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::METHODSEMANTICS];
|
||||
table.push_back({ComputTableIndexByte(TableType::EVENT, TableType::PROPERTY, TagBits::HasSemantics)});
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD)});
|
||||
table.push_back({2});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::METHODIMPL];
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::MethodDefOrRef)});
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::MethodDefOrRef)});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::MODULEREF];
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::TYPESPEC];
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::IMPLMAP];
|
||||
table.push_back({2});
|
||||
table.push_back({ComputTableIndexByte(TableType::MODULEREF)});
|
||||
table.push_back({ComputTableIndexByte(TableType::FIELD, TableType::METHOD, TagBits::MemberForwarded)});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::FIELDRVA];
|
||||
table.push_back({ComputTableIndexByte(TableType::FIELD)});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ENCLOG];
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ENCMAP];
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ASSEMBLY];
|
||||
table.push_back({2});
|
||||
table.push_back({4});
|
||||
table.push_back({2});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({2});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ASSEMBLYPROCESSOR];
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ASSEMBLYOS];
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ASSEMBLYREF];
|
||||
table.push_back({4});
|
||||
table.push_back({2});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({2});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ASSEMBLYREFPROCESSOR];
|
||||
table.push_back({ComputTableIndexByte(TableType::ASSEMBLYREF)});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::ASSEMBLYREFOS];
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
table.push_back({ComputTableIndexByte(TableType::ASSEMBLYREF)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::FILE];
|
||||
table.push_back({4});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::EXPORTEDTYPE];
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputTableIndexByte(TableType::FILE, TableType::EXPORTEDTYPE, TableType::ASSEMBLY, TagBits::Implementation)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::MANIFESTRESOURCE];
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputTableIndexByte(TableType::FILE, TableType::ASSEMBLYREF, TagBits::Implementation)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::NESTEDCLASS];
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF)});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::GENERICPARAM];
|
||||
table.push_back({2});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF, TableType::METHOD, TagBits::TypeOrMethodDef)});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::METHODSPEC];
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD, TableType::MEMBERREF, TagBits::MethodDefOrRef)});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::GENERICPARAMCONSTRAINT];
|
||||
table.push_back({ComputTableIndexByte(TableType::TYPEDEF, TableType::TYPEREF, TableType::TYPESPEC, TagBits::TypeDefOrRef)});
|
||||
table.push_back({ComputTableIndexByte(TableType::GENERICPARAM)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::DOCUMENT];
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({ComputGUIDIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
table.push_back({ComputGUIDIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::METHODDEBUGINFORMATION];
|
||||
table.push_back({ComputTableIndexByte(TableType::DOCUMENT)});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::LOCALSCOPE];
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD)});
|
||||
table.push_back({ComputTableIndexByte(TableType::IMPORTSCOPE)});
|
||||
table.push_back({ComputTableIndexByte(TableType::LOCALVARIABLE)});
|
||||
table.push_back({ComputTableIndexByte(TableType::LOCALCONSTANT)});
|
||||
table.push_back({4});
|
||||
table.push_back({4});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::LOCALVARIABLE];
|
||||
table.push_back({2});
|
||||
table.push_back({2});
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::LOCALCONSTANT];
|
||||
table.push_back({ComputStringIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::IMPORTSCOPE];
|
||||
table.push_back({ComputTableIndexByte(TableType::IMPORTSCOPE)});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::STATEMACHINEMETHOD];
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD)});
|
||||
table.push_back({ComputTableIndexByte(TableType::METHOD)});
|
||||
}
|
||||
{
|
||||
auto& table = _tableRowMetas[(int)TableType::CUSTOMDEBUGINFORMATION];
|
||||
table.push_back({ComputTableIndexByte(HasCustomDebugInformation, sizeof(HasCustomDebugInformation) / sizeof(TableType), TagBits::HasCustomDebugInformation)});
|
||||
table.push_back({ComputGUIDIndexByte()});
|
||||
table.push_back({ComputBlobIndexByte()});
|
||||
}
|
||||
|
||||
//!!!}}TABLE_ROW_METADS
|
||||
|
||||
for (int i = 0; i < TABLE_NUM; i++)
|
||||
{
|
||||
auto& table = _tableRowMetas[i];
|
||||
if (table.empty())
|
||||
{
|
||||
IL2CPP_ASSERT(_tables[i].rowNum == 0 && _tables[i].rowMetaDataSize == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t totalSize = 0;
|
||||
for (auto& col : table)
|
||||
{
|
||||
col.offset = totalSize;
|
||||
totalSize += col.size;
|
||||
}
|
||||
uint32_t computSize = ComputTableRowMetaDataSize((TableType)i);
|
||||
IL2CPP_ASSERT(totalSize == computSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//!!!{{READ_TABLES_IMPLEMENTATIONS
|
||||
TbTypeRef PolymorphicRawImage::ReadTypeRef(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::TYPEREF).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::TYPEREF, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::TYPEREF);
|
||||
TbTypeRef data;
|
||||
data.typeNamespace = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.typeName = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.resolutionScope = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbTypeDef PolymorphicRawImage::ReadTypeDef(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::TYPEDEF).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::TYPEDEF, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::TYPEDEF);
|
||||
TbTypeDef data;
|
||||
data.typeName = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.fieldList = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.extends = ReadColumn(rowPtr, rowSchema[2]);
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[3]);
|
||||
data.typeNamespace = ReadColumn(rowPtr, rowSchema[4]);
|
||||
data.methodList = ReadColumn(rowPtr, rowSchema[5]);
|
||||
return data;
|
||||
}
|
||||
TbField PolymorphicRawImage::ReadField(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::FIELD).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::FIELD, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::FIELD);
|
||||
TbField data;
|
||||
data.signature = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbMethod PolymorphicRawImage::ReadMethod(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::METHOD).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::METHOD, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::METHOD);
|
||||
TbMethod data;
|
||||
data.signature = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.implFlags = ReadColumn(rowPtr, rowSchema[2]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[3]);
|
||||
data.paramList = ReadColumn(rowPtr, rowSchema[4]);
|
||||
data.rva = ReadColumn(rowPtr, rowSchema[5]);
|
||||
return data;
|
||||
}
|
||||
TbParam PolymorphicRawImage::ReadParam(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::PARAM).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::PARAM, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::PARAM);
|
||||
TbParam data;
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.sequence = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbInterfaceImpl PolymorphicRawImage::ReadInterfaceImpl(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::INTERFACEIMPL).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::INTERFACEIMPL, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::INTERFACEIMPL);
|
||||
TbInterfaceImpl data;
|
||||
data.classIdx = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.interfaceIdx = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
TbMemberRef PolymorphicRawImage::ReadMemberRef(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::MEMBERREF).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::MEMBERREF, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::MEMBERREF);
|
||||
TbMemberRef data;
|
||||
data.name = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.signature = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.classIdx = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbConstant PolymorphicRawImage::ReadConstant(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::CONSTANT).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::CONSTANT, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::CONSTANT);
|
||||
TbConstant data;
|
||||
data.padding = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.type = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.parent = ReadColumn(rowPtr, rowSchema[2]);
|
||||
data.value = ReadColumn(rowPtr, rowSchema[3]);
|
||||
return data;
|
||||
}
|
||||
TbCustomAttribute PolymorphicRawImage::ReadCustomAttribute(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::CUSTOMATTRIBUTE).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::CUSTOMATTRIBUTE, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::CUSTOMATTRIBUTE);
|
||||
TbCustomAttribute data;
|
||||
data.parent = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.type = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.value = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbClassLayout PolymorphicRawImage::ReadClassLayout(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::CLASSLAYOUT).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::CLASSLAYOUT, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::CLASSLAYOUT);
|
||||
TbClassLayout data;
|
||||
data.classSize = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.packingSize = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.parent = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbFieldLayout PolymorphicRawImage::ReadFieldLayout(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::FIELDLAYOUT).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::FIELDLAYOUT, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::FIELDLAYOUT);
|
||||
TbFieldLayout data;
|
||||
data.field = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.offset = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
TbStandAloneSig PolymorphicRawImage::ReadStandAloneSig(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::STANDALONESIG).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::STANDALONESIG, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::STANDALONESIG);
|
||||
TbStandAloneSig data;
|
||||
data.signature = ReadColumn(rowPtr, rowSchema[0]);
|
||||
return data;
|
||||
}
|
||||
TbEventMap PolymorphicRawImage::ReadEventMap(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::EVENTMAP).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::EVENTMAP, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::EVENTMAP);
|
||||
TbEventMap data;
|
||||
data.parent = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.eventList = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
TbEvent PolymorphicRawImage::ReadEvent(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::EVENT).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::EVENT, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::EVENT);
|
||||
TbEvent data;
|
||||
data.eventType = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.eventFlags = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbPropertyMap PolymorphicRawImage::ReadPropertyMap(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::PROPERTYMAP).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::PROPERTYMAP, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::PROPERTYMAP);
|
||||
TbPropertyMap data;
|
||||
data.propertyList = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.parent = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
TbProperty PolymorphicRawImage::ReadProperty(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::PROPERTY).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::PROPERTY, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::PROPERTY);
|
||||
TbProperty data;
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.type = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbMethodSemantics PolymorphicRawImage::ReadMethodSemantics(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::METHODSEMANTICS).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::METHODSEMANTICS, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::METHODSEMANTICS);
|
||||
TbMethodSemantics data;
|
||||
data.association = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.method = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.semantics = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbMethodImpl PolymorphicRawImage::ReadMethodImpl(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::METHODIMPL).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::METHODIMPL, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::METHODIMPL);
|
||||
TbMethodImpl data;
|
||||
data.methodDeclaration = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.methodBody = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.classIdx = ReadColumn(rowPtr, rowSchema[2]);
|
||||
return data;
|
||||
}
|
||||
TbModuleRef PolymorphicRawImage::ReadModuleRef(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::MODULEREF).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::MODULEREF, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::MODULEREF);
|
||||
TbModuleRef data;
|
||||
data.name = ReadColumn(rowPtr, rowSchema[0]);
|
||||
return data;
|
||||
}
|
||||
TbTypeSpec PolymorphicRawImage::ReadTypeSpec(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::TYPESPEC).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::TYPESPEC, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::TYPESPEC);
|
||||
TbTypeSpec data;
|
||||
data.signature = ReadColumn(rowPtr, rowSchema[0]);
|
||||
return data;
|
||||
}
|
||||
TbImplMap PolymorphicRawImage::ReadImplMap(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::IMPLMAP).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::IMPLMAP, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::IMPLMAP);
|
||||
TbImplMap data;
|
||||
data.mappingFlags = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.importScope = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.memberForwarded = ReadColumn(rowPtr, rowSchema[2]);
|
||||
data.importName = ReadColumn(rowPtr, rowSchema[3]);
|
||||
return data;
|
||||
}
|
||||
TbFieldRVA PolymorphicRawImage::ReadFieldRVA(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::FIELDRVA).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::FIELDRVA, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::FIELDRVA);
|
||||
TbFieldRVA data;
|
||||
data.field = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.rva = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
TbAssembly PolymorphicRawImage::ReadAssembly(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::ASSEMBLY).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::ASSEMBLY, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::ASSEMBLY);
|
||||
TbAssembly data;
|
||||
data.minorVersion = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.hashAlgId = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.buildNumber = ReadColumn(rowPtr, rowSchema[2]);
|
||||
data.revisionNumber = ReadColumn(rowPtr, rowSchema[3]);
|
||||
data.locale = ReadColumn(rowPtr, rowSchema[4]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[5]);
|
||||
data.publicKey = ReadColumn(rowPtr, rowSchema[6]);
|
||||
data.majorVersion = ReadColumn(rowPtr, rowSchema[7]);
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[8]);
|
||||
return data;
|
||||
}
|
||||
TbAssemblyRef PolymorphicRawImage::ReadAssemblyRef(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::ASSEMBLYREF).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::ASSEMBLYREF, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::ASSEMBLYREF);
|
||||
TbAssemblyRef data;
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.majorVersion = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.buildNumber = ReadColumn(rowPtr, rowSchema[2]);
|
||||
data.publicKeyOrToken = ReadColumn(rowPtr, rowSchema[3]);
|
||||
data.hashValue = ReadColumn(rowPtr, rowSchema[4]);
|
||||
data.revisionNumber = ReadColumn(rowPtr, rowSchema[5]);
|
||||
data.minorVersion = ReadColumn(rowPtr, rowSchema[6]);
|
||||
data.locale = ReadColumn(rowPtr, rowSchema[7]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[8]);
|
||||
return data;
|
||||
}
|
||||
TbNestedClass PolymorphicRawImage::ReadNestedClass(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::NESTEDCLASS).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::NESTEDCLASS, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::NESTEDCLASS);
|
||||
TbNestedClass data;
|
||||
data.enclosingClass = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.nestedClass = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
TbGenericParam PolymorphicRawImage::ReadGenericParam(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::GENERICPARAM).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::GENERICPARAM, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::GENERICPARAM);
|
||||
TbGenericParam data;
|
||||
data.flags = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.number = ReadColumn(rowPtr, rowSchema[1]);
|
||||
data.owner = ReadColumn(rowPtr, rowSchema[2]);
|
||||
data.name = ReadColumn(rowPtr, rowSchema[3]);
|
||||
return data;
|
||||
}
|
||||
TbMethodSpec PolymorphicRawImage::ReadMethodSpec(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::METHODSPEC).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::METHODSPEC, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::METHODSPEC);
|
||||
TbMethodSpec data;
|
||||
data.method = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.instantiation = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
TbGenericParamConstraint PolymorphicRawImage::ReadGenericParamConstraint(uint32_t rawIndex)
|
||||
{
|
||||
IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(TableType::GENERICPARAMCONSTRAINT).rowNum);
|
||||
const byte* rowPtr = GetTableRowPtr(TableType::GENERICPARAMCONSTRAINT, rawIndex);
|
||||
auto& rowSchema = GetRowSchema(TableType::GENERICPARAMCONSTRAINT);
|
||||
TbGenericParamConstraint data;
|
||||
data.constraint = ReadColumn(rowPtr, rowSchema[0]);
|
||||
data.owner = ReadColumn(rowPtr, rowSchema[1]);
|
||||
return data;
|
||||
}
|
||||
|
||||
//!!!}}READ_TABLES_IMPLEMENTATIONS
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "DotNetRawImageBase.h"
|
||||
|
||||
namespace hybridclr
|
||||
{
|
||||
namespace metadata
|
||||
{
|
||||
|
||||
class PolymorphicRawImage : public DotNetRawImageBase
|
||||
{
|
||||
public:
|
||||
PolymorphicRawImage() : DotNetRawImageBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LoadImageErrorCode LoadCLIHeader(uint32_t& entryPointToken, uint32_t& metadataRva, uint32_t& metadataSize) override;
|
||||
virtual LoadImageErrorCode LoadStreamHeaders(uint32_t metadataRva, uint32_t metadataSize) override;
|
||||
virtual LoadImageErrorCode LoadTables() override;
|
||||
virtual void BuildTableRowMetas() override;
|
||||
|
||||
//!!!{{READ_TABLES_OVERRIDES
|
||||
virtual TbTypeRef ReadTypeRef(uint32_t rawIndex) override;
|
||||
virtual TbTypeDef ReadTypeDef(uint32_t rawIndex) override;
|
||||
virtual TbField ReadField(uint32_t rawIndex) override;
|
||||
virtual TbMethod ReadMethod(uint32_t rawIndex) override;
|
||||
virtual TbParam ReadParam(uint32_t rawIndex) override;
|
||||
virtual TbInterfaceImpl ReadInterfaceImpl(uint32_t rawIndex) override;
|
||||
virtual TbMemberRef ReadMemberRef(uint32_t rawIndex) override;
|
||||
virtual TbConstant ReadConstant(uint32_t rawIndex) override;
|
||||
virtual TbCustomAttribute ReadCustomAttribute(uint32_t rawIndex) override;
|
||||
virtual TbClassLayout ReadClassLayout(uint32_t rawIndex) override;
|
||||
virtual TbFieldLayout ReadFieldLayout(uint32_t rawIndex) override;
|
||||
virtual TbStandAloneSig ReadStandAloneSig(uint32_t rawIndex) override;
|
||||
virtual TbEventMap ReadEventMap(uint32_t rawIndex) override;
|
||||
virtual TbEvent ReadEvent(uint32_t rawIndex) override;
|
||||
virtual TbPropertyMap ReadPropertyMap(uint32_t rawIndex) override;
|
||||
virtual TbProperty ReadProperty(uint32_t rawIndex) override;
|
||||
virtual TbMethodSemantics ReadMethodSemantics(uint32_t rawIndex) override;
|
||||
virtual TbMethodImpl ReadMethodImpl(uint32_t rawIndex) override;
|
||||
virtual TbModuleRef ReadModuleRef(uint32_t rawIndex) override;
|
||||
virtual TbTypeSpec ReadTypeSpec(uint32_t rawIndex) override;
|
||||
virtual TbImplMap ReadImplMap(uint32_t rawIndex) override;
|
||||
virtual TbFieldRVA ReadFieldRVA(uint32_t rawIndex) override;
|
||||
virtual TbAssembly ReadAssembly(uint32_t rawIndex) override;
|
||||
virtual TbAssemblyRef ReadAssemblyRef(uint32_t rawIndex) override;
|
||||
virtual TbNestedClass ReadNestedClass(uint32_t rawIndex) override;
|
||||
virtual TbGenericParam ReadGenericParam(uint32_t rawIndex) override;
|
||||
virtual TbMethodSpec ReadMethodSpec(uint32_t rawIndex) override;
|
||||
virtual TbGenericParamConstraint ReadGenericParamConstraint(uint32_t rawIndex) override;
|
||||
|
||||
//!!!}}READ_TABLES_OVERRIDES
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "com.code-philosophy.obfuz4hybridclr",
|
||||
"version": "1.0.0-beta.1",
|
||||
"displayName": "Obfuz4HybridCLR",
|
||||
"description": "Obfuz4HybridCLR is a obfuz extension for HybridCLR",
|
||||
"category": "Scripting",
|
||||
"documentationUrl": "https://www.obfuz.com",
|
||||
"changelogUrl": "https://github.com/focus-creative-games/obfuz/commits/main/",
|
||||
"licensesUrl": "https://github.com/focus-creative-games/obfuz/blob/main/com.code-philosophy.obfuz4hybridclr/LICENSE",
|
||||
"keywords": [
|
||||
"obfuz",
|
||||
"obfuscation",
|
||||
"obfuscator",
|
||||
"confuser",
|
||||
"code-philosophy"
|
||||
],
|
||||
"author": {
|
||||
"name": "Code Philosophy",
|
||||
"email": "obfuz@code-philosophy.com",
|
||||
"url": "https://code-philosophy.com"
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ac66e213a764b840b2533ee30123717
|
||||
PackageManifestImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user