From f3d095a0a7a630f372249bb993c98b4c10f8495a Mon Sep 17 00:00:00 2001 From: CWX Date: Fri, 9 Aug 2024 21:39:39 +0100 Subject: [PATCH] initial start of dumper conversion, moved assets to a Assets folder, updated PB scripts --- Assets/Dumper/DUMPDATA/botReqData.json | 39 ++ Assets/Dumper/DUMPDATA/config.json | 15 + Assets/Dumper/DUMPDATA/raidSettings.json | 7 + Assets/Dumper/DumpLib.dll | Bin 0 -> 23040 bytes .../Templates}/MappingTemplate.jsonc | 0 .../Templates}/Settings.jsonc | 0 {de4dot => Assets/de4dot}/AssemblyData.dll | Bin {de4dot => Assets/de4dot}/de4dot.blocks.dll | Bin {de4dot => Assets/de4dot}/de4dot.code.dll | Bin {de4dot => Assets/de4dot}/de4dot.cui.dll | Bin {de4dot => Assets/de4dot}/de4dot.exe | Bin {de4dot => Assets/de4dot}/de4dot.mdecrypt.dll | Bin {de4dot => Assets/de4dot}/dnlib.dll | Bin DumpLib/DumpLib.csproj | 20 ++ DumpLib/DumpyTool.cs | 338 ++++++++++++++++++ DumpLib/Helpers/ReflectionHelper.cs | 260 ++++++++++++++ DumpLib/Helpers/UtilsHelper.cs | 64 ++++ DumpLib/Models/SptConfigClass.cs | 57 +++ ReCodeItCLI/Commands/Dumper.cs | 39 ++ ReCodeItCLI/ReCodeIt.csproj | 4 +- RecodeIt.sln | 22 ++ RecodeItLib/Dumper/Dumpy.cs | 331 +++++++++++++++++ RecodeItLib/Dumper/DumpyInstructionsHelper.cs | 170 +++++++++ RecodeItLib/Dumper/DumpyTypeHelper.cs | 54 +++ RecodeItLib/Dumper/InstructionsExtensions.cs | 49 +++ RecodeItLib/ReCodeItLib.csproj | 10 + RecodeItLib/Remapper/DeObfuscator.cs | 2 +- 27 files changed, 1478 insertions(+), 3 deletions(-) create mode 100644 Assets/Dumper/DUMPDATA/botReqData.json create mode 100644 Assets/Dumper/DUMPDATA/config.json create mode 100644 Assets/Dumper/DUMPDATA/raidSettings.json create mode 100644 Assets/Dumper/DumpLib.dll rename {Templates => Assets/Templates}/MappingTemplate.jsonc (100%) rename {Templates => Assets/Templates}/Settings.jsonc (100%) rename {de4dot => Assets/de4dot}/AssemblyData.dll (100%) rename {de4dot => Assets/de4dot}/de4dot.blocks.dll (100%) rename {de4dot => Assets/de4dot}/de4dot.code.dll (100%) rename {de4dot => Assets/de4dot}/de4dot.cui.dll (100%) rename {de4dot => Assets/de4dot}/de4dot.exe (100%) rename {de4dot => Assets/de4dot}/de4dot.mdecrypt.dll (100%) rename {de4dot => Assets/de4dot}/dnlib.dll (100%) create mode 100644 DumpLib/DumpLib.csproj create mode 100644 DumpLib/DumpyTool.cs create mode 100644 DumpLib/Helpers/ReflectionHelper.cs create mode 100644 DumpLib/Helpers/UtilsHelper.cs create mode 100644 DumpLib/Models/SptConfigClass.cs create mode 100644 ReCodeItCLI/Commands/Dumper.cs create mode 100644 RecodeItLib/Dumper/Dumpy.cs create mode 100644 RecodeItLib/Dumper/DumpyInstructionsHelper.cs create mode 100644 RecodeItLib/Dumper/DumpyTypeHelper.cs create mode 100644 RecodeItLib/Dumper/InstructionsExtensions.cs diff --git a/Assets/Dumper/DUMPDATA/botReqData.json b/Assets/Dumper/DUMPDATA/botReqData.json new file mode 100644 index 0000000..2c8cffb --- /dev/null +++ b/Assets/Dumper/DUMPDATA/botReqData.json @@ -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"} +] diff --git a/Assets/Dumper/DUMPDATA/config.json b/Assets/Dumper/DUMPDATA/config.json new file mode 100644 index 0000000..4598933 --- /dev/null +++ b/Assets/Dumper/DUMPDATA/config.json @@ -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" + } +} \ No newline at end of file diff --git a/Assets/Dumper/DUMPDATA/raidSettings.json b/Assets/Dumper/DUMPDATA/raidSettings.json new file mode 100644 index 0000000..f48c7eb --- /dev/null +++ b/Assets/Dumper/DUMPDATA/raidSettings.json @@ -0,0 +1,7 @@ +{ + "serverId": null, + "location": "Lighthouse", + "timeVariant": "CURR", + "mode": "PVE_OFFLINE", + "playerSide": "Pmc" +} \ No newline at end of file diff --git a/Assets/Dumper/DumpLib.dll b/Assets/Dumper/DumpLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..bd93e8dd0e2f5543217ba2a350981d654e375467 GIT binary patch literal 23040 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 literal 0 HcmV?d00001 diff --git a/Templates/MappingTemplate.jsonc b/Assets/Templates/MappingTemplate.jsonc similarity index 100% rename from Templates/MappingTemplate.jsonc rename to Assets/Templates/MappingTemplate.jsonc diff --git a/Templates/Settings.jsonc b/Assets/Templates/Settings.jsonc similarity index 100% rename from Templates/Settings.jsonc rename to Assets/Templates/Settings.jsonc diff --git a/de4dot/AssemblyData.dll b/Assets/de4dot/AssemblyData.dll similarity index 100% rename from de4dot/AssemblyData.dll rename to Assets/de4dot/AssemblyData.dll diff --git a/de4dot/de4dot.blocks.dll b/Assets/de4dot/de4dot.blocks.dll similarity index 100% rename from de4dot/de4dot.blocks.dll rename to Assets/de4dot/de4dot.blocks.dll diff --git a/de4dot/de4dot.code.dll b/Assets/de4dot/de4dot.code.dll similarity index 100% rename from de4dot/de4dot.code.dll rename to Assets/de4dot/de4dot.code.dll diff --git a/de4dot/de4dot.cui.dll b/Assets/de4dot/de4dot.cui.dll similarity index 100% rename from de4dot/de4dot.cui.dll rename to Assets/de4dot/de4dot.cui.dll diff --git a/de4dot/de4dot.exe b/Assets/de4dot/de4dot.exe similarity index 100% rename from de4dot/de4dot.exe rename to Assets/de4dot/de4dot.exe diff --git a/de4dot/de4dot.mdecrypt.dll b/Assets/de4dot/de4dot.mdecrypt.dll similarity index 100% rename from de4dot/de4dot.mdecrypt.dll rename to Assets/de4dot/de4dot.mdecrypt.dll diff --git a/de4dot/dnlib.dll b/Assets/de4dot/dnlib.dll similarity index 100% rename from de4dot/dnlib.dll rename to Assets/de4dot/dnlib.dll diff --git a/DumpLib/DumpLib.csproj b/DumpLib/DumpLib.csproj new file mode 100644 index 0000000..5370cef --- /dev/null +++ b/DumpLib/DumpLib.csproj @@ -0,0 +1,20 @@ + + + + net471 + DumpLib + 1.0.0 + latestmajor + enable + enable + ..\Assets\Dumper + + + + + + + + + + diff --git a/DumpLib/DumpyTool.cs b/DumpLib/DumpyTool.cs new file mode 100644 index 0000000..8f5ed20 --- /dev/null +++ b/DumpLib/DumpyTool.cs @@ -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 + { + /// + /// + /// + public static string DumpDataPath = (Directory.GetCurrentDirectory() + "\\DUMPDATA\\").Replace("\\\\", "\\"); + + public static SptConfigClass ConfigSettings = (SptConfigClass)GetSptConfig(); + + /// + /// always start from 1 as their iterations are 1 to 6 + /// + public static int Iteration = 1; + + /// + /// Method to create a "combined" Type that takes a GenericType + /// Example: ClientApplication + GInterface145 = ClientApplication(GInterface145) + /// + /// Object (Type) + /// Object (Type) + /// Type + 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; + } + } + + /// + /// + /// + /// + /// + 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; + } + } + + /// + /// + /// + /// + 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; + } + } + + /// + /// + /// + /// + 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; + } + } + + /// + /// + /// + /// + 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; + + /// + /// Method to run main menu Task, this will request data from BSG, map loot and bot data + /// + 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; + } + + /// + /// Method to log Requests and Responses + /// + /// object (Type) + /// object (Type) + 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; + } + } + } +} \ No newline at end of file diff --git a/DumpLib/Helpers/ReflectionHelper.cs b/DumpLib/Helpers/ReflectionHelper.cs new file mode 100644 index 0000000..1e80ee1 --- /dev/null +++ b/DumpLib/Helpers/ReflectionHelper.cs @@ -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("\\\\", "\\")); + + /// + /// Method to get Singleton<> type from Comfort.dll + /// + /// Type + public static Type GetSingletonType() + { + try + { + return _comfortAssembly.GetTypes().First(x => x.Name.StartsWith("Singleton")); + } + catch (Exception e) + { + UtilsHelper.LogError("GetSingletonType"); + UtilsHelper.LogError(e); + throw; + } + } + + /// + /// Method to get ClientApplication<> type from EFT's assembly + /// + /// Type + public static Type GetClientApplicationType() + { + try + { + return _eftAssembly.GetTypes().First(x => x.Name.StartsWith("ClientApplication")); + } + catch (Exception e) + { + UtilsHelper.LogError("GetClientApplicationType"); + UtilsHelper.LogError(e); + throw; + } + } + + /// + /// Method to get (as of 25/01/2024 - GInterface145) type from EFT's assembly + /// + /// Type + 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; + } + } + + /// + /// Method to get TarkovApplication type from EFT's assembly + /// + /// Type + public static Type GetTarkovApplicationType() + { + try + { + return _eftAssembly.GetTypes().First(x => x.Name == "TarkovApplication"); + } + catch (Exception e) + { + UtilsHelper.LogError("GetTarkovApplicationType"); + UtilsHelper.LogError(e); + throw; + } + } + + /// + /// Method to get (as of 25/01/2024 - GClass1464) type from EFT's assembly + /// + /// + 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; + } + } + + /// + /// Method to get FieldInfo of a field on the TarkovApplication Type for later use + /// + /// FieldInfo + 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; + } + } + + /// + /// Method to get the Instance of a Singleton(Type) passed in + /// + /// object (Type) + /// object (Type) + /// object + 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; + } + } + + /// + /// Method to get BackendSession object from the instance passed in + /// + /// object (Type) + /// object + public static object GetBackendSession(object instance) + { + try + { + return GetTarkovApplicationType().GetMethod("GetClientBackEndSession").Invoke(instance, null); + } + catch (Exception e) + { + UtilsHelper.LogError("GetBackendSession"); + UtilsHelper.LogError(e); + throw; + } + } + + /// + /// Method to get DeserializeObject from Newtonsoft assembly + /// + /// MethodInfo + 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; + } + } + + /// + /// Method to get Quit method from EFT (as of 20/05/2024 - GClass1955) + /// + /// MethodInfo + 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; + } + } + + /// + /// Method to get LocalRaidSettings Type from EFT + /// + /// object + 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; + } + } + } +} \ No newline at end of file diff --git a/DumpLib/Helpers/UtilsHelper.cs b/DumpLib/Helpers/UtilsHelper.cs new file mode 100644 index 0000000..b89d25f --- /dev/null +++ b/DumpLib/Helpers/UtilsHelper.cs @@ -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("\\\\", "\\"); + + /// + /// Log message to something + /// + /// object + 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(); + } + } + } + + /// + /// Log message to something + /// + /// object + public static void LogError(object message) + { + LogMessage(message, "Error"); + } + + /// + /// Log message to something + /// + /// object + public static void LogInfo(object message) + { + LogMessage(message, "Info"); + } + + /// + /// Log message to something + /// + /// object + public static void LogDebug(object message) + { + LogMessage(message, "Debug"); + } + } +} \ No newline at end of file diff --git a/DumpLib/Models/SptConfigClass.cs b/DumpLib/Models/SptConfigClass.cs new file mode 100644 index 0000000..26f5c23 --- /dev/null +++ b/DumpLib/Models/SptConfigClass.cs @@ -0,0 +1,57 @@ +namespace DumpLib.Models +{ + public class SptConfigClass + { + /// + /// Default: Test + /// + public string Name { get; set; } + + /// + /// Default: [ "Interchange", "factory4_day", "laboratory", "bigmap", "Lighthouse", "RezervBase", "Sandbox", "Shoreline", "TarkovStreets", "Woods" ] + /// + public string[] MapNames { get; set; } + + /// + /// Default: "yyyy-MM-dd_HH-mm-ss" + /// + public string DateTimeFormat { get; set; } + + public bool QuickDumpEnabled { get; set; } + + public SptReflections SptReflections { get; set; } + + public SptTimings SptTimings { get; set; } + } + + public class SptTimings + { + /// + /// Default: 10s * 1000ms = 10000ms + /// + public int SingleIterationDelayMs { get; set; } + + /// + /// Default: 5m * 60s * 1000ms = 300000ms + /// + public int AllIterationDelayMs { get; set; } + } + + public class SptReflections + { + /// + /// Default: "get_MainURLFull" as of 128476 client + /// + public string MainUrlPropName { get; set; } + + /// + /// Default: "Params" as of 128476 client + /// + public string ParamFieldName { get; set; } + + /// + /// Default: "responseText" as of 128476 client + /// + public string RequestFieldName { get; set; } + } +} \ No newline at end of file diff --git a/ReCodeItCLI/Commands/Dumper.cs b/ReCodeItCLI/Commands/Dumper.cs new file mode 100644 index 0000000..43c79c5 --- /dev/null +++ b/ReCodeItCLI/Commands/Dumper.cs @@ -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; + } +} \ No newline at end of file diff --git a/ReCodeItCLI/ReCodeIt.csproj b/ReCodeItCLI/ReCodeIt.csproj index 24eb2c2..ae4ce9c 100644 --- a/ReCodeItCLI/ReCodeIt.csproj +++ b/ReCodeItCLI/ReCodeIt.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/RecodeIt.sln b/RecodeIt.sln index e6edcaf..1f0f886 100644 --- a/RecodeIt.sln +++ b/RecodeIt.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReCodeItLib", "RecodeItLib\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReCodeIt", "ReCodeItCLI\ReCodeIt.csproj", "{E404EC0B-06D2-4964-8ABA-A634F259655C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DumpLib", "DumpLib\DumpLib.csproj", "{D0837899-F129-46DB-8BDB-7C9AFB72BD30}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution 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|x86.ActiveCfg = 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 GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RecodeItLib/Dumper/Dumpy.cs b/RecodeItLib/Dumper/Dumpy.cs new file mode 100644 index 0000000..b3b1b2a --- /dev/null +++ b/RecodeItLib/Dumper/Dumpy.cs @@ -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? _gameTypes { get; set; } + private List? _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 + } + + /// + /// Checks for null or multiple types + /// + /// ICollection + /// string + 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"); + } + } + + /// + /// Finds the method with backRequest and bResponse as params. + /// Checks the method instructions before modification has a count of 269, + /// if this is not the case, this needs to be checked. + /// This type passed in is the only type with this method. + /// + /// + /// + 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; + } + + /// + /// Finds the method called ValidateCertificate. + /// Checks that we found two of these methods, + /// if this is not the case, this needs to be checked. + /// This type passed in is the only type with this method. + /// + /// + /// + 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); + } + } + + /// + /// Finds the method called RunValidation and MoveNext. + /// Checks that we found two of these methods, + /// if this is not the case, this needs to be checked. + /// This type passed in is the only type with this method. + /// + /// + /// + 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); + // } + } + + /// + /// Finds the method called EnsureConsistency. + /// if this is not the case, this needs to be checked. + /// This type passed in is the only type with this method. + /// + /// + /// + 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); + // } + } + + /// + /// Finds the method called EnsureConsistencySingle. + /// if this is not the case, this needs to be checked. + /// This type passed in is the only type with this method. + /// + /// + /// + 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); + // } + } +} \ No newline at end of file diff --git a/RecodeItLib/Dumper/DumpyInstructionsHelper.cs b/RecodeItLib/Dumper/DumpyInstructionsHelper.cs new file mode 100644 index 0000000..dcf252f --- /dev/null +++ b/RecodeItLib/Dumper/DumpyInstructionsHelper.cs @@ -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 +// { +// /// +// /// Sets up local variables and returns a List of instructions to add. +// /// +// /// AssemblyDefinition +// /// MethodDefinition +// /// List +// public static List GetBackRequestInstructions(AssemblyDefinition assembly, MethodDefinition method) +// { +// return new List +// { +// 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) }))) +// }; +// } +// +// /// +// /// Returns a List of instructions to be added to the method. +// /// This is an Async method so there is two parts, this part and a RunValidation method. +// /// +// /// AssemblyDefinition +// /// MethodDefinition +// /// List +// public static List 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 +// { +// // 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), +// }; +// } +// +// /// +// /// Returns a List of instructions to be added to the method. +// /// This is an Async method so there is two parts, this part and a RunValidation method. +// /// +// /// AssemblyDefinition +// /// MethodDefinition +// /// List +// public static List 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 +// { +// // return Task.FromResult(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) +// }; +// } +// +// /// +// /// Returns a List of instructions to be added to the method. +// /// This is an Async method so there is two parts, this part and a MoveNext method. +// /// +// /// AssemblyDefinition +// /// MethodDefinition +// /// List +// public static List 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 +// { +// // 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]), +// +// // 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]), +// +// // 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]), +// +// // d__.<>t__builder.Startd__0>(ref 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 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 GetDumpyTaskInstructions(AssemblyDefinition oldAssembly, MethodDefinition method) +// { +// return new List +// { +// Instruction.Create(OpCodes.Call, oldAssembly.MainModule.ImportReference(typeof(DumpyTool).GetMethod("StartDumpyTask"))), +// Instruction.Create(OpCodes.Pop) +// }; +// } +// } \ No newline at end of file diff --git a/RecodeItLib/Dumper/DumpyTypeHelper.cs b/RecodeItLib/Dumper/DumpyTypeHelper.cs new file mode 100644 index 0000000..92fdb6f --- /dev/null +++ b/RecodeItLib/Dumper/DumpyTypeHelper.cs @@ -0,0 +1,54 @@ +// using System.Linq; +// using Mono.Cecil; +// +// namespace ReCodeItLib.Dumper; +// +// public static class DumpyTypeHelper +// { +// /// +// /// Gets the type that has a method called SendAndHandleRetries. +// /// This type is the only one with method. +// /// +// /// TypeDefinition +// /// boolean +// public static bool GetBackRequestType(TypeDefinition type) +// { +// return type.Methods.Any(m => m.Name == "SendAndHandleRetries"); +// } +// +// /// +// /// Gets the type that has a method called ValidateCertificate as the name. +// /// +// /// TypeDefinition +// /// boolean +// public static bool GetValidateCertificateType(TypeDefinition type) +// { +// return type.Methods.Any(m => m.Name == "ValidateCertificate"); +// } +// +// /// +// /// Gets the type that has a method called RunValidation as the name. +// /// +// /// TypeDefinition +// /// boolean +// public static bool GetRunValidationType(TypeDefinition type) +// { +// return type.Methods.Any(m => m.Name == "RunValidation"); +// } +// +// /// +// /// Gets the type that has ConsistencyController as the name. +// /// FilesChecker.dll is not obfuscated. +// /// +// /// TypeDefinition +// /// boolean +// public static bool GetEnsureConsistencyType(TypeDefinition type) +// { +// return type.Name == "ConsistencyController"; +// } +// +// public static bool GetMenuScreenType(TypeDefinition type) +// { +// return type.Name == "MenuScreen"; +// } +// } \ No newline at end of file diff --git a/RecodeItLib/Dumper/InstructionsExtensions.cs b/RecodeItLib/Dumper/InstructionsExtensions.cs new file mode 100644 index 0000000..0c47b58 --- /dev/null +++ b/RecodeItLib/Dumper/InstructionsExtensions.cs @@ -0,0 +1,49 @@ +using dnlib.DotNet.Emit; + +namespace ReCodeItLib.Dumper; + +public static class InstructionsExtensions +{ + public static void InsertBefore(this IList 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 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); + } +} \ No newline at end of file diff --git a/RecodeItLib/ReCodeItLib.csproj b/RecodeItLib/ReCodeItLib.csproj index 420ec58..2472aa9 100644 --- a/RecodeItLib/ReCodeItLib.csproj +++ b/RecodeItLib/ReCodeItLib.csproj @@ -18,4 +18,14 @@ + + + + + + + + Assets\DumpLib.dll + + diff --git a/RecodeItLib/Remapper/DeObfuscator.cs b/RecodeItLib/Remapper/DeObfuscator.cs index 3aebe88..0b5cee6 100644 --- a/RecodeItLib/Remapper/DeObfuscator.cs +++ b/RecodeItLib/Remapper/DeObfuscator.cs @@ -9,7 +9,7 @@ public static class Deobfuscator { 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;