From f3d095a0a7a630f372249bb993c98b4c10f8495a Mon Sep 17 00:00:00 2001 From: CWX <cwxdev@outlook.com> 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 @@ +<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> 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 + { + /// <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; + } + } + } +} \ 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("\\\\", "\\")); + + /// <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; + } + } + } +} \ 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("\\\\", "\\"); + + /// <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"); + } + } +} \ 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 + { + /// <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; } + } +} \ 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 @@ </PropertyGroup> <Target Name="PostBuild" AfterTargets="PostBuildEvent"> - <Exec Command="xcopy "$(SolutionDir)Templates" "$(TargetDir)Data" /E /I /Y" /> - <Exec Command="xcopy "$(SolutionDir)de4dot" "$(TargetDir)Data/de4dot" /E /I /Y" /> + <Exec Command="xcopy "$(SolutionDir)/Assets/Templates" "$(TargetDir)Data" /E /I /Y" /> + <Exec Command="xcopy "$(SolutionDir)/Assets/de4dot" "$(TargetDir)Data/de4dot" /E /I /Y" /> </Target> <ItemGroup> 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<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); + // } + } +} \ 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 +// { +// /// <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) +// }; +// } +// } \ 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 +// { +// /// <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"; +// } +// } \ 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<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); + } +} \ 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 @@ <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\DumpLib\DumpLib.csproj" /> + </ItemGroup> + + <ItemGroup> + <Reference Include="DumpLib"> + <HintPath>Assets\DumpLib.dll</HintPath> + </Reference> + </ItemGroup> </Project> 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;