mirror of https://github.com/Xpl0itR/protodec.git
Compare commits
2 Commits
9c9121920a
...
2be6148ff1
Author | SHA1 | Date |
---|---|---|
Xpl0itR | 2be6148ff1 | |
Xpl0itR | 54ba50bfb4 |
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright © 2024 Xpl0itR
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using SystemEx.Memory;
|
||||||
|
|
||||||
|
namespace LibProtodec;
|
||||||
|
|
||||||
|
public static class CilReader
|
||||||
|
{
|
||||||
|
// Temporary AOT incompatible method to fill the dictionary, TODO: replace with a source generator
|
||||||
|
private static readonly Dictionary<int, OpCode> OpCodeLookup =
|
||||||
|
typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static)
|
||||||
|
.Select(field => (OpCode)field.GetValue(null)!)
|
||||||
|
.ToDictionary(opCode => (int)(ushort)opCode.Value);
|
||||||
|
|
||||||
|
public static OpCode ReadCilOpCode(this ref MemoryReader reader, out int operandLength)
|
||||||
|
{
|
||||||
|
byte opCodeByte = reader.ReadByte();
|
||||||
|
int opCodeInt = opCodeByte == OpCodes.Prefix1.Value
|
||||||
|
? (opCodeByte << 8) | reader.ReadByte()
|
||||||
|
: opCodeByte;
|
||||||
|
|
||||||
|
OpCode opCode = OpCodeLookup[opCodeInt];
|
||||||
|
operandLength = SizeOf(opCode.OperandType);
|
||||||
|
|
||||||
|
return opCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static int SizeOf(OperandType operandType)
|
||||||
|
{
|
||||||
|
switch (operandType)
|
||||||
|
{
|
||||||
|
case OperandType.ShortInlineBrTarget:
|
||||||
|
case OperandType.ShortInlineI:
|
||||||
|
case OperandType.ShortInlineVar:
|
||||||
|
return 1;
|
||||||
|
case OperandType.InlineVar:
|
||||||
|
return 2;
|
||||||
|
case OperandType.InlineBrTarget:
|
||||||
|
case OperandType.InlineField:
|
||||||
|
case OperandType.InlineI:
|
||||||
|
case OperandType.InlineMethod:
|
||||||
|
case OperandType.InlineSig:
|
||||||
|
case OperandType.InlineString:
|
||||||
|
case OperandType.InlineSwitch:
|
||||||
|
case OperandType.InlineTok:
|
||||||
|
case OperandType.InlineType:
|
||||||
|
case OperandType.ShortInlineR:
|
||||||
|
return 4;
|
||||||
|
case OperandType.InlineI8:
|
||||||
|
case OperandType.InlineR:
|
||||||
|
return 8;
|
||||||
|
case OperandType.InlineNone:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
|
||||||
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="8.0.0" />
|
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="8.0.0" />
|
||||||
<PackageReference Include="Xpl0itR.SystemEx" Version="1.1.0" />
|
<PackageReference Include="Xpl0itR.SystemEx" Version="1.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
|
@ -11,12 +11,14 @@ using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
using SystemEx;
|
using SystemEx;
|
||||||
using CommunityToolkit.Diagnostics;
|
using CommunityToolkit.Diagnostics;
|
||||||
using LibProtodec.Models;
|
using LibProtodec.Models;
|
||||||
using LibProtodec.Models.Fields;
|
using LibProtodec.Models.Fields;
|
||||||
using LibProtodec.Models.TopLevels;
|
using LibProtodec.Models.TopLevels;
|
||||||
using LibProtodec.Models.Types;
|
using LibProtodec.Models.Types;
|
||||||
|
using SystemEx.Memory;
|
||||||
|
|
||||||
namespace LibProtodec;
|
namespace LibProtodec;
|
||||||
|
|
||||||
|
@ -70,6 +72,8 @@ public sealed class ProtodecContext
|
||||||
|
|
||||||
Protobuf protobuf = GetProtobuf(messageClass, message, options);
|
Protobuf protobuf = GetProtobuf(messageClass, message, options);
|
||||||
|
|
||||||
|
ParseWriteToMethodTesting(messageClass);
|
||||||
|
|
||||||
FieldInfo[] idFields = messageClass.GetFields(PublicStatic);
|
FieldInfo[] idFields = messageClass.GetFields(PublicStatic);
|
||||||
PropertyInfo[] properties = messageClass.GetProperties(PublicInstanceDeclared);
|
PropertyInfo[] properties = messageClass.GetProperties(PublicInstanceDeclared);
|
||||||
|
|
||||||
|
@ -128,6 +132,39 @@ public sealed class ProtodecContext
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ParseWriteToMethodTesting(Type messageClass)
|
||||||
|
{
|
||||||
|
MethodInfo writeTo = messageClass.GetMethod("WriteTo", BindingFlags.Public | BindingFlags.Instance)!;
|
||||||
|
MemoryReader reader = new(writeTo.GetMethodBody()!.GetILAsByteArray()!);
|
||||||
|
|
||||||
|
int fieldToken = 0;
|
||||||
|
while (reader.Remaining > 0)
|
||||||
|
{
|
||||||
|
OpCode opCode = reader.ReadCilOpCode(out int operandLength);
|
||||||
|
if (opCode == OpCodes.Ret) // DummyDLL from il2cppdumper will only have ret in method body
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (opCode == OpCodes.Ldfld)
|
||||||
|
{
|
||||||
|
fieldToken = reader.ReadInt32LittleEndian();
|
||||||
|
}
|
||||||
|
else if (opCode == OpCodes.Call)
|
||||||
|
{
|
||||||
|
Guard.IsNotEqualTo(fieldToken, 0);
|
||||||
|
int methodToken = reader.ReadInt32LittleEndian();
|
||||||
|
|
||||||
|
MethodBase? method = messageClass.Module.ResolveMethod(methodToken); // System.NotSupportedException: 'Resolving tokens is not supported on assemblies loaded by a MetadataLoadContext.'
|
||||||
|
FieldInfo? field = messageClass.Module.ResolveField(fieldToken);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reader.Position += operandLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Enum ParseEnum(Type enumEnum, ParserOptions options = ParserOptions.None)
|
public Enum ParseEnum(Type enumEnum, ParserOptions options = ParserOptions.None)
|
||||||
{
|
{
|
||||||
Guard.IsTrue(enumEnum.IsEnum);
|
Guard.IsTrue(enumEnum.IsEnum);
|
||||||
|
|
Loading…
Reference in New Issue