From c0240c5e467e919d940ba09e0e3821eb36b531b1 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Mon, 2 Jan 2023 23:21:12 +0100 Subject: [PATCH] feat(bindings): support stack arguments with asm detour --- .../NosBindingManager.cs | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Core/NosSmooth.LocalBinding/NosBindingManager.cs b/src/Core/NosSmooth.LocalBinding/NosBindingManager.cs index c7c4a3d405ecf290cef02aeb5d32967f363d9480..024fb34afaa6234439cae1157033ec554549eb33 100644 --- a/src/Core/NosSmooth.LocalBinding/NosBindingManager.cs +++ b/src/Core/NosSmooth.LocalBinding/NosBindingManager.cs @@ -5,6 +5,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; +using System.Reflection; using Microsoft.Extensions.Options; using NosSmooth.LocalBinding.Errors; using NosSmooth.LocalBinding.Hooks; @@ -14,6 +15,8 @@ using NosSmooth.LocalBinding.Options; using Reloaded.Hooks; using Reloaded.Hooks.Definitions; using Reloaded.Hooks.Definitions.Helpers; +using Reloaded.Hooks.Definitions.Internal; +using Reloaded.Hooks.Definitions.X86; using Reloaded.Hooks.Tools; using Reloaded.Hooks.X86; using Reloaded.Memory.Sigscan; @@ -168,6 +171,7 @@ public class NosBindingManager : IDisposable HookOptions options, bool cancellable = true ) + where TFunction : Delegate { var walkFunctionAddress = Scanner.FindPattern(options.MemoryPattern); if (!walkFunctionAddress.Found) @@ -183,6 +187,15 @@ public class NosBindingManager : IDisposable var reverseWrapper = Hooks.CreateReverseWrapper(callbackFunction); var callDetour = Utilities.GetAbsoluteCallMnemonics (reverseWrapper.WrapperPointer.ToUnsigned(), IntPtr.Size == 8); + if (!Misc.TryGetAttribute(out var attribute)) + { + return new ArgumentInvalidError(nameof(TFunction), "The function does not have a function attribute."); + } + var stackArgumentsCount = Utilities.GetNumberofParameters() - attribute.SourceRegisters.Length; + if (stackArgumentsCount < 0) + { + stackArgumentsCount = 0; + } var asmInstructions = new List(); @@ -191,11 +204,22 @@ public class NosBindingManager : IDisposable "use32", "pushad", "pushfd", - - // call managed function - callDetour }); + for (int i = 0; i < stackArgumentsCount; i++) + { // TODO make it into asm loop + asmInstructions.AddRange(new[] + { + $"add esp, {36 + (4 * stackArgumentsCount)}", + "pop ebx", + "sub esp, 0x04", + $"sub esp, {36 + (4 * stackArgumentsCount)}", + "push ebx", + }); + } + + asmInstructions.Add(callDetour); + if (cancellable) { asmInstructions.AddRange @@ -211,7 +235,8 @@ public class NosBindingManager : IDisposable // returned 0, going to return early "popfd", "popad", - "ret", // return early + + $"ret {4 * stackArgumentsCount}", // return early } ); }