Plugins: Simplify event data; add GetStrings and GetStringLiterals
This commit is contained in:
@@ -43,7 +43,7 @@ namespace Il2CppInspector
|
|||||||
public uint[] VTableMethodIndices { get; set; }
|
public uint[] VTableMethodIndices { get; set; }
|
||||||
public string[] StringLiterals { get; set; }
|
public string[] StringLiterals { get; set; }
|
||||||
|
|
||||||
public Dictionary<int, string> Strings { get; } = new Dictionary<int, string>();
|
public Dictionary<int, string> Strings { get; private set; } = new Dictionary<int, string>();
|
||||||
|
|
||||||
// Set if something in the metadata has been modified / decrypted
|
// Set if something in the metadata has been modified / decrypted
|
||||||
public bool IsModified { get; private set; } = false;
|
public bool IsModified { get; private set; } = false;
|
||||||
@@ -97,7 +97,7 @@ namespace Il2CppInspector
|
|||||||
// in the header after the sanity and version fields, and since it will always point directly to the first byte after the end of the header,
|
// in the header after the sanity and version fields, and since it will always point directly to the first byte after the end of the header,
|
||||||
// we can use this value to determine the actual header length and therefore narrow down the metadata version to 24.0/24.1 or 24.2.
|
// we can use this value to determine the actual header length and therefore narrow down the metadata version to 24.0/24.1 or 24.2.
|
||||||
|
|
||||||
if (!pluginResult.AdditionalData.SkipValidation) {
|
if (!pluginResult.SkipValidation) {
|
||||||
var realHeaderLength = Header.stringLiteralOffset;
|
var realHeaderLength = Header.stringLiteralOffset;
|
||||||
|
|
||||||
if (realHeaderLength != Sizeof(typeof(Il2CppGlobalMetadataHeader))) {
|
if (realHeaderLength != Sizeof(typeof(Il2CppGlobalMetadataHeader))) {
|
||||||
@@ -169,12 +169,17 @@ namespace Il2CppInspector
|
|||||||
AttributeTypeRanges = ReadArray<Il2CppCustomAttributeTypeRange>(Header.attributesInfoOffset, Header.attributesInfoCount / Sizeof(typeof(Il2CppCustomAttributeTypeRange)));
|
AttributeTypeRanges = ReadArray<Il2CppCustomAttributeTypeRange>(Header.attributesInfoOffset, Header.attributesInfoCount / Sizeof(typeof(Il2CppCustomAttributeTypeRange)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all metadata string literals
|
// Get all metadata strings
|
||||||
|
var pluginGetStringsResult = PluginHooks.GetStrings(this);
|
||||||
|
if (pluginGetStringsResult.IsHandled)
|
||||||
|
Strings = pluginGetStringsResult.Strings;
|
||||||
|
|
||||||
|
else {
|
||||||
Position = Header.stringOffset;
|
Position = Header.stringOffset;
|
||||||
|
|
||||||
// Naive implementation: this works for normal IL2CPP metadata but isn't good enough when the strings are encrypted
|
// Naive implementation: this works for normal IL2CPP metadata but isn't good enough when the strings are encrypted
|
||||||
while (Position < Header.stringOffset + Header.stringCount)
|
while (Position < Header.stringOffset + Header.stringCount)
|
||||||
Strings.Add((int)Position - Header.stringOffset, ReadNullTerminatedString());
|
Strings.Add((int) Position - Header.stringOffset, ReadNullTerminatedString());
|
||||||
|
|
||||||
// To check for encryption, find every single string start position by scanning all of the definitions
|
// To check for encryption, find every single string start position by scanning all of the definitions
|
||||||
var stringOffsets =
|
var stringOffsets =
|
||||||
@@ -232,13 +237,20 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
IsModified = true;
|
IsModified = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get all managed code string literals
|
// Get all string literals
|
||||||
|
var pluginGetStringLiteralsResult = PluginHooks.GetStringLiterals(this);
|
||||||
|
if (pluginGetStringLiteralsResult.IsHandled)
|
||||||
|
StringLiterals = pluginGetStringLiteralsResult.StringLiterals.ToArray();
|
||||||
|
|
||||||
|
else {
|
||||||
var stringLiteralList = ReadArray<Il2CppStringLiteral>(Header.stringLiteralOffset, Header.stringLiteralCount / Sizeof(typeof(Il2CppStringLiteral)));
|
var stringLiteralList = ReadArray<Il2CppStringLiteral>(Header.stringLiteralOffset, Header.stringLiteralCount / Sizeof(typeof(Il2CppStringLiteral)));
|
||||||
|
|
||||||
StringLiterals = new string[stringLiteralList.Length];
|
StringLiterals = new string[stringLiteralList.Length];
|
||||||
for (var i = 0; i < stringLiteralList.Length; i++)
|
for (var i = 0; i < stringLiteralList.Length; i++)
|
||||||
StringLiterals[i] = ReadFixedLengthString(Header.stringLiteralDataOffset + stringLiteralList[i].dataIndex, stringLiteralList[i].length);
|
StringLiterals[i] = ReadFixedLengthString(Header.stringLiteralDataOffset + stringLiteralList[i].dataIndex, stringLiteralList[i].length);
|
||||||
|
}
|
||||||
|
|
||||||
// Post-processing hook
|
// Post-processing hook
|
||||||
IsModified |= PluginHooks.PostProcessMetadata(this).IsStreamModified;
|
IsModified |= PluginHooks.PostProcessMetadata(this).IsStreamModified;
|
||||||
|
|||||||
@@ -28,6 +28,22 @@ namespace Il2CppInspector.PluginAPI.V100
|
|||||||
void PostProcessMetadata(Metadata metadata, PluginPostProcessMetadataEventInfo data);
|
void PostProcessMetadata(Metadata metadata, PluginPostProcessMetadataEventInfo data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch all of the .NET identifier strings
|
||||||
|
/// </summary>
|
||||||
|
public interface IGetStrings
|
||||||
|
{
|
||||||
|
void GetStrings(Metadata metadata, PluginGetStringsEventInfo data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch all of the (constant) string literals
|
||||||
|
/// </summary>
|
||||||
|
public interface IGetStringLiterals
|
||||||
|
{
|
||||||
|
void GetStringLiterals(Metadata metadata, PluginGetStringLiteralsEventInfo data);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Post-process the .NET type model to make changes after it has been fully created
|
/// Post-process the .NET type model to make changes after it has been fully created
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -10,20 +10,11 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Il2CppInspector.PluginAPI.V100
|
namespace Il2CppInspector.PluginAPI.V100
|
||||||
{
|
{
|
||||||
public interface IPluginEventInfo
|
|
||||||
{
|
|
||||||
public bool IsHandled { get; set; }
|
|
||||||
public bool IsInvalid { get; set; }
|
|
||||||
public bool IsDataModified { get; set; }
|
|
||||||
public bool IsStreamModified { get; set; }
|
|
||||||
public PluginErrorEventArgs Error { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Object which allows plugins to report on what has happened during a call
|
/// Object which allows plugins to report on what has happened during a call
|
||||||
/// Changes made to this object propagate to the next plugin in the call chain until IsHandled is set to true
|
/// Changes made to this object propagate to the next plugin in the call chain until IsHandled is set to true
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginEventInfo<T> : IPluginEventInfo where T : new()
|
public class PluginEventInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A plugin should set this if it has processed the supplied data in such a way that no further processing is required by other plugins
|
/// A plugin should set this if it has processed the supplied data in such a way that no further processing is required by other plugins
|
||||||
@@ -53,45 +44,52 @@ namespace Il2CppInspector.PluginAPI.V100
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsStreamModified { get; set; } = false;
|
public bool IsStreamModified { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event-specific additional options and controls. See the documentation for each event for more details.
|
|
||||||
/// </summary>
|
|
||||||
public T AdditionalData { get; } = new T();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This wiil be set automatically by Il2CppInspector to the last exception thrown by a plugin for the current event
|
/// This wiil be set automatically by Il2CppInspector to the last exception thrown by a plugin for the current event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginErrorEventArgs Error { get; set; } = null;
|
public PluginErrorEventArgs Error { get; set; } = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generic event info with no additional paramters
|
|
||||||
/// </summary>
|
|
||||||
public class PluginEventInfo : PluginEventInfo<object> { }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event info for PreProcessMetadata
|
/// Event info for PreProcessMetadata
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginPreProcessMetadataEventInfo : PluginEventInfo<PluginPreProcessMetadataEventData> { }
|
public class PluginPreProcessMetadataEventInfo : PluginEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Set to true to disable some validation checks by Il2CppInspector that the metadata is valid
|
||||||
|
/// </summary>
|
||||||
|
public bool SkipValidation { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event info for PostProcessMetadata
|
/// Event info for PostProcessMetadata
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginPostProcessMetadataEventInfo : PluginEventInfo { }
|
public class PluginPostProcessMetadataEventInfo : PluginEventInfo { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event info for GetStrings
|
||||||
|
/// </summary>
|
||||||
|
public class PluginGetStringsEventInfo : PluginEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All of the fetched strings to be returned
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<int, string> Strings { get; set; } = new Dictionary<int, string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event info for GetStringLiterals
|
||||||
|
/// </summary>
|
||||||
|
public class PluginGetStringLiteralsEventInfo : PluginEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All of the fetched string literals to be returned
|
||||||
|
/// </summary>
|
||||||
|
public List<string> StringLiterals { get; set; } = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event info for PostProcessTypeModel
|
/// Event info for PostProcessTypeModel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginPostProcessTypeModelEventInfo : PluginEventInfo { }
|
public class PluginPostProcessTypeModelEventInfo : PluginEventInfo { }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Additional data for PreProcessMetadata
|
|
||||||
/// </summary>
|
|
||||||
public class PluginPreProcessMetadataEventData
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Set to true to disable some validation checks by Il2CppInspector that the metadata is valid
|
|
||||||
/// </summary>
|
|
||||||
public bool SkipValidation { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,23 @@ namespace Il2CppInspector
|
|||||||
// Hooks we provide to plugins which can choose whether or not to provide implementations
|
// Hooks we provide to plugins which can choose whether or not to provide implementations
|
||||||
internal static class PluginHooks
|
internal static class PluginHooks
|
||||||
{
|
{
|
||||||
public static PluginPostProcessMetadataEventInfo PostProcessMetadata(Metadata metadata)
|
|
||||||
=> PluginManager.Try<IPostProcessMetadata, PluginPostProcessMetadataEventInfo>((p, e) => p.PostProcessMetadata(metadata, e));
|
|
||||||
|
|
||||||
public static PluginPreProcessMetadataEventInfo PreProcessMetadata(BinaryObjectStream stream)
|
public static PluginPreProcessMetadataEventInfo PreProcessMetadata(BinaryObjectStream stream)
|
||||||
=> PluginManager.Try<IPreProcessMetadata, PluginPreProcessMetadataEventInfo>((p, e) => {
|
=> PluginManager.Try<IPreProcessMetadata, PluginPreProcessMetadataEventInfo>((p, e) => {
|
||||||
stream.Position = 0;
|
stream.Position = 0;
|
||||||
p.PreProcessMetadata(stream, e);
|
p.PreProcessMetadata(stream, e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public static PluginPostProcessMetadataEventInfo PostProcessMetadata(Metadata metadata)
|
||||||
|
=> PluginManager.Try<IPostProcessMetadata, PluginPostProcessMetadataEventInfo>((p, e) => p.PostProcessMetadata(metadata, e));
|
||||||
|
|
||||||
|
public static PluginGetStringsEventInfo GetStrings(Metadata metadata)
|
||||||
|
=> PluginManager.Try<IGetStrings, PluginGetStringsEventInfo>((p, e) => p.GetStrings(metadata, e));
|
||||||
|
|
||||||
|
public static PluginGetStringLiteralsEventInfo GetStringLiterals(Metadata metadata)
|
||||||
|
=> PluginManager.Try<IGetStringLiterals, PluginGetStringLiteralsEventInfo>((p, e) => p.GetStringLiterals(metadata, e));
|
||||||
|
|
||||||
public static PluginPostProcessTypeModelEventInfo PostProcessTypeModel(TypeModel typeModel)
|
public static PluginPostProcessTypeModelEventInfo PostProcessTypeModel(TypeModel typeModel)
|
||||||
=> PluginManager.Try<IPostProcessTypeModel, PluginPostProcessTypeModelEventInfo>((p, e) => p.PostProcessTypeModel(typeModel, e));
|
=> PluginManager.Try<IPostProcessTypeModel, PluginPostProcessTypeModelEventInfo>((p, e) => p.PostProcessTypeModel(typeModel, e));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Try to cast each enabled plugin to a specific interface type, and for those supporting the interface, execute the supplied delegate
|
// Try to cast each enabled plugin to a specific interface type, and for those supporting the interface, execute the supplied delegate
|
||||||
// Errors will be forwarded to the error handler
|
// Errors will be forwarded to the error handler
|
||||||
internal static E Try<I, E>(Action<I, E> action) where E : IPluginEventInfo, new()
|
internal static E Try<I, E>(Action<I, E> action) where E : PluginEventInfo, new()
|
||||||
{
|
{
|
||||||
var eventInfo = new E();
|
var eventInfo = new E();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user