initial start of dumper conversion, moved assets to a Assets folder, updated PB scripts

This commit is contained in:
CWX 2024-08-09 21:39:39 +01:00
parent f7543672fc
commit f3d095a0a7
27 changed files with 1478 additions and 3 deletions

View File

@ -0,0 +1,39 @@
[
{"Role":"assault","Limit":2,"Difficulty":"easy"},
{"Role":"assault","Limit":2,"Difficulty":"normal"},
{"Role":"assault","Limit":2,"Difficulty":"hard"},
{"Role":"marksman","Limit":2,"Difficulty":"normal"},
{"Role":"marksman","Limit":2,"Difficulty":"hard"},
{"Role":"pmcBot","Limit":2,"Difficulty":"normal"},
{"Role":"bossGluhar","Limit":2,"Difficulty":"normal"},
{"Role":"followerGluharAssault","Limit":2,"Difficulty":"normal"},
{"Role":"followerGluharSecurity","Limit":2,"Difficulty":"normal"},
{"Role":"followerGluharScout","Limit":2,"Difficulty":"normal"},
{"Role":"bossKolontay","Limit":2,"Difficulty":"normal"},
{"Role":"followerKolontayAssault","Limit":2,"Difficulty":"normal"},
{"Role":"followerKolontaySecurity","Limit":2,"Difficulty":"normal"},
{"Role":"bossBoar","Limit":2,"Difficulty":"normal"},
{"Role":"followerBoar","Limit":2,"Difficulty":"normal"},
{"Role":"followerBoarClose1","Limit":2,"Difficulty":"normal"},
{"Role":"followerBoarClose2","Limit":2,"Difficulty":"normal"},
{"Role":"bossBoarSniper","Limit":2,"Difficulty":"normal"},
{"Role":"exUsec","Limit":2,"Difficulty":"normal"},
{"Role":"bossZryachiy","Limit":2,"Difficulty":"normal"},
{"Role":"followerZryachiy","Limit":2,"Difficulty":"normal"},
{"Role":"bossKnight","Limit":2,"Difficulty":"normal"},
{"Role":"followerBigPipe","Limit":2,"Difficulty":"normal"},
{"Role":"followerBirdEye","Limit":2,"Difficulty":"normal"},
{"Role":"bossBully","Limit":2,"Difficulty":"normal"},
{"Role":"followerBully","Limit":2,"Difficulty":"normal"},
{"Role":"sectantPriest","Limit":2,"Difficulty":"normal"},
{"Role":"sectantWarrior","Limit":2,"Difficulty":"normal"},
{"Role":"bossTagilla","Limit":2,"Difficulty":"normal"},
{"Role":"gifter","Limit":2,"Difficulty":"normal"},
{"Role":"bossSanitar","Limit":2,"Difficulty":"normal"},
{"Role":"bossKilla","Limit":2,"Difficulty":"normal"},
{"Role":"bossKojaniy","Limit":2,"Difficulty":"normal"},
{"Role":"followerKojaniy","Limit":2,"Difficulty":"normal"},
{"Role":"skier","Limit":2,"Difficulty":"normal"},
{"Role":"peacemaker","Limit":2,"Difficulty":"normal"}
]

View File

@ -0,0 +1,15 @@
{
"Name": "Dumper",
"MapNames": [ "Interchange", "factory4_day", "laboratory", "bigmap", "Lighthouse", "RezervBase", "Sandbox", "Sandbox_high", "Shoreline", "TarkovStreets", "Woods" ],
"DateTimeFormat": "yyyy-MM-dd_HH-mm-ss",
"QuickDumpEnabled": true,
"SptTimings": {
"SingleIterationDelayMs": 10000,
"AllIterationDelayMs": 300000
},
"SptReflections": {
"MainUrlPropName": "get_MainURLFull",
"ParamFieldName": "Params",
"RequestFieldName": "responseText"
}
}

View File

@ -0,0 +1,7 @@
{
"serverId": null,
"location": "Lighthouse",
"timeVariant": "CURR",
"mode": "PVE_OFFLINE",
"playerSide": "Pmc"
}

BIN
Assets/Dumper/DumpLib.dll Normal file

Binary file not shown.

20
DumpLib/DumpLib.csproj Normal file
View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net471</TargetFramework>
<RootNamespace>DumpLib</RootNamespace>
<Version>1.0.0</Version>
<LangVersion>latestmajor</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<DestinationFolder>..\Assets\Dumper</DestinationFolder>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<Target Name="CopyDll" AfterTargets="Build">
<Exec Command="copy $(TargetPath) $(DestinationFolder)" />
</Target>
</Project>

338
DumpLib/DumpyTool.cs Normal file
View File

@ -0,0 +1,338 @@
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using DumpLib.Helpers;
using DumpLib.Models;
namespace DumpLib
{
public static class DumpyTool
{
/// <summary>
///
/// </summary>
public static string DumpDataPath = (Directory.GetCurrentDirectory() + "\\DUMPDATA\\").Replace("\\\\", "\\");
public static SptConfigClass ConfigSettings = (SptConfigClass)GetSptConfig();
/// <summary>
/// always start from 1 as their iterations are 1 to 6
/// </summary>
public static int Iteration = 1;
/// <summary>
/// <para>Method to create a "combined" Type that takes a GenericType</para>
/// <para>Example: ClientApplication + GInterface145 = ClientApplication(GInterface145)</para>
/// </summary>
/// <param name="firstType">Object (Type)</param>
/// <param name="secondType">Object (Type)</param>
/// <returns>Type</returns>
public static Type CreateGenericType(object firstType, object secondType)
{
try
{
return (firstType as Type).MakeGenericType(new Type[] { secondType as Type });
}
catch (Exception e)
{
UtilsHelper.LogError("CreateCombinedType");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static MethodInfo CreateDeserializerMethod(object type)
{
try
{
return ReflectionHelper.GetDeserializerMethodInfo().MakeGenericMethod(new Type[] { type as Type });
}
catch (Exception e)
{
UtilsHelper.LogError("CreateCombinedMethod");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static object CreateBackendSessionAndTarkovApp(out object tarkovApp)
{
try
{
// To get to this point and keeping this generic
// Get types required
var singletonType = ReflectionHelper.GetSingletonType();
var clientApplicationType = ReflectionHelper.GetClientApplicationType();
var interfaceType = ReflectionHelper.GetInterfaceType();
// Create singleton
var clientApplicationInterfaceType = CreateGenericType(clientApplicationType, interfaceType);
var singletonClientApplicationInterfaceType = CreateGenericType(singletonType, clientApplicationInterfaceType);
// Get singleton instance
var singletonClientApplicationInterfaceInstance = ReflectionHelper.GetSingletonInstance(singletonClientApplicationInterfaceType);
tarkovApp = singletonClientApplicationInterfaceInstance;
return ReflectionHelper.GetBackendSession(singletonClientApplicationInterfaceInstance);
}
catch (Exception e)
{
UtilsHelper.LogError("CreateBackendSession");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static object GetWaveSettings()
{
try
{
// combine List<> and WaveSettingsType
var listWaveType = CreateGenericType(ReflectionHelper.GetListType(), ReflectionHelper.GetWaveSettingsType());
// combine with JsonConvert.DeserializeObject<>() and invoke with getCurrentDir + "\\DUMPDATA\\.replace("\\\\","\\") + "botReqData.json";
return CreateDeserializerMethod(listWaveType).Invoke(null, new[] { File.ReadAllText(Path.Combine(DumpDataPath, "botReqData.json")) });
}
catch (Exception e)
{
UtilsHelper.LogError("GetWaveSettings");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static object GetSptConfig()
{
try
{
return CreateDeserializerMethod(typeof(SptConfigClass)).Invoke(null,
new[] { File.ReadAllText(Path.Combine(DumpDataPath, "config.json")) });
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public static object GetRaidSettings()
{
try
{
return CreateDeserializerMethod(ReflectionHelper.GetLocalRaidSettingsType()).Invoke(null,
new[] { File.ReadAllText(Path.Combine(DumpDataPath, "raidSettings.json")) });
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public static bool GotBackend = false;
public static object WaveSettings = null;
public static object RaidSettings = null;
public static object AppRaidSettings = null;
public static FieldInfo MainMenuController = null;
public static object Session = null;
public static object TarkovApp = null;
public static int ErrorCounter = 0;
/// <summary>
/// Method to run main menu Task, this will request data from BSG, map loot and bot data
/// </summary>
public static async Task StartDumpyTask()
{
if (!ConfigSettings.QuickDumpEnabled)
{
return;
}
await Task.Factory.StartNew(async delegate
{
UtilsHelper.LogInfo("[Dumpy] Starting Dumpy Loop");
while (true)
{
try
{
if (!GotBackend)
{
// get client backend session
Session = CreateBackendSessionAndTarkovApp(out TarkovApp);
// get field for MainMenuController
MainMenuController = ReflectionHelper.GetMainMenuControllerField();
// get wave information from json
WaveSettings = GetWaveSettings();
// get Raid Settings from json
RaidSettings = GetRaidSettings();
// get Raid settings from tarkovApp
AppRaidSettings = ReflectionHelper.GetRaidSettingsFromApp(TarkovApp);
CheckVariableConditions();
GotBackend = true;
}
}
catch (Exception e)
{
UtilsHelper.LogError("[Dumpy] Exception occured in StartDumpyTask::GotBackend");
UtilsHelper.LogError(e);
if (ErrorCounter > 3)
{
UtilsHelper.LogError("[Dumpy] ErrorsCounter was above 3, exiting app!");
// use EFT method to close app
ReflectionHelper.GetApplicationQuitMethod().Invoke(null, null);
}
ErrorCounter += 1;
UtilsHelper.LogError("[Dumpy] Resetting backend and trying again");
ClearVariables();
}
try
{
if (Iteration > 6)
{
// reset to 1
Iteration = 1;
UtilsHelper.LogInfo($"[Dumpy] Restarting Loop in {ConfigSettings.SptTimings.AllIterationDelayMs}ms");
var controller = MainMenuController.GetValue(TarkovApp);
if (controller != null)
{
controller.GetType().GetMethod("StopAfkMonitor").Invoke(controller, null);
}
await Task.Delay(ConfigSettings.SptTimings.AllIterationDelayMs);
}
else
{
UtilsHelper.LogInfo($"Map iteration number: {Iteration}");
foreach (var map in ConfigSettings.MapNames)
{
// theory is send a request SendRaidSettings before starting
// Set location in the RaidSettings object
UtilsHelper.LogInfo($"[Dumpy] Setting RaidSettings location to: {map}");
RaidSettings.GetType().GetField("location").SetValue(RaidSettings, map);
// Call server with new map name
UtilsHelper.LogInfo($"[Dumpy] Getting loot for {map}");
await (Task)Session.GetType().GetMethod("LocalRaidStarted")
.Invoke(Session, new[] { RaidSettings });
// Call server with bot wave data
UtilsHelper.LogInfo($"[Dumpy] Getting Bot Data");
await (Task)Session.GetType().GetMethod("LoadBots")
.Invoke(Session, new[] { WaveSettings });
await Task.Delay(ConfigSettings.SptTimings.SingleIterationDelayMs);
}
Iteration++;
}
}
catch (Exception e)
{
UtilsHelper.LogError("[Dumpy] Exception occured in StartDumpyTask::Iteration");
UtilsHelper.LogError(e);
if (ErrorCounter > 3)
{
UtilsHelper.LogError("[Dumpy] ErrorsCounter was above 3, exiting app");
// use EFT method to close app
ReflectionHelper.GetApplicationQuitMethod().Invoke(null, null);
}
ErrorCounter += 1;
UtilsHelper.LogError("[Dumpy] Resetting backend and trying again");
ClearVariables();
}
}
}, TaskCreationOptions.LongRunning);
}
private static void CheckVariableConditions()
{
UtilsHelper.LogInfo($"[Dumpy] CheckVariableConditions");
UtilsHelper.LogInfo($"[Dumpy] GotBackend- type: {GotBackend.GetType()} null?: {GotBackend == null}");
UtilsHelper.LogInfo($"[Dumpy] WaveSettings- type: {WaveSettings.GetType()} null?: {WaveSettings == null}");
UtilsHelper.LogInfo($"[Dumpy] MainMenuController- type: {MainMenuController.GetType()} null?: {MainMenuController == null}");
UtilsHelper.LogInfo($"[Dumpy] Session- type: {Session.GetType()} null?: {Session == null}");
UtilsHelper.LogInfo($"[Dumpy] TarkovApp- type: {TarkovApp.GetType()} null?: {TarkovApp == null}");
UtilsHelper.LogInfo($"[Dumpy] RaidSettings- type: {RaidSettings.GetType()} null?: {RaidSettings == null}");
UtilsHelper.LogInfo($"[Dumpy] CheckVariableConditions");
UtilsHelper.LogInfo($"[Dumpy] AppRaidSettings- type: {AppRaidSettings.GetType()} null?: {AppRaidSettings == null}");
UtilsHelper.LogInfo($"[Dumpy] CheckVariableConditions");
UtilsHelper.LogInfo($"[Dumpy] -----------------------------------------------------------------------------");
}
private static void ClearVariables()
{
GotBackend = false;
WaveSettings = null;
MainMenuController = null;
Session = null;
TarkovApp = null;
RaidSettings = null;
AppRaidSettings = null;
}
/// <summary>
/// Method to log Requests and Responses
/// </summary>
/// <param name="requestType">object (Type)</param>
/// <param name="responseType">object (Type)</param>
public static void LogRequestResponse(object requestType, object responseText)
{
try
{
var uri = new Uri((string)requestType.GetType().GetMethod(ConfigSettings.SptReflections.MainUrlPropName).Invoke(requestType, null));
var path = (Directory.GetCurrentDirectory() + "\\HTTP_DATA\\").Replace("\\\\", "\\");
var file = uri.LocalPath.Replace("/", ".").Remove(0, 1);
var time = DateTime.Now.ToString(ConfigSettings.DateTimeFormat);
if (Directory.CreateDirectory(path).Exists)
{
var reqParams = requestType.GetType().GetField(ConfigSettings.SptReflections.ParamFieldName).GetValue(requestType);
if (Directory.CreateDirectory($@"{path}req.{file}").Exists)
{
if (reqParams != null)
File.WriteAllText($@"{path}req.{file}\\req.{file}_{time}_{ConfigSettings.Name}.json", JsonConvert.SerializeObject(reqParams));
}
if (Directory.CreateDirectory($@"{path}resp.{file}").Exists)
File.WriteAllText($@"{path}resp.{file}\\resp.{file}_{time}_{ConfigSettings.Name}.json", (string)responseText);
}
}
catch (Exception e)
{
UtilsHelper.LogError("[Dumpy] Exception occured at LogRequestResponse");
UtilsHelper.LogError(e);
throw;
}
}
}
}

View File

@ -0,0 +1,260 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace DumpLib.Helpers
{
public static class ReflectionHelper
{
private static Assembly _newtonAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\Newtonsoft.Json.dll").Replace("\\\\", "\\"));
private static Assembly _msAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\mscorlib.dll").Replace("\\\\", "\\"));
private static Assembly _eftAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\Assembly-CSharp.dll").Replace("\\\\", "\\"));
private static Assembly _comfortAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\Comfort.dll").Replace("\\\\", "\\"));
/// <summary>
/// Method to get Singleton<> type from Comfort.dll
/// </summary>
/// <returns>Type</returns>
public static Type GetSingletonType()
{
try
{
return _comfortAssembly.GetTypes().First(x => x.Name.StartsWith("Singleton"));
}
catch (Exception e)
{
UtilsHelper.LogError("GetSingletonType");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get ClientApplication<> type from EFT's assembly
/// </summary>
/// <returns>Type</returns>
public static Type GetClientApplicationType()
{
try
{
return _eftAssembly.GetTypes().First(x => x.Name.StartsWith("ClientApplication"));
}
catch (Exception e)
{
UtilsHelper.LogError("GetClientApplicationType");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get (as of 25/01/2024 - GInterface145) type from EFT's assembly
/// </summary>
/// <returns>Type</returns>
public static Type GetInterfaceType()
{
try
{
return _eftAssembly.GetTypes()
.First(x => x.IsInterface && x.GetMethods().Any(m => m.Name == "GetPhpSessionId"));
}
catch (Exception e)
{
UtilsHelper.LogError("GetInterfaceType");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get TarkovApplication type from EFT's assembly
/// </summary>
/// <returns>Type</returns>
public static Type GetTarkovApplicationType()
{
try
{
return _eftAssembly.GetTypes().First(x => x.Name == "TarkovApplication");
}
catch (Exception e)
{
UtilsHelper.LogError("GetTarkovApplicationType");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get (as of 25/01/2024 - GClass1464) type from EFT's assembly
/// </summary>
/// <returns></returns>
public static object GetWaveSettingsType()
{
try
{
return _eftAssembly.GetTypes().First(x =>
{
// if type contains Role, Limit and Difficulty, return true
var fields = x.GetFields();
if (fields.Any(f => f.Name == "Role") && fields.Any(f => f.Name == "Limit") && fields.Any(f => f.Name == "Difficulty") && fields.Length == 3)
return true;
return false;
});
}
catch (Exception e)
{
UtilsHelper.LogError("GetWaveSettingsType");
UtilsHelper.LogError(e);
throw;
}
}
public static Type GetListType()
{
try
{
return _msAssembly.GetTypes().First(x => x.Name.StartsWith("List") && x.Namespace == "System.Collections.Generic");
}
catch (Exception e)
{
UtilsHelper.LogError("GetListType");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get FieldInfo of a field on the TarkovApplication Type for later use
/// </summary>
/// <returns>FieldInfo</returns>
public static FieldInfo GetMainMenuControllerField()
{
try
{
return GetTarkovApplicationType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(x => x.FieldType.GetMethods().Any(m => m.Name == "StopAfkMonitor"));
}
catch (Exception e)
{
UtilsHelper.LogError("GetMainMenuControllerField");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get the Instance of a Singleton(Type) passed in
/// </summary>
/// <param name="singletonType">object (Type)</param>
/// <param name="instance">object (Type)</param>
/// <returns>object</returns>
public static object GetSingletonInstance(object singletonType)
{
try
{
return (singletonType as Type).GetProperty("Instance", BindingFlags.Public | BindingFlags.Static)
.GetGetMethod().Invoke(singletonType, null);
}
catch (Exception e)
{
UtilsHelper.LogError("GetSingletonInstance");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get BackendSession object from the instance passed in
/// </summary>
/// <param name="instance">object (Type)</param>
/// <returns>object</returns>
public static object GetBackendSession(object instance)
{
try
{
return GetTarkovApplicationType().GetMethod("GetClientBackEndSession").Invoke(instance, null);
}
catch (Exception e)
{
UtilsHelper.LogError("GetBackendSession");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get DeserializeObject from Newtonsoft assembly
/// </summary>
/// <returns>MethodInfo</returns>
public static MethodInfo GetDeserializerMethodInfo()
{
try
{
return _newtonAssembly.GetTypes().First(x => x.Name == "JsonConvert").GetMethods().First(m =>
m.Name == "DeserializeObject" && m.IsGenericMethodDefinition && m.GetParameters().Length == 1 &&
m.GetParameters().Any(p => p.ParameterType == typeof(string)));
}
catch (Exception e)
{
UtilsHelper.LogError("GetDeserializerMethodInfo");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get Quit method from EFT (as of 20/05/2024 - GClass1955)
/// </summary>
/// <returns>MethodInfo</returns>
public static MethodInfo GetApplicationQuitMethod()
{
try
{
return _eftAssembly.GetTypes().First(x => x.GetMethods().Any(y => y.Name == "Quit")).GetMethod("Quit");
}
catch (Exception e)
{
UtilsHelper.LogError("GetApplicationQuitMethod");
UtilsHelper.LogError(e);
throw;
}
}
/// <summary>
/// Method to get LocalRaidSettings Type from EFT
/// </summary>
/// <returns>object</returns>
public static object GetLocalRaidSettingsType()
{
try
{
return _eftAssembly.GetTypes().First(x => x.Name == "LocalRaidSettings");
}
catch (Exception e)
{
UtilsHelper.LogError("GetLocalRaidSettingsType");
UtilsHelper.LogError(e);
throw;
}
}
public static object GetRaidSettingsFromApp(object tarkovApp)
{
try
{
return tarkovApp.GetType().GetField("_raidSettings").GetValue(tarkovApp);
}
catch (Exception e)
{
UtilsHelper.LogError("GetRaidSettingsFromApp");
UtilsHelper.LogError(e);
throw;
}
}
}
}

View File

@ -0,0 +1,64 @@
using System;
using System.IO;
namespace DumpLib.Helpers
{
public static class UtilsHelper
{
private static string _loggerPath = (Directory.GetCurrentDirectory() + "\\DUMPDATA\\Log.txt").Replace("\\\\", "\\");
/// <summary>
/// Log message to something
/// </summary>
/// <param name="message">object</param>
private static void LogMessage(object message, string messageType)
{
StreamWriter writer = null;
try
{
writer = new StreamWriter(_loggerPath, true);
writer.WriteLine($"[{messageType}] - {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}");
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
finally
{
if (writer != null)
{
writer.Close();
writer.Dispose();
}
}
}
/// <summary>
/// Log message to something
/// </summary>
/// <param name="message">object</param>
public static void LogError(object message)
{
LogMessage(message, "Error");
}
/// <summary>
/// Log message to something
/// </summary>
/// <param name="message">object</param>
public static void LogInfo(object message)
{
LogMessage(message, "Info");
}
/// <summary>
/// Log message to something
/// </summary>
/// <param name="message">object</param>
public static void LogDebug(object message)
{
LogMessage(message, "Debug");
}
}
}

View File

@ -0,0 +1,57 @@
namespace DumpLib.Models
{
public class SptConfigClass
{
/// <summary>
/// Default: Test
/// </summary>
public string Name { get; set; }
/// <summary>
/// Default: [ "Interchange", "factory4_day", "laboratory", "bigmap", "Lighthouse", "RezervBase", "Sandbox", "Shoreline", "TarkovStreets", "Woods" ]
/// </summary>
public string[] MapNames { get; set; }
/// <summary>
/// Default: "yyyy-MM-dd_HH-mm-ss"
/// </summary>
public string DateTimeFormat { get; set; }
public bool QuickDumpEnabled { get; set; }
public SptReflections SptReflections { get; set; }
public SptTimings SptTimings { get; set; }
}
public class SptTimings
{
/// <summary>
/// Default: 10s * 1000ms = 10000ms
/// </summary>
public int SingleIterationDelayMs { get; set; }
/// <summary>
/// Default: 5m * 60s * 1000ms = 300000ms
/// </summary>
public int AllIterationDelayMs { get; set; }
}
public class SptReflections
{
/// <summary>
/// Default: "get_MainURLFull" as of 128476 client
/// </summary>
public string MainUrlPropName { get; set; }
/// <summary>
/// Default: "Params" as of 128476 client
/// </summary>
public string ParamFieldName { get; set; }
/// <summary>
/// Default: "responseText" as of 128476 client
/// </summary>
public string RequestFieldName { get; set; }
}
}

View File

@ -0,0 +1,39 @@
using CliFx;
using CliFx.Attributes;
using CliFx.Infrastructure;
using ReCodeIt.Utils;
using ReCodeItLib.Dumper;
namespace ReCodeIt.Commands;
[Command("Dumper", Description = "Generates a dumper zip")]
public class Dumper : ICommand
{
[CommandParameter(0, IsRequired = true, Description = "The absolute path to your DeObfuscated assembly file, folder must contain all references to be resolved.")]
public string GameAssemblyPath { get; init; }
[CommandParameter(1, IsRequired = true, Description = "The absolute path to your FileChecker.dll file, folder must contain all refgerences to be resolved.")]
public string CheckerAssemblyPath { get; init; }
private Dumpy _dumpy { get; set; }
public ValueTask ExecuteAsync(IConsole console)
{
DataProvider.IsCli = true;
DataProvider.LoadAppSettings();
Logger.Log("Creating Dumper...");
_dumpy = new Dumpy(GameAssemblyPath, CheckerAssemblyPath, Path.GetDirectoryName(GameAssemblyPath));
_dumpy.CreateDumpFolders();
_dumpy.CreateDumper();
Logger.Log("Complete", ConsoleColor.Green);
// Wait for log termination
Logger.Terminate();
while (Logger.IsRunning()) { }
return default;
}
}

View File

@ -9,8 +9,8 @@
</PropertyGroup> </PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> <Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy &quot;$(SolutionDir)Templates&quot; &quot;$(TargetDir)Data&quot; /E /I /Y" /> <Exec Command="xcopy &quot;$(SolutionDir)/Assets/Templates&quot; &quot;$(TargetDir)Data&quot; /E /I /Y" />
<Exec Command="xcopy &quot;$(SolutionDir)de4dot&quot; &quot;$(TargetDir)Data/de4dot&quot; /E /I /Y" /> <Exec Command="xcopy &quot;$(SolutionDir)/Assets/de4dot&quot; &quot;$(TargetDir)Data/de4dot&quot; /E /I /Y" />
</Target> </Target>
<ItemGroup> <ItemGroup>

View File

@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReCodeItLib", "RecodeItLib\
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReCodeIt", "ReCodeItCLI\ReCodeIt.csproj", "{E404EC0B-06D2-4964-8ABA-A634F259655C}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReCodeIt", "ReCodeItCLI\ReCodeIt.csproj", "{E404EC0B-06D2-4964-8ABA-A634F259655C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DumpLib", "DumpLib\DumpLib.csproj", "{D0837899-F129-46DB-8BDB-7C9AFB72BD30}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -83,6 +85,26 @@ Global
{E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x64.Build.0 = Release|Any CPU {E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x64.Build.0 = Release|Any CPU
{E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x86.ActiveCfg = Release|Any CPU {E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x86.ActiveCfg = Release|Any CPU
{E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x86.Build.0 = Release|Any CPU {E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x86.Build.0 = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM.Build.0 = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM64.Build.0 = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x64.ActiveCfg = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x64.Build.0 = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x86.ActiveCfg = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x86.Build.0 = Debug|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|Any CPU.Build.0 = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM.ActiveCfg = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM.Build.0 = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM64.ActiveCfg = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM64.Build.0 = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x64.ActiveCfg = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x64.Build.0 = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x86.ActiveCfg = Release|Any CPU
{D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

331
RecodeItLib/Dumper/Dumpy.cs Normal file
View File

@ -0,0 +1,331 @@
using System.Collections;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using ReCodeIt.Utils;
namespace ReCodeItLib.Dumper;
public class Dumpy
{
private ModuleDefMD? _gameModule { get; set; }
private ModuleDefMD? _checkerModule { get; set; }
private string _assemblyPath { get; set; }
private string _fileCheckerPath { get; set; }
private string _path { get; set; }
private List<TypeDef>? _gameTypes { get; set; }
private List<TypeDef>? _checkerTypes { get; set; }
public Dumpy(string assemblyPath, string fileCheckerPath, string path)
{
_assemblyPath = assemblyPath;
_fileCheckerPath = fileCheckerPath;
_path = path;
if (!File.Exists(_assemblyPath))
{
Logger.Log($"File does not exist at: {_assemblyPath}", ConsoleColor.Red);
return;
}
if (!File.Exists(_fileCheckerPath))
{
Logger.Log($"File does not exist at: {_fileCheckerPath}", ConsoleColor.Red);
return;
}
_gameModule = DataProvider.LoadModule(_assemblyPath);
_checkerModule = DataProvider.LoadModule(_fileCheckerPath);
_gameTypes = _gameModule.GetTypes().ToList();
_checkerTypes = _checkerModule.GetTypes().ToList();
}
public void CreateDumper()
{
if (_gameModule == null || _gameTypes == null)
{
Logger.Log($"_gameModule or _gameTypes in Dumpy was null", ConsoleColor.Red);
return;
}
if (_checkerModule == null || _checkerTypes == null)
{
Logger.Log($"_checkerModule or _checkerTypes in Dumpy was null", ConsoleColor.Red);
return;
}
// make changes to assembly
// get required types
// var backRequestType = _gameTypes.Where(DumpyTypeHelper.GetBackRequestType).ToList();
// var validateCertType = _gameTypes.Where(DumpyTypeHelper.GetValidateCertType).ToList();
// var runValidationType = _gameTypes.Where(DumpyTypeHelper.GetRunValidationType).ToList();
// var dumpyTaskType = _gameTypes.Where(DumpyTypeHelper.GetMenuscreenType).ToList();
// check types
// CheckNullOrMulti(backRequestType, "BackRequest");
// CheckNullOrMulti(validateCertType, "ValidateCertificate");
// CheckNullOrMulti(runValidationType, "RunValidation");
// CheckNullOrMulti(dumpyTaskType, "DumpyTask");
// apply code changes
// SetBackRequestCode(backRequestType[0]);
// SetValidateCertCode(validateCertificateType[0]);
// SetRunValidationCode(runValidationType[0]);
// SetDumpyTaskCode(dumpyTaskType[0]);
// TODO: Write game assembly to file
// get types
// var ensureConsistencyTypes = _checkerTypes.Where(DumpyTypeHelper.GetEnsureConsistencyType).ToList();
// check types
// CheckNullOrMulti(ensureConsistencyTypes, "EnsureConsistency");
// apply code changes
// SetEnsureConsistencyCode(ensureConsistencyType[0]);
// SetEnsureConsistencySingleCode(ensureConsistencyType[0]);
// TODO: Write fileChecker assembly to file
}
public void CreateDumpFolders()
{
// create dumper folders
}
/// <summary>
/// Checks for null or multiple types
/// </summary>
/// <param name="types">ICollection</param>
/// <param name="name">string</param>
private void CheckNullOrMulti(ICollection types, string name = "")
{
if (types == null)
{
Logger.Log($"{name} was null");
}
if (types.Count > 1)
{
Logger.Log($"{name} count was more than 1");
}
}
/// <summary>
/// <para>Finds the method with backRequest and bResponse as params.</para>
/// <para>Checks the method instructions before modification has a count of 269,</para>
/// <para>if this is not the case, this needs to be checked.</para>
/// <para>This type passed in is the only type with this method.</para>
/// </summary>
/// <param name="oldAssembly"></param>
/// <param name="type"></param>
private void SetBackRequestCode(TypeDef type)
{
// find method
var method = type.Methods.First(x => x.Parameters.Any(p => p.Name is "backRequest" && x.Parameters.Any(p => p.Name == "bResponse")));
if (method == null || method.Body.Instructions.Count != 269)
{
Logger.Log($"BackRequest Instructions count has changed from 269 to {method.Body.Instructions.Count}", ConsoleColor.Red);
}
var startOfInstructions = 252;
// var liList = DumpyInstructionsHelper.GetBackRequestInstructions();
var index = method.Body.Instructions[startOfInstructions];
// foreach (var li in liList)
// {
// // something along these lines, this needs to be tested
// method.Body.Instructions.InsertBefore(index, li);
// }
// create instruction
var ins = Instruction.Create(OpCodes.Brfalse_S, method.Body.Instructions[startOfInstructions]);
// replace instruction at 220 with this
method.Body.Instructions[220] = ins;
}
/// <summary>
/// <para>Finds the method called ValidateCertificate.</para>
/// <para>Checks that we found two of these methods,</para>
/// <para>if this is not the case, this needs to be checked.</para>
/// <para>This type passed in is the only type with this method.</para>
/// </summary>
/// <param name="oldAssembly"></param>
/// <param name="type"></param>
private void SetValidateCertCode(TypeDef type)
{
var methods = type.Methods.Where(x =>
x.Name == "ValidateCertificate"); // should be 2
// check make sure nothing has changed
var firstMethod = methods.FirstOrDefault(m => m.Parameters.Any(p => p.Name == "certificate"));
var secondMethod = methods.FirstOrDefault(m => m.Parameters.Any(p => p.Name == "certificateData"));
if (firstMethod?.Body.Instructions.Count != 55 || secondMethod?.Body.Instructions.Count != 14)
{
Logger.Log($"Instruction count has changed, method with 'certificate' as a param - before: 51, now: {firstMethod.Body.Instructions.Count}, " +
$"method with 'certificateData' as a param - before: 14, now: {secondMethod.Body.Instructions.Count}", ConsoleColor.Red);
}
if (methods.Count() != 2)
{
Logger.Log($"ValidateCertificate should be found twice, count was: {methods.Count()}", ConsoleColor.Red);
}
foreach (var method in methods)
{
// clear these from the body.
method.Body.Instructions.Clear();
method.Body.Variables.Clear();
method.Body.ExceptionHandlers.Clear();
// return true;
var ins = Instruction.Create(OpCodes.Ldc_I4_1);
var ins1 = Instruction.Create(OpCodes.Ret);
// add instructions
method.Body.Instructions.Add(ins);
method.Body.Instructions.Add(ins1);
}
}
/// <summary>
/// <para>Finds the method called RunValidation and MoveNext.</para>
/// <para>Checks that we found two of these methods,</para>
/// <para>if this is not the case, this needs to be checked.</para>
/// <para>This type passed in is the only type with this method.</para>
/// </summary>
/// <param name="oldAssembly"></param>
/// <param name="type"></param>
private void SetRunValidationCode(TypeDef type)
{
var method = type.Methods.First(x => x.Name == "RunValidation");
var method2 = type.NestedTypes[0].Methods.First(x => x.Name == "MoveNext");
if (method == null || method.Body.Instructions.Count != 25)
{
Logger.Log($"RunValidation Instructions count has changed from 25 to {method.Body.Instructions.Count}");
}
if (method2 == null || method2.Body.Instructions.Count != 171)
{
Logger.Log($"RunValidation's MoveNext Instructions count has changed from 171 to {method2.Body.Instructions.Count}");
}
// Clear these from the body of each method respectively
method.Body.Instructions.Clear();
method2.Body.Instructions.Clear();
method2.Body.Variables.Clear();
method2.Body.ExceptionHandlers.Clear();
// var liList = DumpyInstructionsHelper.GetRunValidationInstructions(oldAssembly, method);
// var liList2 = DumpyInstructionsHelper.GetRunValidationInstructionsMoveNext(oldAssembly, method2);
// foreach (var instruction in liList)
// {
// method.Body.Instructions.Append(instruction);
// }
//
// foreach (var instruction in liList2)
// {
// method2.Body.Instructions.Append(instruction);
// }
var ins = Instruction.Create(OpCodes.Leave_S, method2.Body.Instructions[14]); // Create instruction to jump to index 14
var ins1 = Instruction.Create(OpCodes.Leave_S, method2.Body.Instructions[method2.Body.Instructions.IndexOf(method2.Body.Instructions.Last())]); // Create instruction to jump to last index
method2.Body.Instructions.InsertAfter(method2.Body.Instructions[5], ins); // Instruction to jump from 5 to 14
method2.Body.Instructions.InsertAfter(method2.Body.Instructions[14], ins1); // Instruction to jump from 14 to last index
// Create exception handler with defined indexes
var handler = new ExceptionHandler(ExceptionHandlerType.Catch)
{
TryStart = method2.Body.Instructions[3],
TryEnd = method2.Body.Instructions[7],
HandlerStart = method2.Body.Instructions[7],
HandlerEnd = method2.Body.Instructions[16],
// CatchType = method2.Module.ImportReference(typeof(Exception)), // needs fixing
};
// Add exception handler to method body
method2.Body.ExceptionHandlers.Add(handler);
}
private void SetDumpyTaskCode(TypeDef type)
{
var method = type.Methods.First(x => x.Name == "Awake");
if (method == null || method.Body.Instructions.Count != 62)
{
Logger.Log($"MainMenu is null or isnt 62 instructions, SOMETHING HAD CHANGED!", ConsoleColor.Red);
}
// var liList = DumpyInstructionsHelper.GetDumpyTaskInstructions(oldAssembly, method);
var index = method.Body.Instructions.First(x => x.OpCode == OpCodes.Ret);
// foreach (var item in liList)
// {
// method.Body.Instructions.InsertBefore(index, item);
// }
}
/// <summary>
/// <para>Finds the method called EnsureConsistency.</para>
/// <para>if this is not the case, this needs to be checked.</para>
/// <para>This type passed in is the only type with this method.</para>
/// </summary>
/// <param name="oldFileChecker"></param>
/// <param name="type"></param>
private static void SetEnsureConsistencyCode(TypeDef type)
{
var method = type.Methods.First(x => x.Name == "EnsureConsistency");
if (method == null || method.Body.Instructions.Count != 152)
{
Logger.Log($"EnsureConsistency Instructions count has changed from 152 to {method.Body.Instructions.Count}", ConsoleColor.Red);
}
// clear these from the method body
method.Body.Instructions.Clear();
method.Body.Variables.Clear();
method.Body.ExceptionHandlers.Clear();
// var liList = DumpyInstructionsHelper.GetEnsureConsistencyInstructions(oldFileChecker, method);
//
// foreach (var li in liList)
// {
// method.Body.Instructions.Append(li);
// }
}
/// <summary>
/// <para>Finds the method called EnsureConsistencySingle.</para>
/// <para>if this is not the case, this needs to be checked.</para>
/// <para>This type passed in is the only type with this method.</para>
/// </summary>
/// <param name="oldFileChecker"></param>
/// <param name="type"></param>
private static void SetEnsureConsistencySingleCode(TypeDef type)
{
var method = type.Methods.First(x => x.Name == "EnsureConsistencySingle");
if (method == null || method.Body.Instructions.Count != 101)
{
Logger.Log($"EnsureConsistencySingle Instructions count has changed from 101 to {method.Body.Instructions.Count}", ConsoleColor.Red);
}
// clear these from the method body
method.Body.Instructions.Clear();
method.Body.Variables.Clear();
method.Body.ExceptionHandlers.Clear();
// var liList = DumpyInstructionsHelper.GetEnsureConsistencyInstructions(oldFileChecker, method);
//
// foreach (var li in liList)
// {
// method.Body.Instructions.Append(li);
// }
}
}

View File

@ -0,0 +1,170 @@
// using System;
// using System.Collections.Generic;
// using System.Linq;
// using System.Threading.Tasks;
// using DumpLib;
//
// namespace ReCodeItLib.Dumper;
//
// public static class DumpyInstructionsHelper
// {
// /// <summary>
// /// <para>Sets up local variables and returns a List of instructions to add.</para>
// /// </summary>
// /// <param name="assembly">AssemblyDefinition</param>
// /// <param name="method">MethodDefinition</param>
// /// <returns>List<Instruction></returns>
// public static List<Instruction> GetBackRequestInstructions(AssemblyDefinition assembly, MethodDefinition method)
// {
// return new List<Instruction>
// {
// Instruction.Create(OpCodes.Ldarg_1),
// Instruction.Create(OpCodes.Ldloc_S, method.Body.Variables[6]),
// Instruction.Create(OpCodes.Call, assembly.MainModule.ImportReference(typeof(DumpLib.DumpyTool).GetMethod("LogRequestResponse", new[] { typeof(object), typeof(object) })))
// };
// }
//
// /// <summary>
// /// <para>Returns a List of instructions to be added to the method.</para>
// /// <para>This is an Async method so there is two parts, this part and a RunValidation method.</para>
// /// </summary>
// /// <param name="assembly">AssemblyDefinition</param>
// /// <param name="method">MethodDefinition</param>
// /// <returns>List<Instruction></returns>
// public static List<Instruction> GetRunValidationInstructionsMoveNext(AssemblyDefinition assembly, MethodDefinition method)
// {
// // Add our own local variables
//
// // var1 index0 class1159Type
// var sptClassType = assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType);
// var sptClass = new VariableDefinition(sptClassType);
// method.Body.Variables.Add(sptClass);
//
// // var2 index1 ExceptionType
// var sptExceptionType = method.Module.ImportReference(typeof(Exception));
// var sptException = new VariableDefinition(sptExceptionType);
// method.Body.Variables.Add(sptException);
//
// return new List<Instruction>
// {
// // most of this is to keep the Async happy
//
// Instruction.Create(OpCodes.Ldarg_0),
// Instruction.Create(OpCodes.Ldfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[2]),
// Instruction.Create(OpCodes.Stloc_0),
//
// // this.Succeed = true;
// Instruction.Create(OpCodes.Ldloc_0),
// Instruction.Create(OpCodes.Ldc_I4_1),
// Instruction.Create(OpCodes.Call, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).Methods.First(x => x.Name == "set_Succeed")),
//
// Instruction.Create(OpCodes.Stloc_1),
// Instruction.Create(OpCodes.Ldarg_0),
// Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)-2),
// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[0]),
// Instruction.Create(OpCodes.Ldarg_0),
// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
// Instruction.Create(OpCodes.Ldloc_1),
// Instruction.Create(OpCodes.Call,
// method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "SetException"))),
//
// Instruction.Create(OpCodes.Ldarg_0),
// Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)-2),
// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[0]),
//
// Instruction.Create(OpCodes.Ldarg_0),
// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
// Instruction.Create(OpCodes.Call, method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "SetResult"))),
//
// Instruction.Create(OpCodes.Ret),
// };
// }
//
// /// <summary>
// /// <para>Returns a List of instructions to be added to the method.</para>
// /// <para>This is an Async method so there is two parts, this part and a RunValidation method.</para>
// /// </summary>
// /// <param name="assembly">AssemblyDefinition</param>
// /// <param name="method">MethodDefinition</param>
// /// <returns>List<Instruction></returns>
// public static List<Instruction> GetEnsureConsistencyInstructions(AssemblyDefinition oldFileChecker, MethodDefinition method)
// {
// // init local vars
// // var1 index0 TimeSpan type
// var sptTimeSpanType = method.Module.ImportReference(typeof(TimeSpan));
// var sptClass = new VariableDefinition(sptTimeSpanType);
// method.Body.Variables.Add(sptClass);
//
// // Create genericInstance of a method
// var type = oldFileChecker.MainModule.GetTypes().First(DumpyTypeHelper.GetEnsureConsistencyType).NestedTypes[0].Interfaces[0].InterfaceType;
// var typeMethod = method.Module.ImportReference(typeof(Task).GetMethod("FromResult"));
// var instanceType = new GenericInstanceMethod(typeMethod);
// instanceType.GenericArguments.Add(type);
//
// return new List<Instruction>
// {
// // return Task.FromResult<ICheckResult>(ConsistencyController.CheckResult.Succeed(default(TimeSpan)));
// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
// Instruction.Create(OpCodes.Initobj, method.Module.ImportReference(typeof(TimeSpan))),
// Instruction.Create(OpCodes.Ldloc_0),
// Instruction.Create(OpCodes.Call, oldFileChecker.MainModule.GetTypes().First(DumpyTypeHelper.GetEnsureConsistencyType).NestedTypes[0].Methods.First(x => x.Name == "Succeed")),
// Instruction.Create(OpCodes.Call, instanceType),
// Instruction.Create(OpCodes.Ret)
// };
// }
//
// /// <summary>
// /// <para>Returns a List of instructions to be added to the method.</para>
// /// <para>This is an Async method so there is two parts, this part and a MoveNext method.</para>
// /// </summary>
// /// <param name="assembly">AssemblyDefinition</param>
// /// <param name="method">MethodDefinition</param>
// /// <returns>List<Instruction></returns>
// public static List<Instruction> GetRunValidationInstructions(AssemblyDefinition assembly, MethodDefinition method)
// {
// // Create genericInstance of a method
// var type = assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0];
// var typeMethod = method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "Start"));
// var instanceMethod = new GenericInstanceMethod(typeMethod);
// instanceMethod.GenericArguments.Add(type);
//
// return new List<Instruction>
// {
// // <RunValidation>d__.<>t__builder = AsyncTaskMethodBuilder.Create();
// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
// Instruction.Create(OpCodes.Call, method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "Create"))),
// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
//
// // <RunValidation>d__.<>4__this = this;
// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
// Instruction.Create(OpCodes.Ldarg_0),
// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[2]),
//
// // <RunValidation>d__.<>1__state = -1;
// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
// Instruction.Create(OpCodes.Ldc_I4_M1),
// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[0]),
//
// // <RunValidation>d__.<>t__builder.Start<Class1159.<RunValidation>d__0>(ref <RunValidation>d__);
// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
// Instruction.Create(OpCodes.Call, instanceMethod),
//
// // return <RunValidation>d__.<>t__builder.Task;
// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
// Instruction.Create(OpCodes.Call, method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "get_Task"))),
// Instruction.Create(OpCodes.Ret),
// };
// }
//
// public static List<Instruction> GetDumpyTaskInstructions(AssemblyDefinition oldAssembly, MethodDefinition method)
// {
// return new List<Instruction>
// {
// Instruction.Create(OpCodes.Call, oldAssembly.MainModule.ImportReference(typeof(DumpyTool).GetMethod("StartDumpyTask"))),
// Instruction.Create(OpCodes.Pop)
// };
// }
// }

View File

@ -0,0 +1,54 @@
// using System.Linq;
// using Mono.Cecil;
//
// namespace ReCodeItLib.Dumper;
//
// public static class DumpyTypeHelper
// {
// /// <summary>
// /// <para>Gets the type that has a method called SendAndHandleRetries.</para>
// /// <para>This type is the only one with method.</para>
// /// </summary>
// /// <param name="type">TypeDefinition</param>
// /// <returns>boolean</returns>
// public static bool GetBackRequestType(TypeDefinition type)
// {
// return type.Methods.Any(m => m.Name == "SendAndHandleRetries");
// }
//
// /// <summary>
// /// <para>Gets the type that has a method called ValidateCertificate as the name.</para>
// /// </summary>
// /// <param name="type">TypeDefinition</param>
// /// <returns>boolean</returns>
// public static bool GetValidateCertificateType(TypeDefinition type)
// {
// return type.Methods.Any(m => m.Name == "ValidateCertificate");
// }
//
// /// <summary>
// /// <para>Gets the type that has a method called RunValidation as the name.</para>
// /// </summary>
// /// <param name="type">TypeDefinition</param>
// /// <returns>boolean</returns>
// public static bool GetRunValidationType(TypeDefinition type)
// {
// return type.Methods.Any(m => m.Name == "RunValidation");
// }
//
// /// <summary>
// /// <para>Gets the type that has ConsistencyController as the name.</para>
// /// <para>FilesChecker.dll is not obfuscated.</para>
// /// </summary>
// /// <param name="type">TypeDefinition</param>
// /// <returns>boolean</returns>
// public static bool GetEnsureConsistencyType(TypeDefinition type)
// {
// return type.Name == "ConsistencyController";
// }
//
// public static bool GetMenuScreenType(TypeDefinition type)
// {
// return type.Name == "MenuScreen";
// }
// }

View File

@ -0,0 +1,49 @@
using dnlib.DotNet.Emit;
namespace ReCodeItLib.Dumper;
public static class InstructionsExtensions
{
public static void InsertBefore(this IList<Instruction> instructions, Instruction target, Instruction instruction)
{
if (target == null)
{
throw new ArgumentNullException(nameof (target));
}
if (instruction == null)
{
throw new ArgumentNullException(nameof (instruction));
}
int index = instructions.IndexOf(target);
if (index == -1)
{
throw new ArgumentOutOfRangeException(nameof (target));
}
instructions.Insert(index, instruction);
}
public static void InsertAfter(this IList<Instruction> instructions, Instruction target, Instruction instruction)
{
if (target == null)
{
throw new ArgumentNullException(nameof (target));
}
if (instruction == null)
{
throw new ArgumentNullException(nameof (instruction));
}
int index = instructions.IndexOf(target);
if (index == -1)
{
throw new ArgumentOutOfRangeException(nameof (target));
}
instructions.Insert(index + 1, instruction);
}
}

View File

@ -18,4 +18,14 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DumpLib\DumpLib.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="DumpLib">
<HintPath>Assets\DumpLib.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View File

@ -9,7 +9,7 @@ public static class Deobfuscator
{ {
public static void Deobfuscate(string assemblyPath) public static void Deobfuscate(string assemblyPath)
{ {
var executablePath = Path.Combine(DataProvider.DataPath, "De4dot", "de4dot.exe"); var executablePath = Path.Combine(DataProvider.DataPath, "Assets", "De4dot", "de4dot.exe");
string token; string token;