From e51bc00dd2fa058cccb36ca13957feb3edf8d99b Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sat, 11 Feb 2023 19:52:29 +0100 Subject: [PATCH] feat(binding): add nt client with encryption key (session id) --- .../Extensions/ServiceCollectionExtensions.cs | 1 + .../Hooks/Implementations/HookManager.cs | 2 +- .../NosBrowserManager.cs | 60 ++++++++++++++-- .../Options/NtClientOptions.cs | 27 +++++++ .../Structs/NtClient.cs | 72 +++++++++++++++++++ 5 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 src/Core/NosSmooth.LocalBinding/Options/NtClientOptions.cs create mode 100644 src/Core/NosSmooth.LocalBinding/Structs/NtClient.cs diff --git a/src/Core/NosSmooth.LocalBinding/Extensions/ServiceCollectionExtensions.cs b/src/Core/NosSmooth.LocalBinding/Extensions/ServiceCollectionExtensions.cs index 9f6ea32..84e6b25 100644 --- a/src/Core/NosSmooth.LocalBinding/Extensions/ServiceCollectionExtensions.cs +++ b/src/Core/NosSmooth.LocalBinding/Extensions/ServiceCollectionExtensions.cs @@ -53,6 +53,7 @@ public static class ServiceCollectionExtensions .AddSingleton(p => p.GetRequiredService().PlayerManager) .AddSingleton(p => p.GetRequiredService().NetworkManager) .AddSingleton(p => p.GetRequiredService().UnitManager) + .AddSingleton(p => p.GetRequiredService().NtClient) .AddSingleton(p => p.GetRequiredService().PacketReceive) .AddSingleton(p => p.GetRequiredService().PacketSend) .AddSingleton(p => p.GetRequiredService().PlayerWalk) diff --git a/src/Core/NosSmooth.LocalBinding/Hooks/Implementations/HookManager.cs b/src/Core/NosSmooth.LocalBinding/Hooks/Implementations/HookManager.cs index fbdb2b5..8d94cc7 100644 --- a/src/Core/NosSmooth.LocalBinding/Hooks/Implementations/HookManager.cs +++ b/src/Core/NosSmooth.LocalBinding/Hooks/Implementations/HookManager.cs @@ -21,7 +21,7 @@ internal class HookManager : IHookManager /// Initializes a new instance of the class. /// /// The hook manager options. - public HookManager(IOptions options) + public HookManager(IOptionsSnapshot options) { _options = options.Value; _hooks = new Dictionary(); diff --git a/src/Core/NosSmooth.LocalBinding/NosBrowserManager.cs b/src/Core/NosSmooth.LocalBinding/NosBrowserManager.cs index 51d59e0..7d9f4e6 100644 --- a/src/Core/NosSmooth.LocalBinding/NosBrowserManager.cs +++ b/src/Core/NosSmooth.LocalBinding/NosBrowserManager.cs @@ -58,11 +58,13 @@ public class NosBrowserManager private readonly PetManagerOptions _petManagerOptions; private readonly NetworkManagerOptions _networkManagerOptions; private readonly UnitManagerOptions _unitManagerOptions; + private readonly NtClientOptions _ntClientOptions; private PlayerManager? _playerManager; private SceneManager? _sceneManager; private PetManagerList? _petManagerList; private NetworkManager? _networkManager; private UnitManager? _unitManager; + private NtClient? _ntClient; /// /// Initializes a new instance of the class. @@ -72,13 +74,15 @@ public class NosBrowserManager /// The pet manager options. /// The network manager options. /// The unit manager options. + /// The nt client options. public NosBrowserManager ( - IOptions playerManagerOptions, - IOptions sceneManagerOptions, - IOptions petManagerOptions, - IOptions networkManagerOptions, - IOptions unitManagerOptions + IOptionsSnapshot playerManagerOptions, + IOptionsSnapshot sceneManagerOptions, + IOptionsSnapshot petManagerOptions, + IOptionsSnapshot networkManagerOptions, + IOptionsSnapshot unitManagerOptions, + IOptionsSnapshot ntClientOptions ) : this ( @@ -87,7 +91,8 @@ public class NosBrowserManager sceneManagerOptions.Value, petManagerOptions.Value, networkManagerOptions.Value, - unitManagerOptions.Value + unitManagerOptions.Value, + ntClientOptions.Value ) { } @@ -101,6 +106,7 @@ public class NosBrowserManager /// The pet manager options. /// The network manager options. /// The unit manager options. + /// The nt client options. public NosBrowserManager ( Process process, @@ -108,7 +114,8 @@ public class NosBrowserManager SceneManagerOptions sceneManagerOptions, PetManagerOptions petManagerOptions, NetworkManagerOptions networkManagerOptions, - UnitManagerOptions unitManagerOptions + UnitManagerOptions unitManagerOptions, + NtClientOptions ntClientOptions ) { _playerManagerOptions = playerManagerOptions; @@ -116,6 +123,7 @@ public class NosBrowserManager _petManagerOptions = petManagerOptions; _networkManagerOptions = networkManagerOptions; _unitManagerOptions = unitManagerOptions; + _ntClientOptions = ntClientOptions; Process = process; Memory = Process.Id == Process.GetCurrentProcess().Id ? new Memory() : new ExternalMemory(process); Scanner = new Scanner(process, process.MainModule); @@ -196,6 +204,26 @@ public class NosBrowserManager } } + /// + /// Gets the nt client. + /// + /// Thrown if the browser is not initialized or there was an error with initialization of nt client. + public NtClient NtClient + { + get + { + if (_ntClient is null) + { + throw new InvalidOperationException + ( + "Could not get nt client. The browser manager is not initialized. Did you forget to call NosBrowserManager.Initialize?" + ); + } + + return _ntClient; + } + } + /// /// Gets the player manager. /// @@ -361,6 +389,24 @@ public class NosBrowserManager _petManagerList = petManagerResult.Entity; } + if (_ntClient is null) + { + var ntClientResult = NtClient.Create(this, _ntClientOptions); + if (!ntClientResult.IsSuccess) + { + errorResults.Add + ( + Result.FromError + ( + new CouldNotInitializeModuleError(typeof(NtClient), ntClientResult.Error), + ntClientResult + ) + ); + } + + _ntClient = ntClientResult.Entity; + } + return errorResults.Count switch { 0 => Result.FromSuccess(), diff --git a/src/Core/NosSmooth.LocalBinding/Options/NtClientOptions.cs b/src/Core/NosSmooth.LocalBinding/Options/NtClientOptions.cs new file mode 100644 index 0000000..c53e35e --- /dev/null +++ b/src/Core/NosSmooth.LocalBinding/Options/NtClientOptions.cs @@ -0,0 +1,27 @@ +// +// NtClientOptions.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.LocalBinding.Structs; + +namespace NosSmooth.LocalBinding.Options; + +/// +/// Options for . +/// +public class NtClientOptions +{ + /// + /// Gets or sets the pattern to find static pet manager list address at. + /// + public string NtClientPattern { get; set; } + = "FF ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF 00 00"; + + /// + /// Gets or sets the offsets to find the scene manager at from the static address. + /// + public int[] NtClientOffsets { get; set; } + = { 1 }; +} \ No newline at end of file diff --git a/src/Core/NosSmooth.LocalBinding/Structs/NtClient.cs b/src/Core/NosSmooth.LocalBinding/Structs/NtClient.cs new file mode 100644 index 0000000..79f13e7 --- /dev/null +++ b/src/Core/NosSmooth.LocalBinding/Structs/NtClient.cs @@ -0,0 +1,72 @@ +// +// NtClient.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.LocalBinding.Errors; +using NosSmooth.LocalBinding.Extensions; +using NosSmooth.LocalBinding.Options; +using Reloaded.Memory.Sources; +using Remora.Results; + +namespace NosSmooth.LocalBinding.Structs; + +/// +/// A NosTale client base object. +/// +public class NtClient : NostaleObject +{ + /// + /// Create instance. + /// + /// The NosTale process browser. + /// The options. + /// The player manager or an error. + public static Result Create(NosBrowserManager nosBrowserManager, NtClientOptions options) + { + var networkObjectAddress = nosBrowserManager.Scanner.FindPattern(options.NtClientPattern); + if (!networkObjectAddress.Found) + { + return new BindingNotFoundError(options.NtClientPattern, "NtClient"); + } + + if (nosBrowserManager.Process.MainModule is null) + { + return new NotFoundError("Cannot find the main module of the target process."); + } + + var staticAddress = (nuint)(nosBrowserManager.Process.MainModule.BaseAddress + networkObjectAddress.Offset); + return new NtClient(nosBrowserManager.Memory, staticAddress, options.NtClientOffsets); + } + + private readonly IMemory _memory; + private readonly int _staticNtClientAddress; + private readonly int[] _ntClientOffsets; + + private NtClient(IMemory memory, nuint staticNtClientAddress, int[] ntClientOffsets) + : base(memory, nuint.Zero) + { + _memory = memory; + _staticNtClientAddress = (int)staticNtClientAddress; + _ntClientOffsets = ntClientOffsets; + } + + /// + /// Gets the address to the player manager. + /// + public override nuint Address => _memory.FollowStaticAddressOffsets + (_staticNtClientAddress, _ntClientOffsets); + + /// + /// Gets the encryption key used for world encryption. + /// + public int EncryptionKey + { + get + { + _memory.SafeRead(Address + 0x48, out int encryptionKey); + return encryptionKey; + } + } +} \ No newline at end of file -- 2.48.1