From 8284e52adca052bf0b918c191a8412b3ddfeca82 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Wed, 9 Oct 2024 11:27:44 +0200 Subject: [PATCH 01/12] feat: `CreateValveFunctionByOffset` --- .../DynamicFunctions/BaseMemoryFunction.cs | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs index 05cc01e12..0e8b6f06f 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs @@ -7,7 +7,9 @@ namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; public abstract class BaseMemoryFunction : NativeObject { - private static Dictionary _createdFunctions = new(); + private static Dictionary _createdFunctions = new(); + + private static Dictionary> _createdOffsetFunctions = new(); private static IntPtr CreateValveFunctionBySignature(string signature, DataType returnType, DataType[] argumentTypes) @@ -45,6 +47,30 @@ private static IntPtr CreateValveFunctionBySignature(string signature, string bi } return function; + } + + private static IntPtr CreateValveFunctionByOffset(IntPtr objectPtr, int offset, DataType returnType, + DataType[] argumentTypes) + { + if (!_createdOffsetFunctions.TryGetValue(objectPtr, out var createdFunctions)) + { + createdFunctions = new Dictionary(); + _createdOffsetFunctions[objectPtr] = createdFunctions; + } + + if (!createdFunctions.TryGetValue(offset, out var function)) + { + try + { + function = NativeAPI.CreateVirtualFunction(objectPtr, offset, + argumentTypes.Length, (int)returnType, argumentTypes.Cast().ToArray()); + createdFunctions[offset] = function; + } catch (Exception) + { + } + } + + return function; } public BaseMemoryFunction(string signature, DataType returnType, DataType[] parameters) : base( @@ -55,6 +81,14 @@ public BaseMemoryFunction(string signature, DataType returnType, DataType[] para public BaseMemoryFunction(string signature, string binarypath, DataType returnType, DataType[] parameters) : base( CreateValveFunctionBySignature(signature, binarypath, returnType, parameters)) { + } + + /// + /// WARNING: this is only supposed to be used with and + /// + internal BaseMemoryFunction(IntPtr objectPtr, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionByOffset(objectPtr, offset, returnType, parameters)) + { } public void Hook(Func handler, HookMode mode) @@ -76,4 +110,4 @@ protected void InvokeInternalVoid(params object[] args) { NativeAPI.ExecuteVirtualFunction(Handle, args); } -} \ No newline at end of file +} From 679ce6c6e3b51ad37ca9a775ae7e88d3cf2f6803 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Wed, 9 Oct 2024 11:28:06 +0200 Subject: [PATCH 02/12] feat: overloaded constructor --- .../DynamicFunctions/MemoryFunctionVoid.cs | 126 ++++++++++++++++-- .../MemoryFunctionWithReturn.cs | 106 ++++++++++++++- 2 files changed, 221 insertions(+), 11 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs index 482254d6e..7e00c69ee 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs @@ -1,10 +1,24 @@ -using System; +/* + * This file is part of CounterStrikeSharp. + * CounterStrikeSharp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CounterStrikeSharp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CounterStrikeSharp. If not, see . * + */ namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; #pragma warning disable CS8601 // Possible null reference assignment. -#pragma warning disable CS8604 // Possible null reference argument. - +#pragma warning disable CS8604 // Possible null reference argument. + public class MemoryFunctionVoid : BaseMemoryFunction { public MemoryFunctionVoid(string signature) : base(signature, DataType.DATA_TYPE_VOID, Array.Empty()) @@ -13,14 +27,18 @@ public MemoryFunctionVoid(string signature) : base(signature, DataType.DATA_TYPE public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID, Array.Empty()) { + } + + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, Array.Empty()) + { } public void Invoke() { InvokeInternalVoid(); } -} - +} + public class MemoryFunctionVoid : BaseMemoryFunction { public MemoryFunctionVoid(string signature) : base(signature, DataType.DATA_TYPE_VOID, @@ -33,6 +51,11 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { + } + public void Invoke(T1 arg1) { InvokeInternalVoid(arg1); @@ -51,6 +74,11 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + public void Invoke(T1 arg1, T2 arg2) { InvokeInternalVoid(arg1, arg2); @@ -69,6 +97,11 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3) { InvokeInternalVoid(arg1, arg2, arg3); @@ -95,12 +128,21 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { InvokeInternalVoid(arg1, arg2, arg3, arg4); } -} - +} + public class MemoryFunctionVoid : BaseMemoryFunction { public MemoryFunctionVoid(string signature) : base(signature, DataType.DATA_TYPE_VOID, @@ -123,6 +165,16 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5); @@ -151,6 +203,16 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6); @@ -181,6 +243,17 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7); @@ -211,12 +284,23 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } } - + public class MemoryFunctionVoid : BaseMemoryFunction { public MemoryFunctionVoid(string signature) : base(signature, DataType.DATA_TYPE_VOID, @@ -243,6 +327,18 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); @@ -275,6 +371,18 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { + } + public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); @@ -282,4 +390,4 @@ public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7 } #pragma warning restore CS8601 // Possible null reference assignment. -#pragma warning restore CS8604 // Possible null reference argument. \ No newline at end of file +#pragma warning restore CS8604 // Possible null reference argument. diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs index 8730debe7..054efd139 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs @@ -1,4 +1,18 @@ -using System; +/* + * This file is part of CounterStrikeSharp. + * CounterStrikeSharp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CounterStrikeSharp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CounterStrikeSharp. If not, see . * + */ namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; @@ -15,6 +29,11 @@ public MemoryFunctionWithReturn(string signature) : base(signature, typeof(TResu public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(), Array.Empty()) { + } + + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + Array.Empty()) + { } public TResult Invoke() @@ -35,6 +54,11 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { + } + public TResult Invoke(T1 arg1) { return InvokeInternal(arg1); @@ -53,6 +77,11 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + public TResult Invoke(T1 arg1, T2 arg2) { return InvokeInternal(arg1, arg2); @@ -71,6 +100,11 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3) { return InvokeInternal(arg1, arg2, arg3); @@ -97,6 +131,15 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { return InvokeInternal(arg1, arg2, arg3, arg4); @@ -123,6 +166,15 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { return InvokeInternal(arg1, arg2, arg3, arg4, arg5); @@ -149,6 +201,15 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { return InvokeInternal(arg1, arg2, arg3, arg4, arg5, arg6); @@ -177,6 +238,16 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { return InvokeInternal(arg1, arg2, arg3, arg4, arg5, arg6, arg7); @@ -205,6 +276,16 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { return InvokeInternal(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); @@ -233,6 +314,16 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { return InvokeInternal(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); @@ -263,6 +354,17 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { + } + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { return InvokeInternal(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); @@ -270,4 +372,4 @@ public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 a } #pragma warning restore CS8601 // Possible null reference assignment. -#pragma warning restore CS8604 // Possible null reference argument. \ No newline at end of file +#pragma warning restore CS8604 // Possible null reference argument. From 73fe4ff912d28ee8fa653c19be03c541f8d19721 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Wed, 9 Oct 2024 11:28:28 +0200 Subject: [PATCH 03/12] feat: now inherits from `MemoryFunction*` --- .../Modules/Memory/VirtualFunctionVoid.cs | 179 ++++++----------- .../Memory/VirtualFunctionWithReturn.cs | 180 ++++++------------ 2 files changed, 118 insertions(+), 241 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs index 08f9630fd..5d282c8a3 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs @@ -14,274 +14,215 @@ * along with CounterStrikeSharp. If not, see . * */ +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; + namespace CounterStrikeSharp.API.Modules.Memory; -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; + public VirtualFunctionVoid(string signature) : base(signature) + { + } - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public void Invoke() + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3, arg4); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } } -public partial class VirtualFunctionVoid +public partial class VirtualFunctionVoid : MemoryFunctionVoid { - private Action Function; - - public VirtualFunctionVoid(string signature) + public VirtualFunctionVoid(string signature) : base(signature) { - this.Function = VirtualFunction.CreateVoid(signature); } - public VirtualFunctionVoid(string signature, string binarypath) + public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.CreateVoid(signature, binarypath); } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.CreateVoid(objectPtr, offset); } - public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { - this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } -} \ No newline at end of file +} diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs index 489bb40b0..0ddd4c1b1 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs @@ -14,279 +14,215 @@ * along with CounterStrikeSharp. If not, see . * */ +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; + namespace CounterStrikeSharp.API.Modules.Memory; -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke() + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3, arg4); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } } -public partial class VirtualFunctionWithReturn +public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { - private Func Function; - - public VirtualFunctionWithReturn(string signature) + public VirtualFunctionWithReturn(string signature) : base(signature) { - this.Function = VirtualFunction.Create(signature); } - public VirtualFunctionWithReturn(string signature, string binarypath) + public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) { - this.Function = VirtualFunction.Create(signature, binarypath); } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { - this.Function = VirtualFunction.Create(objectPtr, offset); } - public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { - return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } -} \ No newline at end of file +} From d9dcb7e1a2a535d35c130dc4bdb190e42e96e7c7 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Sat, 10 May 2025 11:06:08 +0200 Subject: [PATCH 04/12] fix: disambiguate virtual functions by offset --- .../DynamicFunctions/BaseMemoryFunction.cs | 23 +++----- .../DynamicFunctions/MemoryFunctionVoid.cs | 22 +++---- .../MemoryFunctionWithReturn.cs | 22 +++---- .../Modules/Memory/VirtualFunctionVoid.cs | 59 +++++++------------ .../Memory/VirtualFunctionWithReturn.cs | 59 +++++++------------ 5 files changed, 70 insertions(+), 115 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs index 0e8b6f06f..a743530bd 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using CounterStrikeSharp.API.Core; +using Microsoft.Extensions.Logging; namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; @@ -9,7 +6,7 @@ public abstract class BaseMemoryFunction : NativeObject { private static Dictionary _createdFunctions = new(); - private static Dictionary> _createdOffsetFunctions = new(); + private static Dictionary _createdOffsetFunctions = new(); private static IntPtr CreateValveFunctionBySignature(string signature, DataType returnType, DataType[] argumentTypes) @@ -49,22 +46,18 @@ private static IntPtr CreateValveFunctionBySignature(string signature, string bi return function; } - private static IntPtr CreateValveFunctionByOffset(IntPtr objectPtr, int offset, DataType returnType, + private static IntPtr CreateValveFunctionByOffset(IntPtr objectPtr, Type type, int offset, DataType returnType, DataType[] argumentTypes) { - if (!_createdOffsetFunctions.TryGetValue(objectPtr, out var createdFunctions)) - { - createdFunctions = new Dictionary(); - _createdOffsetFunctions[objectPtr] = createdFunctions; - } + string constructKey = $"{type.Name}_{offset}"; - if (!createdFunctions.TryGetValue(offset, out var function)) + if (!_createdOffsetFunctions.TryGetValue(constructKey, out var function)) { try { function = NativeAPI.CreateVirtualFunction(objectPtr, offset, argumentTypes.Length, (int)returnType, argumentTypes.Cast().ToArray()); - createdFunctions[offset] = function; + _createdOffsetFunctions[constructKey] = function; } catch (Exception) { } @@ -86,8 +79,8 @@ public BaseMemoryFunction(string signature, string binarypath, DataType returnTy /// /// WARNING: this is only supposed to be used with and /// - internal BaseMemoryFunction(IntPtr objectPtr, int offset, DataType returnType, DataType[] parameters) : base( - CreateValveFunctionByOffset(objectPtr, offset, returnType, parameters)) + internal BaseMemoryFunction(IntPtr objectPtr, Type type, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionByOffset(objectPtr, type, offset, returnType, parameters)) { } diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs index 7e00c69ee..97090a1d1 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs @@ -29,7 +29,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, Array.Empty()) + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, Array.Empty()) { } @@ -51,7 +51,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType() }) { } @@ -74,7 +74,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) { } @@ -97,7 +97,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) { } @@ -128,7 +128,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -165,7 +165,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -203,7 +203,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -243,7 +243,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -284,7 +284,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -327,7 +327,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -371,7 +371,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs index 054efd139..10a1a6566 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs @@ -31,7 +31,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), Array.Empty()) { } @@ -54,7 +54,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType() }) { } @@ -77,7 +77,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) { } @@ -100,7 +100,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) { } @@ -131,7 +131,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -166,7 +166,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -201,7 +201,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -238,7 +238,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -276,7 +276,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -314,7 +314,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -354,7 +354,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs index 5d282c8a3..5becec0e8 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs @@ -18,25 +18,6 @@ namespace CounterStrikeSharp.API.Modules.Memory; -public partial class VirtualFunctionVoid : MemoryFunctionVoid -{ - public VirtualFunctionVoid(string signature) : base(signature) - { - } - - public VirtualFunctionVoid(string signature, string binarypath) : base(signature, binarypath) - { - } - - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) - { - } - - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) - { - } -} - public partial class VirtualFunctionVoid : MemoryFunctionVoid { public VirtualFunctionVoid(string signature) : base(signature) @@ -47,11 +28,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -66,11 +47,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -85,11 +66,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -104,11 +85,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -123,11 +104,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -142,11 +123,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -161,11 +142,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -180,11 +161,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -199,11 +180,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -218,11 +199,11 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs index 0ddd4c1b1..cf60729cd 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs @@ -18,25 +18,6 @@ namespace CounterStrikeSharp.API.Modules.Memory; -public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn -{ - public VirtualFunctionWithReturn(string signature) : base(signature) - { - } - - public VirtualFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath) - { - } - - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) - { - } - - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) - { - } -} - public partial class VirtualFunctionWithReturn : MemoryFunctionWithReturn { public VirtualFunctionWithReturn(string signature) : base(signature) @@ -47,11 +28,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -66,11 +47,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -85,11 +66,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -104,11 +85,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -123,11 +104,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -142,11 +123,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -161,11 +142,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -180,11 +161,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -199,11 +180,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } @@ -218,11 +199,11 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) { } } From a789b0f77e0727bbcb3763ad0eb58b5933368b97 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Sat, 10 May 2025 12:45:43 +0200 Subject: [PATCH 05/12] chore: removed unused import --- .../Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs index a743530bd..0f83da6a0 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs @@ -1,6 +1,4 @@ -using Microsoft.Extensions.Logging; - -namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +namespace CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; public abstract class BaseMemoryFunction : NativeObject { From 4624aedd8ee6934cd07df9f6dd2a0670d70cbd81 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 12 May 2025 13:04:22 +0200 Subject: [PATCH 06/12] feat: CModule::FindVirtualTable --- src/core/memory_module.cpp | 207 +++++++++++++++++++++++++++++++++++-- src/core/memory_module.h | 8 +- 2 files changed, 204 insertions(+), 11 deletions(-) diff --git a/src/core/memory_module.cpp b/src/core/memory_module.cpp index 089010648..b361996d6 100644 --- a/src/core/memory_module.cpp +++ b/src/core/memory_module.cpp @@ -152,20 +152,23 @@ CModule::CModule(std::string_view path, std::uint64_t base) auto section = IMAGE_FIRST_SECTION(nt_header); - for (auto i = 0; i < nt_header->FileHeader.NumberOfSections; i++, section++) + for (auto i = 0; i < nt_header->FileHeader.NumberOfSections; i++) { - const auto is_executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; - const auto is_readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; + const auto is_executable = (section[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; + const auto is_readable = (section[i].Characteristics & IMAGE_SCN_MEM_READ) != 0; - if (is_executable && is_readable) - { - const auto start = this->m_baseAddress + section->VirtualAddress; - const auto size = (std::min)(section->SizeOfRawData, section->Misc.VirtualSize); - const auto data = reinterpret_cast(start); + const auto start = this->m_baseAddress + section[i].VirtualAddress; + const auto size = (std::min)(section[i].SizeOfRawData, section[i].Misc.VirtualSize); + + auto& segment = m_vecSegments.emplace_back(); - auto& segment = m_vecSegments.emplace_back(); + segment.name = (char*)section[i].Name; + segment.address = start; + segment.size = size; - segment.address = start; + if (is_executable && is_readable) + { + // we only reserve bytes for executable and readable sections segment.bytes.reserve(size); if (should_read_from_disk) @@ -180,6 +183,7 @@ CModule::CModule(std::string_view path, std::uint64_t base) return; } + const auto data = reinterpret_cast(start); segment.bytes.assign(&data[0], &data[size]); } } @@ -239,6 +243,7 @@ CModule::CModule(std::string_view path, dl_phdr_info* info) auto& segment = m_vecSegments.emplace_back(); + segment.name = (char*)section[i].Name; segment.address = address; segment.bytes.reserve(size); @@ -562,4 +567,186 @@ void* CModule::FindSymbol(const std::string& name) CSSHARP_CORE_ERROR("Cannot find symbol {}", name); return nullptr; } + +#ifdef _WIN32 +void* CModule::FindVirtualTable(const std::string& name) +{ + if (_vtables.find(name) != _vtables.end()) + { + return reinterpret_cast(_vtables[name]); + } + + auto runTimeData = GetSegment(".data"); + auto readOnlyData = GetSegment(".rdata"); + + if (!runTimeData || !readOnlyData) + { + CSSHARP_CORE_ERROR("Failed to find .data or .rdata segment"); + return nullptr; + } + + std::string decoratedTableName = ".?AV" + name + "@@"; + size_t tableNameLength = decoratedTableName.size() + 1; + + bool foundTypeDescriptor = false; + void* typeDescriptor = nullptr; + + for (uintptr_t i = 0; i < runTimeData->size - tableNameLength; ++i) + { + if (memcmp((void*)((uintptr_t)runTimeData->address + i), decoratedTableName.c_str(), tableNameLength) == 0) + { + typeDescriptor = (void*)((uintptr_t)runTimeData->address + i); + foundTypeDescriptor = true; + break; + } + } + + if (!foundTypeDescriptor) + { + CSSHARP_CORE_ERROR("Failed to find type descriptor for {}", name); + return nullptr; + } + + typeDescriptor = (void*)((uintptr_t)typeDescriptor - 0x10); + const uint32_t rttiTDRva = (uintptr_t)typeDescriptor - (uintptr_t)m_base; + + bool foundCompleteObjectLocator = false; + void* completeObjectLocator = nullptr; + + for (uintptr_t i = 0; i < readOnlyData->size - sizeof(uint32_t); ++i) + { + if (*(uint32_t*)((uintptr_t)readOnlyData->address + i) == rttiTDRva) + { + uintptr_t completeObjectLocatorHeader = (uintptr_t)readOnlyData->address + i - 0xC; + + if (*(int32_t*)completeObjectLocatorHeader != 1) + continue; + + if (*(int32_t*)(completeObjectLocatorHeader - 0x8) != 0) + continue; + + completeObjectLocator = (void*)completeObjectLocatorHeader; + foundCompleteObjectLocator = true; + break; + } + } + + if (!foundCompleteObjectLocator) + { + CSSHARP_CORE_ERROR("Failed to find complete object locator for {}", name); + return nullptr; + } + + bool foundVTable = false; + void* vtable = nullptr; + + for (uintptr_t i = 0; i < readOnlyData->size - sizeof(void*); ++i) + { + if (*(void**)((uintptr_t)readOnlyData->address + i) == completeObjectLocator) + { + vtable = (void*)((uintptr_t)readOnlyData->address + i + 0x8); + foundVTable = true; + break; + } + } + + if (!foundVTable) + { + return nullptr; + } + + _vtables.insert({ name, reinterpret_cast(vtable) }); + return vtable; +} +#else +void* CModule::FindVirtualTable(const std::string& name) +{ + if (_vtables.find(name) != _vtables.end()) + { + return reinterpret_cast(_vtables[name]); + } + + auto readOnlyData = GetSegment(".rodata"); + auto readOnlyRelocations = GetSegment(".data.rel.ro"); + + if (!readOnlyData || !readOnlyRelocations) + { + CSSHARP_CORE_ERROR("Failed to find .rodata or .data.rel.ro segment"); + return nullptr; + } + + std::string decoratedTableName = std::to_string(name.length()) + name; + + void* classNameString = nullptr; + + for (uintptr_t i = 0; i < readOnlyData->size - decoratedTableName.size(); ++i) + { + if (memcmp((void*)((uintptr_t)readOnlyData->address + i), decoratedTableName.c_str(), decoratedTableName.size()) == 0) + { + classNameString = (void*)((uintptr_t)readOnlyData->address + i); + break; + } + } + + if (!classNameString) + { + CSSHARP_CORE_ERROR("Failed to find type descriptor for {}", name); + return nullptr; + } + + void* typeName = nullptr; + + for (uintptr_t i = 0; i < readOnlyRelocations->size - sizeof(void*); ++i) + { + if (*(void**)((uintptr_t)readOnlyRelocations->address + i) == classNameString) + { + typeName = (void*)((uintptr_t)readOnlyRelocations->address + i); + break; + } + } + + if (!typeName) + { + CSSHARP_CORE_ERROR("Failed to find type name for {}", name); + return nullptr; + } + + void* typeInfo = (void*)((uintptr_t)typeName - 0x8); + + for (const auto& sectionName : { std::string_view(".data.rel.ro"), std::string_view(".data.rel.ro.local") }) + { + auto section = GetSegment(sectionName); + + if (!section) + continue; + + for (uintptr_t i = 0; i < section->size - sizeof(void*); ++i) + { + if (*(void**)((uintptr_t)section->address + i) == typeInfo) + { + void* vtable = (void*)((uintptr_t)section->address + i + 0x8); + + if (*(int64_t*)((uintptr_t)vtable - 0x8) == 0) + { + _vtables.insert({ name, reinterpret_cast(vtable) }); + return vtable; + } + } + } + } + + return nullptr; +} +#endif + +Segments* CModule::GetSegment(std::string_view name) +{ + for (auto&& segment : m_vecSegments) + { + if (segment.name == name) + return &segment; + } + + return nullptr; +} } // namespace counterstrikesharp::modules diff --git a/src/core/memory_module.h b/src/core/memory_module.h index 7f339a1e0..899192294 100644 --- a/src/core/memory_module.h +++ b/src/core/memory_module.h @@ -35,7 +35,6 @@ #undef snprintf namespace counterstrikesharp::modules { - struct Segments { Segments() = default; @@ -45,8 +44,10 @@ struct Segments Segments& operator=(const Segments&) = default; Segments& operator=(Segments&&) = default; + std::string name{}; std::uintptr_t address{}; std::vector bytes{}; + size_t size{}; }; class CModule @@ -64,6 +65,10 @@ class CModule void* FindSymbol(const std::string& name); + void* FindVirtualTable(const std::string& name); + + Segments* GetSegment(std::string_view name); + [[nodiscard]] bool IsInitialized() const { return m_bInitialized; } std::string m_pszModule{}; @@ -77,6 +82,7 @@ class CModule std::uintptr_t m_baseAddress{}; std::unordered_map _symbols{}; std::unordered_map _interfaces{}; + std::unordered_map _vtables{}; using fnCreateInterface = void*(*)(const char*); fnCreateInterface m_fnCreateInterface {}; From 415daced17761ccf9a38fb3902a2aa5152b10ad3 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 12 May 2025 13:07:45 +0200 Subject: [PATCH 07/12] feat: implemented new natives --- managed/CounterStrikeSharp.API/Core/API.cs | 49 ++++++++ src/scripting/natives/natives_memory.cpp | 134 ++++++++++++++++++++- src/scripting/natives/natives_memory.yaml | 5 +- 3 files changed, 185 insertions(+), 3 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs index af67fa895..920b921c5 100644 --- a/managed/CounterStrikeSharp.API/Core/API.cs +++ b/managed/CounterStrikeSharp.API/Core/API.cs @@ -1103,6 +1103,43 @@ public static IntPtr CreateVirtualFunctionBySignature(IntPtr pointer, string bin } } + public static IntPtr CreateVirtualFunctionBySymbol(string binaryname, string symbolname, int vtableoffset, int numarguments, int returntype, object[] arguments){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(binaryname); + ScriptContext.GlobalScriptContext.Push(symbolname); + ScriptContext.GlobalScriptContext.Push(vtableoffset); + ScriptContext.GlobalScriptContext.Push(numarguments); + ScriptContext.GlobalScriptContext.Push(returntype); + foreach (var obj in arguments) + { + ScriptContext.GlobalScriptContext.Push(obj); + } + ScriptContext.GlobalScriptContext.SetIdentifier(0xF873189F); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + + public static IntPtr CreateVirtualFunctionFromVTable(IntPtr pointer, int vtableoffset, int numarguments, int returntype, object[] arguments){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(pointer); + ScriptContext.GlobalScriptContext.Push(vtableoffset); + ScriptContext.GlobalScriptContext.Push(numarguments); + ScriptContext.GlobalScriptContext.Push(returntype); + foreach (var obj in arguments) + { + ScriptContext.GlobalScriptContext.Push(obj); + } + ScriptContext.GlobalScriptContext.SetIdentifier(0xE9D17E63); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + public static void HookFunction(IntPtr function, InputArgument hook, bool post){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); @@ -1154,6 +1191,18 @@ public static IntPtr FindSignature(string modulepath, string signature){ } } + public static IntPtr FindVirtualTable(string binarypath, string symbolname){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(binarypath); + ScriptContext.GlobalScriptContext.Push(symbolname); + ScriptContext.GlobalScriptContext.SetIdentifier(0xEA506CFF); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + public static int GetNetworkVectorSize(IntPtr vec){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); diff --git a/src/scripting/natives/natives_memory.cpp b/src/scripting/natives/natives_memory.cpp index a31d0957b..1e031c658 100644 --- a/src/scripting/natives/natives_memory.cpp +++ b/src/scripting/natives/natives_memory.cpp @@ -23,6 +23,14 @@ #include "scripting/autonative.h" #include "scripting/script_engine.h" +#include "core/memory_module.h" + +#ifdef _WIN32 +#define CALL_CONV CONV_THISCALL +#else +#define CALL_CONV CONV_CDECL +#endif + namespace counterstrikesharp { std::vector m_managed_ptrs; @@ -34,6 +42,32 @@ void* FindSignatureNative(ScriptContext& scriptContext) return FindSignature(moduleName, bytesStr); } +void* FindVirtualTable(ScriptContext& scriptContext) +{ + auto binary_name = scriptContext.GetArgument(0); + auto symbol_name = scriptContext.GetArgument(1); + + auto module = modules::GetModuleByName(binary_name); + + if (!module) + { + scriptContext.ThrowNativeError("Failed to get module %s", binary_name); + return nullptr; + } + + auto vtable = module->FindVirtualTable(symbol_name); + + if (!vtable) + { + scriptContext.ThrowNativeError("Failed to get VTable %s from module %s", symbol_name, binary_name); + return nullptr; + } + + return vtable; +} + +// I think we should simplify these in the future as most of the logic is redundant + ValveFunction* CreateVirtualFunctionBySignature(ScriptContext& script_context) { auto ptr = script_context.GetArgument(0); @@ -56,7 +90,7 @@ ValveFunction* CreateVirtualFunctionBySignature(ScriptContext& script_context) args.push_back(script_context.GetArgument(5 + i)); } - auto function = new ValveFunction(function_addr, CONV_CDECL, args, return_type); + auto function = new ValveFunction(function_addr, CALL_CONV, args, return_type); function->SetSignature(signature_hex_string); CSSHARP_CORE_TRACE("Created virtual function, pointer found at {}, signature {}", function_addr, signature_hex_string); @@ -81,15 +115,108 @@ ValveFunction* CreateVirtualFunction(ScriptContext& script_context) auto function_addr = (void*)vtable[vtable_offset]; + if (function_addr == nullptr) + { + script_context.ThrowNativeError("Could not find virtual function at offset %i", vtable_offset); + return nullptr; + } + auto args = std::vector(); for (int i = 0; i < num_arguments; i++) { args.push_back(script_context.GetArgument(4 + i)); } - auto function = new ValveFunction(function_addr, CONV_THISCALL, args, return_type); + auto function = new ValveFunction(function_addr, CALL_CONV, args, return_type); function->SetOffset(vtable_offset); + CSSHARP_CORE_TRACE("Created virtual function, pointer found at {}, offset {}", function_addr, vtable_offset); + + m_managed_ptrs.push_back(function); + return function; +} + +ValveFunction* CreateVirtualFunctionBySymbol(ScriptContext& script_context) +{ + auto binary_name = script_context.GetArgument(0); + auto symbol_name = script_context.GetArgument(1); + auto vtable_offset = script_context.GetArgument(2); + auto num_arguments = script_context.GetArgument(3); + auto return_type = script_context.GetArgument(4); + + auto module = modules::GetModuleByName(binary_name); + + if (!module) + { + script_context.ThrowNativeError("Failed to get module %s", binary_name); + return nullptr; + } + + auto vtable = module->FindVirtualTable(symbol_name); + + if (!vtable) + { + script_context.ThrowNativeError("Failed to get VTable %s from module %s", symbol_name, binary_name); + return nullptr; + } + + auto function_addr = static_cast(vtable)[vtable_offset]; + + if (function_addr == nullptr) + { + script_context.ThrowNativeError("Could not find virtual function at offset %i", vtable_offset); + return nullptr; + } + + auto args = std::vector(); + + for (int i = 0; i < num_arguments; i++) + { + args.push_back(script_context.GetArgument(5 + i)); + } + + auto function = new ValveFunction(function_addr, CALL_CONV, args, return_type); + function->SetOffset(vtable_offset); + + CSSHARP_CORE_TRACE("Created virtual function, pointer found at {}, symbol {}, offset {}", function_addr, symbol_name, vtable_offset); + + m_managed_ptrs.push_back(function); + return function; +} + +ValveFunction* CreateVirtualFunctionFromVTable(ScriptContext& script_context) +{ + auto vtable = script_context.GetArgument(0); + auto vtable_offset = script_context.GetArgument(1); + auto num_arguments = script_context.GetArgument(2); + auto return_type = script_context.GetArgument(3); + + if (!vtable) + { + script_context.ThrowNativeError("VTable is null"); + return nullptr; + } + + auto function_addr = static_cast(vtable)[vtable_offset]; + + if (function_addr == nullptr) + { + script_context.ThrowNativeError("Could not find virtual function at offset %i", vtable_offset); + return nullptr; + } + + auto args = std::vector(); + + for (int i = 0; i < num_arguments; i++) + { + args.push_back(script_context.GetArgument(4 + i)); + } + + auto function = new ValveFunction(function_addr, CALL_CONV, args, return_type); + function->SetOffset(vtable_offset); + + CSSHARP_CORE_TRACE("Created virtual function, pointer found at {}, offset {}", function_addr, vtable_offset); + m_managed_ptrs.push_back(function); return function; } @@ -162,10 +289,13 @@ void RemoveAllNetworkVectorElements(ScriptContext& script_context) REGISTER_NATIVES(memory, { ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION", CreateVirtualFunction); ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_BY_SIGNATURE", CreateVirtualFunctionBySignature); + ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_BY_SYMBOL", CreateVirtualFunctionBySymbol); + ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_FROM_V_TABLE", CreateVirtualFunctionFromVTable); ScriptEngine::RegisterNativeHandler("EXECUTE_VIRTUAL_FUNCTION", ExecuteVirtualFunction); ScriptEngine::RegisterNativeHandler("HOOK_FUNCTION", HookFunction); ScriptEngine::RegisterNativeHandler("UNHOOK_FUNCTION", UnhookFunction); ScriptEngine::RegisterNativeHandler("FIND_SIGNATURE", FindSignatureNative); + ScriptEngine::RegisterNativeHandler("FIND_VIRTUAL_TABLE", FindVirtualTable); ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_SIZE", GetNetworkVectorSize); ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_ELEMENT_AT", GetNetworkVectorElementAt); ScriptEngine::RegisterNativeHandler("REMOVE_ALL_NETWORK_VECTOR_ELEMENTS", RemoveAllNetworkVectorElements); diff --git a/src/scripting/natives/natives_memory.yaml b/src/scripting/natives/natives_memory.yaml index 7d8c9610b..1eb77a54f 100644 --- a/src/scripting/natives/natives_memory.yaml +++ b/src/scripting/natives/natives_memory.yaml @@ -1,9 +1,12 @@ CREATE_VIRTUAL_FUNCTION: pointer:pointer,vtableOffset:int,numArguments:int,returnType:int,arguments:object[] -> pointer CREATE_VIRTUAL_FUNCTION_BY_SIGNATURE: pointer:pointer,binaryName:string,signature:string,numArguments:int,returnType:int,arguments:object[] -> pointer +CREATE_VIRTUAL_FUNCTION_BY_SYMBOL: binaryName:string, symbolName:string, vtableOffset:int, numArguments:int, returnType:int, arguments:object[] -> pointer +CREATE_VIRTUAL_FUNCTION_FROM_V_TABLE: pointer:pointer, vtableOffset:int, numArguments:int, returnType:int, arguments:object[] -> pointer HOOK_FUNCTION: function:pointer, hook:callback, post:bool -> void UNHOOK_FUNCTION: function:pointer, hook:callback, post:bool -> void EXECUTE_VIRTUAL_FUNCTION: function:pointer,arguments:object[] -> any FIND_SIGNATURE: modulePath:string, signature:string -> pointer +FIND_VIRTUAL_TABLE: binaryPath:string, symbolName:string -> pointer GET_NETWORK_VECTOR_SIZE: vec:pointer -> int GET_NETWORK_VECTOR_ELEMENT_AT: vec:pointer, index:int -> pointer -REMOVE_ALL_NETWORK_VECTOR_ELEMENTS: vec:pointer -> void \ No newline at end of file +REMOVE_ALL_NETWORK_VECTOR_ELEMENTS: vec:pointer -> void From 106c9cda9829490d18a0932d4ea0629b42ba20ab Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 12 May 2025 13:08:45 +0200 Subject: [PATCH 08/12] feat: vtables can now be accessed without an instance --- .../DynamicFunctions/BaseMemoryFunction.cs | 71 ++++- .../DynamicFunctions/MemoryFunctionVoid.cs | 294 +++++++++++++++++- .../MemoryFunctionWithReturn.cs | 274 +++++++++++++++- .../Modules/Memory/VTable.cs | 184 +++++++++++ .../Modules/Memory/VirtualFunctionVoid.cs | 200 ++++++++++-- .../Memory/VirtualFunctionWithReturn.cs | 200 ++++++++++-- 6 files changed, 1145 insertions(+), 78 deletions(-) create mode 100644 managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs index 0f83da6a0..6b5fc61ae 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/BaseMemoryFunction.cs @@ -4,7 +4,7 @@ public abstract class BaseMemoryFunction : NativeObject { private static Dictionary _createdFunctions = new(); - private static Dictionary _createdOffsetFunctions = new(); + internal static Dictionary _createdOffsetFunctions = new(); private static IntPtr CreateValveFunctionBySignature(string signature, DataType returnType, DataType[] argumentTypes) @@ -44,17 +44,16 @@ private static IntPtr CreateValveFunctionBySignature(string signature, string bi return function; } - private static IntPtr CreateValveFunctionByOffset(IntPtr objectPtr, Type type, int offset, DataType returnType, - DataType[] argumentTypes) + private static IntPtr CreateValveFunctionByOffset(string symbolName, int offset, DataType returnType, + DataType[] argumentTypes, Func nativeCaller) { - string constructKey = $"{type.Name}_{offset}"; + string constructKey = $"{symbolName}_{offset}"; if (!_createdOffsetFunctions.TryGetValue(constructKey, out var function)) { try { - function = NativeAPI.CreateVirtualFunction(objectPtr, offset, - argumentTypes.Length, (int)returnType, argumentTypes.Cast().ToArray()); + function = nativeCaller(); _createdOffsetFunctions[constructKey] = function; } catch (Exception) { @@ -62,6 +61,36 @@ private static IntPtr CreateValveFunctionByOffset(IntPtr objectPtr, Type type, i } return function; + } + + private static IntPtr CreateValveFunctionByOffset(IntPtr objectPtr, string symbolName, int offset, DataType returnType, + DataType[] argumentTypes) + { + return CreateValveFunctionByOffset(symbolName, offset, returnType, argumentTypes, () => + { + return NativeAPI.CreateVirtualFunction(objectPtr, offset, argumentTypes.Length, + (int)returnType, argumentTypes.Cast().ToArray()); + }); + } + + private static IntPtr CreateValveFunctionBySymbol(string symbolName, string binaryPath, int offset, DataType returnType, + DataType[] argumentTypes) + { + return CreateValveFunctionByOffset(symbolName, offset, returnType, argumentTypes, () => + { + return NativeAPI.CreateVirtualFunctionBySymbol(binaryPath, symbolName, offset, argumentTypes.Length, + (int)returnType, argumentTypes.Cast().ToArray()); + }); + } + + private static IntPtr CreateValveFunctionFromVTable(string symbolName, IntPtr vtable, int offset, DataType returnType, + DataType[] argumentTypes) + { + return CreateValveFunctionByOffset(symbolName, offset, returnType, argumentTypes, () => + { + return NativeAPI.CreateVirtualFunctionFromVTable(vtable, offset, argumentTypes.Length, + (int)returnType, argumentTypes.Cast().ToArray()); + }); } public BaseMemoryFunction(string signature, DataType returnType, DataType[] parameters) : base( @@ -75,10 +104,34 @@ public BaseMemoryFunction(string signature, string binarypath, DataType returnTy } /// - /// WARNING: this is only supposed to be used with and + /// WARNING: this is only supposed to be used with and variants. + /// + internal BaseMemoryFunction(IntPtr objectPtr, string symbolName, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionByOffset(objectPtr, symbolName, offset, returnType, parameters)) + { + } + + /// + /// WARNING: this is only supposed to be used with and variants. + /// + internal BaseMemoryFunction(string symbolName, string binaryPath, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionBySymbol(symbolName, binaryPath, offset, returnType, parameters)) + { + } + + /// + /// WARNING: this is only supposed to be used with and variants. + /// + internal BaseMemoryFunction(string symbolName, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionBySymbol(symbolName, Addresses.ServerPath, offset, returnType, parameters)) + { + } + + /// + /// WARNING: this is only supposed to be used with and variants. /// - internal BaseMemoryFunction(IntPtr objectPtr, Type type, int offset, DataType returnType, DataType[] parameters) : base( - CreateValveFunctionByOffset(objectPtr, type, offset, returnType, parameters)) + internal BaseMemoryFunction(string symbolName, IntPtr vtable, int offset, DataType returnType, DataType[] parameters) : base( + CreateValveFunctionFromVTable(symbolName, vtable, offset, returnType, parameters)) { } diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs index 97090a1d1..e66905b68 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionVoid.cs @@ -27,10 +27,6 @@ public MemoryFunctionVoid(string signature) : base(signature, DataType.DATA_TYPE public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID, Array.Empty()) { - } - - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, Array.Empty()) - { } public void Invoke() @@ -51,9 +47,24 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType() }) + { } public void Invoke(T1 arg1) @@ -74,9 +85,24 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { } public void Invoke(T1 arg1, T2 arg2) @@ -97,9 +123,24 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { } public void Invoke(T1 arg1, T2 arg2, T3 arg3) @@ -128,13 +169,40 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() + }) + { } public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) @@ -165,7 +233,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -174,6 +242,36 @@ internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(obje }) { } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType() + }) + { + } public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { @@ -203,7 +301,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -211,6 +309,36 @@ internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(obje typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { } public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) @@ -243,7 +371,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -252,6 +380,39 @@ internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(obje typeof(T7).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { } public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) @@ -284,7 +445,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -293,6 +454,39 @@ internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(obje typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { } public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) @@ -327,7 +521,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -337,6 +531,42 @@ internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(obje typeof(T9).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType() + }) + { } public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) @@ -371,7 +601,7 @@ public MemoryFunctionVoid(string signature, string binarypath) : base(signature, { } - internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, DataType.DATA_TYPE_VOID, + internal MemoryFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, DataType.DATA_TYPE_VOID, new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), @@ -381,6 +611,42 @@ internal MemoryFunctionVoid(IntPtr objectPtr, Type type, int offset) : base(obje typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() }) { + } + + internal MemoryFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(string symbolName, int offset) : base(symbolName, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionVoid(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, DataType.DATA_TYPE_VOID, + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), + typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), + typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), + typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType() + }) + { } public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs index 10a1a6566..e722905ce 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/MemoryFunctionWithReturn.cs @@ -28,11 +28,6 @@ public MemoryFunctionWithReturn(string signature) : base(signature, typeof(TResu public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(), Array.Empty()) - { - } - - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), - Array.Empty()) { } @@ -54,9 +49,24 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType() }) + { } public TResult Invoke(T1 arg1) @@ -77,9 +87,24 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() }) + { } public TResult Invoke(T1 arg1, T2 arg2) @@ -100,9 +125,24 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3) @@ -131,13 +171,40 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType() + }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) @@ -166,13 +233,40 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType() + }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) @@ -201,13 +295,40 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType() + }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) @@ -238,7 +359,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -246,6 +367,36 @@ internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : bas typeof(T7).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType() + }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) @@ -276,7 +427,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -284,6 +435,36 @@ internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : bas typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType() + }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) @@ -314,7 +495,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -322,6 +503,36 @@ internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : bas typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType() + }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) @@ -354,7 +565,7 @@ public MemoryFunctionWithReturn(string signature, string binarypath) : base(sign { } - internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : base(objectPtr, type, offset, typeof(TResult).ToValidDataType(), + internal MemoryFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(T1).Name, offset, typeof(TResult).ToValidDataType(), new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), @@ -363,6 +574,39 @@ internal MemoryFunctionWithReturn(IntPtr objectPtr, Type type, int offset) : bas typeof(T10).ToValidDataType() }) { + } + + internal MemoryFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { + } + + internal MemoryFunctionWithReturn(VTableBase vtable, int offset) : base(typeof(T1).Name, vtable.Handle, offset, typeof(TResult).ToValidDataType(), + new[] + { + typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(), + typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(), + typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(), + typeof(T10).ToValidDataType() + }) + { } public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs new file mode 100644 index 000000000..f7e147979 --- /dev/null +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs @@ -0,0 +1,184 @@ +/* + * This file is part of CounterStrikeSharp. + * CounterStrikeSharp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CounterStrikeSharp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CounterStrikeSharp. If not, see . * + */ + +namespace CounterStrikeSharp.API.Modules.Memory +{ + public abstract class VTableBase : NativeObject + { + internal VTableBase(IntPtr ptr) : base(ptr) + { } + + internal VTableBase(string symbolName) : this(NativeAPI.FindVirtualTable(Addresses.ServerPath, symbolName)) + { } + + internal VTableBase(string symbolName, string binaryPath) : this(NativeAPI.FindVirtualTable(binaryPath, symbolName)) + { } + } + + /// + /// Represents a low-level virtual table. + /// + public sealed class VTable : VTableBase + { + public VTable(IntPtr ptr) : base(ptr) + { } + + public VTable(string symbolName) : base(symbolName) + { } + + public VTable(string symbolName, string binaryPath) : base(binaryPath, symbolName) + { } + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + } + + /// + /// Represents a low-level virtual table. + /// This version is meant to be used with explicit class type. TClass will be passed as TArg1 on invocation. + /// + public sealed class VTable : VTableBase + { + public VTable(IntPtr ptr) : base(ptr) + { } + + public VTable() : base(typeof(TClass).Name) + { } + + public VTable(string symbolName) : base(symbolName) + { } + + public VTable(string symbolName, string binaryPath) : base(binaryPath, symbolName) + { } + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionVoid GetFunctionVoid(int index) + => new VirtualFunctionVoid(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + + public VirtualFunctionWithReturn GetFunctionWithReturn(int index) + => new VirtualFunctionWithReturn(this, index); + } +} diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs index 5becec0e8..473521bbd 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionVoid.cs @@ -28,11 +28,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -47,11 +63,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -66,11 +98,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -85,11 +133,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -104,11 +168,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -123,11 +203,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -142,11 +238,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -161,11 +273,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -180,11 +308,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -199,11 +343,27 @@ public VirtualFunctionVoid(string signature, string binarypath) : base(signature { } - public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionVoid(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionVoid(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionVoid(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionVoid(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { } - public VirtualFunctionVoid(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionVoid(VTableBase vtable, int offset) : base(vtable, offset) { } } diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs index cf60729cd..31c818a22 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VirtualFunctionWithReturn.cs @@ -28,11 +28,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -47,11 +63,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -66,11 +98,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -85,11 +133,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -104,11 +168,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -123,11 +203,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -142,11 +238,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -161,11 +273,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -180,11 +308,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) + { + } + + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } @@ -199,11 +343,27 @@ public VirtualFunctionWithReturn(string signature, string binarypath) : base(sig { } - public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, typeof(TArg1), offset) + public VirtualFunctionWithReturn(IntPtr objectPtr, int offset) : base(objectPtr, offset) + { + } + + public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, offset) + { + } + + public VirtualFunctionWithReturn(int offset) : base(typeof(TArg1).Name, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, int offset) : base(symbolName, offset) + { + } + + public VirtualFunctionWithReturn(string symbolName, string binaryPath, int offset) : base(symbolName, binaryPath, offset) { } - public VirtualFunctionWithReturn(NativeObject instance, int offset) : base(instance.Handle, typeof(TArg1), offset) + public VirtualFunctionWithReturn(VTableBase vtable, int offset) : base(vtable, offset) { } } From 0006d031caa7af351d221dadce5d60be14381842 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 12 May 2025 13:08:57 +0200 Subject: [PATCH 09/12] feat: created example plugin --- .../WithVirtualFunctions.csproj | 13 ++ .../WithVirtualFunctionsPlugin.cs | 146 ++++++++++++++++++ managed/CounterStrikeSharp.sln | 7 + 3 files changed, 166 insertions(+) create mode 100644 examples/WithVirtualFunctions/WithVirtualFunctions.csproj create mode 100644 examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs diff --git a/examples/WithVirtualFunctions/WithVirtualFunctions.csproj b/examples/WithVirtualFunctions/WithVirtualFunctions.csproj new file mode 100644 index 000000000..32c0ee55a --- /dev/null +++ b/examples/WithVirtualFunctions/WithVirtualFunctions.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs new file mode 100644 index 000000000..4e835206c --- /dev/null +++ b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs @@ -0,0 +1,146 @@ +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Memory; +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +using CounterStrikeSharp.API.Modules.Utils; + +using Microsoft.Extensions.Logging; + +namespace WithVTableHooks; + +public class WithVirtualFunctionsPlugin : BasePlugin +{ + public override string ModuleName => "Example: With Virtual Functions"; + public override string ModuleVersion => "1.0.0"; + public override string ModuleAuthor => "CounterStrikeSharp & Contributors"; + public override string ModuleDescription => "A simple plugin that hooks virtual functions by signature and offset"; + + // There are 3 ways to access a virtual function: + // 1 -> By signature + // 2 -> By the vtable offset (index) and an instance of the class + // 3 -> By the vtable offset (index) and without an instance of the class, but you need to know the vtable symbol + + // In this example, we are going to cover each method. + // Note: we won't cover RE here. + + // 1 -> Working with a signature: + + // this example shows that you can just pass the signature of the function + // Note: CS# assumes the server binary by default. there are overloads that allow you to specify a different binary. + // this example will continue inside the "Load" method. + private static VirtualFunctionVoid CCSPlayerController_SwitchTeam = new(GameData.GetSignature("CCSPlayerController_SwitchTeam")); + + // 2 -> Working with a vtable offset and an instance of the class + // Since we need an active instance of the class, we can only declare our virtual function here, and the rest of the code will be inside the "Load" method. + // Declare it as a nullable type, because we only set a value when this is being used. + private static VirtualFunctionVoid? CCSPlayer_ItemServices_GiveNamedItem; + + // 3 -> Working with a vtable offset without an instance: + + // this example shows that you can just pass the offset of the function, and CS# will automatically gather the VTable and access the function at the given offset. + // Note: CS# assumes the server binary by default. there are overloads that allow you to specify a different binary. + // Note: here, CS# uses the 'CCSPlayerController' (TArg1) argument type name as the "vtable symbol" and you should only rely on this if you know what you are doing. + // Note: if you need more freedom, there are other variants that supports custom parameters. (Check below) + private static VirtualFunctionVoid CCSPlayerController_ChangeTeam = new(GameData.GetOffset("CCSPlayerController_ChangeTeam")); + + // this example is pretty much the same as above, but you should prefer this method if you are not using explicit types, or the vtable symbol is not the same as a predefined class name. (usually when you use 'nint' instead) + // Note: you can still use the `CCSPlayerController` as TArg1, the main point here is if you explicitly set the vtable symbol name, then that value will be used and CS# will NOT use the TArg1 type name. + private static VirtualFunctionVoid CCSPlayerController_Respawn = new("CCSPlayerController", GameData.GetOffset("CCSPlayerController_Respawn")); + + // this is still the same, the main point here is that you can set the vtable symbol, binary path, and the offset. + // private static VirtualFunctionVoid Random_Function = new("VTABLE_SYMBOL_IN_ENGINE_BINARY", Addresses.EnginePath, 51); // this offset is a random example here + + private static VirtualFunctionWithReturn? CCSGameRules_FindPickerEntity; + + // Also there are wrapper classes that you can use: + // Note that this class actually holds the vtable ptr. (.Handle) + // VTable CCSGameRules_VTable_Symbol = new VTable("CCSGameRules"); // this will look for "CCSGameRules" vtable symbol, and if found, you can use this class to retrieve the functions. + + // this is the same as above, but CS# here will use the `TClass` type name as the vtable symbol, and when you retrieve functions, you don't have to specify the TArg1 each time, just the parameters. + VTable CCSGameRules_VTable = new VTable(); + + // examples can be found in the load method. + + public override void Load(bool hotReload) + { + // 1 -> By signature + // setup a hook on the virtual function that we got using the signature. + CCSPlayerController_SwitchTeam.Hook(OnSwitchTeam, HookMode.Pre); + + // 2 -> By the vtable offset (index) and an instance of the class + // so we need to somehow get an instance of `CCSPlayer_ItemServices`, the following code will be a random example and it depends on context. + + AddCommand("vfunc_2", "Example way of accessing a virtual function", (controller, info) => + { + // we don't want to setup the same thing over and over again + if (CCSPlayer_ItemServices_GiveNamedItem != null) + return; + + // sanity checks are up to you + if (controller == null || !controller.IsValid || controller.IsBot || controller.PlayerPawn.Value == null) + return; + + if (controller.PlayerPawn.Value.ItemServices == null) + return; + + // as you can see we used an active instance of the class (controller.PlayerPawn.Value.ItemServices) to access the virtual function. + // if you hook this function, any and every call to it will be intercepted, regardless of the instance. + // in this way, the instance is only needed to access the function through the vtable. + CCSPlayer_ItemServices_GiveNamedItem = new(controller.PlayerPawn.Value.ItemServices, GameData.GetOffset("CCSPlayer_ItemServices_GiveNamedItem")); + CCSPlayer_ItemServices_GiveNamedItem.Hook(OnGiveNamedItem, HookMode.Pre); + }); + + // 3 -> By the vtable offset (index) and without an instance of the class + + // we have already created our virtual function, so we can just use it here. + CCSPlayerController_ChangeTeam.Hook(OnChangeTeam, HookMode.Pre); + + // Wrapper examples + + // when using the generic variant of the VTable class, you only need to pass the generic parameters of the function, TArg1 is assumed to be `CCSGameRules` + CCSGameRules_FindPickerEntity = CCSGameRules_VTable.GetFunctionWithReturn(GameData.GetOffset("CCSGameRules_FindPickerEntity")); + CCSGameRules_FindPickerEntity.Hook(OnFindPickerEntity, HookMode.Pre); + + // and when you are not using the generic variant, you also need to pass the `CCSGameRules` each time. + // CCSGameRules_VTable_Symbol.GetFunctionWithReturn(GameData.GetOffset("CCSGameRules_FindPickerEntity")).Hook(OnFindPickerEntity, HookMode.Pre); + } + + private HookResult OnChangeTeam(DynamicHook hook) + { + Logger.LogInformation("ON CHANGE TEAM"); + return HookResult.Continue; + } + + private HookResult OnGiveNamedItem(DynamicHook hook) + { + string itemName = hook.GetParam(1); + Logger.LogInformation("ON GIVE NAMED ITEM {0}", itemName); + return HookResult.Continue; + } + + private HookResult OnSwitchTeam(DynamicHook hook) + { + Logger.LogInformation("ON SWITCH TEAM"); + return HookResult.Continue; + } + + private HookResult OnFindPickerEntity(DynamicHook hook) + { + Logger.LogInformation("ON FIND PICKER ENTITY"); + return HookResult.Continue; + } + + public override void Unload(bool hotReload) + { + // Dont forget to release your hooks + + // 1 -> By signature + CCSPlayerController_SwitchTeam.Unhook(OnSwitchTeam, HookMode.Pre); + + // 2 -> By the vtable offset (index) and an instance of the class + CCSPlayer_ItemServices_GiveNamedItem?.Unhook(OnSwitchTeam, HookMode.Pre); + + //3 -> By the vtable offset (index) and without an instance of the class + CCSPlayerController_ChangeTeam.Unhook(OnChangeTeam, HookMode.Pre); + CCSGameRules_FindPickerEntity?.Unhook(OnFindPickerEntity, HookMode.Pre); + } +} diff --git a/managed/CounterStrikeSharp.sln b/managed/CounterStrikeSharp.sln index 82ccb2078..627e71957 100644 --- a/managed/CounterStrikeSharp.sln +++ b/managed/CounterStrikeSharp.sln @@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithUserMessages", "..\exam EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithCheckTransmit", "..\examples\WithCheckTransmit\WithCheckTransmit.csproj", "{854B06B5-0E7B-438A-BA51-3F299557F884}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithVirtualFunctions", "..\examples\WithVirtualFunctions\WithVirtualFunctions.csproj", "{ED0905E1-F5D4-4769-89FA-F26F6DB8C4C7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -137,6 +139,10 @@ Global {854B06B5-0E7B-438A-BA51-3F299557F884}.Debug|Any CPU.Build.0 = Debug|Any CPU {854B06B5-0E7B-438A-BA51-3F299557F884}.Release|Any CPU.ActiveCfg = Release|Any CPU {854B06B5-0E7B-438A-BA51-3F299557F884}.Release|Any CPU.Build.0 = Release|Any CPU + {ED0905E1-F5D4-4769-89FA-F26F6DB8C4C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED0905E1-F5D4-4769-89FA-F26F6DB8C4C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED0905E1-F5D4-4769-89FA-F26F6DB8C4C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED0905E1-F5D4-4769-89FA-F26F6DB8C4C7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -159,6 +165,7 @@ Global {76AD7BB0-A096-4336-83E2-B32CAE4E9933} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} {A14029BA-CADE-4F25-ADC5-48CF14332F61} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} {854B06B5-0E7B-438A-BA51-3F299557F884} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} + {ED0905E1-F5D4-4769-89FA-F26F6DB8C4C7} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {069C4CD4-BACA-446A-A6B8-0194E4F75355} From 2c28db9e7c5abd849c9521c0d36afcad1b8f79de Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 13 May 2025 09:26:44 +0200 Subject: [PATCH 10/12] fix: unhook correct method --- examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs index 4e835206c..3989e63b0 100644 --- a/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs +++ b/examples/WithVirtualFunctions/WithVirtualFunctionsPlugin.cs @@ -137,7 +137,7 @@ public override void Unload(bool hotReload) CCSPlayerController_SwitchTeam.Unhook(OnSwitchTeam, HookMode.Pre); // 2 -> By the vtable offset (index) and an instance of the class - CCSPlayer_ItemServices_GiveNamedItem?.Unhook(OnSwitchTeam, HookMode.Pre); + CCSPlayer_ItemServices_GiveNamedItem?.Unhook(OnGiveNamedItem, HookMode.Pre); //3 -> By the vtable offset (index) and without an instance of the class CCSPlayerController_ChangeTeam.Unhook(OnChangeTeam, HookMode.Pre); From 81f188be68648b45264ec5635b790354b4c1b084 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 13 May 2025 09:35:44 +0200 Subject: [PATCH 11/12] tweak: removed symbol ctors from VTable --- managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs b/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs index f7e147979..913d9de8f 100644 --- a/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs +++ b/managed/CounterStrikeSharp.API/Modules/Memory/VTable.cs @@ -115,10 +115,7 @@ public VTable(IntPtr ptr) : base(ptr) public VTable() : base(typeof(TClass).Name) { } - public VTable(string symbolName) : base(symbolName) - { } - - public VTable(string symbolName, string binaryPath) : base(binaryPath, symbolName) + public VTable(string binaryPath) : base(typeof(TClass).Name, binaryPath) { } public VirtualFunctionVoid GetFunctionVoid(int index) From ab31593a4b5937f2ca28f28a598806cb0ca21c05 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Thu, 15 May 2025 19:51:31 +0200 Subject: [PATCH 12/12] feat: windows and linux implementation of CModule::FindVirtualTable --- src/core/memory_module.cpp | 208 +++++++++++++++++++++++++++---------- src/core/memory_module.h | 20 +++- 2 files changed, 172 insertions(+), 56 deletions(-) diff --git a/src/core/memory_module.cpp b/src/core/memory_module.cpp index b361996d6..506620415 100644 --- a/src/core/memory_module.cpp +++ b/src/core/memory_module.cpp @@ -16,8 +16,14 @@ #else #include #include +#include +#include +#include #endif +#include +#include + #include "core/gameconfig.h" #include "core/memory.h" #include "dbg.h" @@ -127,12 +133,15 @@ CModule::CModule(std::string_view path, std::uint64_t base) return; } + m_hModule = dlmount(path.data()); m_base = reinterpret_cast(base); m_pszModule = path.substr(path.find_last_of('/') + 1); m_pszPath = path; m_baseAddress = base; m_size = nt_header->OptionalHeader.SizeOfImage; + DumpSections(); + const bool should_read_from_disk = std::any_of(modules_to_read_from_disk.begin(), modules_to_read_from_disk.end(), [&](const auto& i) { return m_pszModule == i; }); @@ -152,23 +161,20 @@ CModule::CModule(std::string_view path, std::uint64_t base) auto section = IMAGE_FIRST_SECTION(nt_header); - for (auto i = 0; i < nt_header->FileHeader.NumberOfSections; i++) + for (auto i = 0; i < nt_header->FileHeader.NumberOfSections; i++, section++) { - const auto is_executable = (section[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; - const auto is_readable = (section[i].Characteristics & IMAGE_SCN_MEM_READ) != 0; - - const auto start = this->m_baseAddress + section[i].VirtualAddress; - const auto size = (std::min)(section[i].SizeOfRawData, section[i].Misc.VirtualSize); - - auto& segment = m_vecSegments.emplace_back(); - - segment.name = (char*)section[i].Name; - segment.address = start; - segment.size = size; + const auto is_executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; + const auto is_readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; if (is_executable && is_readable) { - // we only reserve bytes for executable and readable sections + const auto start = this->m_baseAddress + section->VirtualAddress; + const auto size = (std::min)(section->SizeOfRawData, section->Misc.VirtualSize); + const auto data = reinterpret_cast(start); + + auto& segment = m_vecSegments.emplace_back(); + + segment.address = start; segment.bytes.reserve(size); if (should_read_from_disk) @@ -183,7 +189,6 @@ CModule::CModule(std::string_view path, std::uint64_t base) return; } - const auto data = reinterpret_cast(start); segment.bytes.assign(&data[0], &data[size]); } } @@ -199,8 +204,11 @@ CModule::CModule(std::string_view path, dl_phdr_info* info) { m_pszModule = path.substr(path.find_last_of('/') + 1); m_pszPath = path.data(); + m_hModule = dlmount(m_pszPath.c_str()); m_baseAddress = info->dlpi_addr; + DumpSections(); + const bool should_read_from_disk = std::any_of(modules_to_read_from_disk.begin(), modules_to_read_from_disk.end(), [&](const auto& i) { return m_pszModule == i; }); @@ -243,7 +251,6 @@ CModule::CModule(std::string_view path, dl_phdr_info* info) auto& segment = m_vecSegments.emplace_back(); - segment.name = (char*)section[i].Name; segment.address = address; segment.bytes.reserve(size); @@ -407,6 +414,87 @@ void CModule::DumpSymbols(ElfW(Dyn) * dyn) } #endif +#ifdef _WIN32 +void CModule::DumpSections() +{ + const auto dos_header = reinterpret_cast(m_hModule); + const auto nt_header = reinterpret_cast(reinterpret_cast(m_hModule) + dos_header->e_lfanew); + const auto sectionHeader = IMAGE_FIRST_SECTION(nt_header); + + for (int i = 0; i < nt_header->FileHeader.NumberOfSections; i++) + { + Section section; + section.name = (char*)sectionHeader[i].Name; + section.address = (uintptr_t)((uint8_t*)m_base + sectionHeader[i].VirtualAddress); + section.size = sectionHeader[i].SizeOfRawData; + + m_vecSections.push_back(std::move(section)); + } +} +#else +void CModule::DumpSections() +{ + link_map* lmap; + + if (dlinfo(m_hModule, RTLD_DI_LINKMAP, &lmap) != 0) + { + dlclose(m_hModule); + CSSHARP_CORE_ERROR("Failed to get shared object handle for {}", m_pszPath); + return; + } + + int fd = open(lmap->l_name, O_RDONLY); + + if (fd == -1) + { + dlclose(m_hModule); + CSSHARP_CORE_ERROR("Failed to get file descriptor for {}", m_pszPath); + return; + } + + struct stat st; + + if (fstat(fd, &st) < 0) + { + close(fd); + dlclose(m_hModule); + CSSHARP_CORE_ERROR("Failed to get file attributes for {}", m_pszPath); + return; + } + + void* map = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + + if (map == MAP_FAILED) + { + close(fd); + dlclose(m_hModule); + CSSHARP_CORE_ERROR("Failed to get sections for {} (mmap: {})", m_pszPath, strerror(errno)); + return; + } + + ElfW(Ehdr)* ehdr = static_cast(map); + ElfW(Shdr)* shdr = reinterpret_cast(reinterpret_cast(ehdr) + ehdr->e_shoff); + const char* strTab = reinterpret_cast(reinterpret_cast(ehdr) + shdr[ehdr->e_shstrndx].sh_offset); + + for (int i = 0; i < ehdr->e_shnum; i++) + { + if (*(strTab + shdr[i].sh_name) == '\0') + continue; + + Section section; + section.name = std::string(strTab + shdr[i].sh_name); + section.address = reinterpret_cast(lmap->l_addr + shdr[i].sh_addr); + section.size = shdr[i].sh_size; + + m_vecSections.push_back(section); + } + + munmap(map, st.st_size); + close(fd); + // dlclose(m_hModule); // we might need this later? +} +#endif + std::optional> CModule::GetOriginalBytes(const std::vector& disk_data, std::uintptr_t rva, std::size_t size) { @@ -576,8 +664,8 @@ void* CModule::FindVirtualTable(const std::string& name) return reinterpret_cast(_vtables[name]); } - auto runTimeData = GetSegment(".data"); - auto readOnlyData = GetSegment(".rdata"); + auto runTimeData = GetSection(".data"); + auto readOnlyData = GetSection(".rdata"); if (!runTimeData || !readOnlyData) { @@ -586,16 +674,16 @@ void* CModule::FindVirtualTable(const std::string& name) } std::string decoratedTableName = ".?AV" + name + "@@"; - size_t tableNameLength = decoratedTableName.size() + 1; + size_t pattern1Length = decoratedTableName.size() + 1; bool foundTypeDescriptor = false; void* typeDescriptor = nullptr; - for (uintptr_t i = 0; i < runTimeData->size - tableNameLength; ++i) + for (size_t i = 0; i < runTimeData->size - pattern1Length; i++) { - if (memcmp((void*)((uintptr_t)runTimeData->address + i), decoratedTableName.c_str(), tableNameLength) == 0) + if (memcmp((void*)(runTimeData->address + i), decoratedTableName.c_str(), pattern1Length) == 0) { - typeDescriptor = (void*)((uintptr_t)runTimeData->address + i); + typeDescriptor = (void*)(runTimeData->address + i); foundTypeDescriptor = true; break; } @@ -610,14 +698,13 @@ void* CModule::FindVirtualTable(const std::string& name) typeDescriptor = (void*)((uintptr_t)typeDescriptor - 0x10); const uint32_t rttiTDRva = (uintptr_t)typeDescriptor - (uintptr_t)m_base; - bool foundCompleteObjectLocator = false; void* completeObjectLocator = nullptr; - for (uintptr_t i = 0; i < readOnlyData->size - sizeof(uint32_t); ++i) + for (size_t i = 0; i < readOnlyData->size - sizeof(uint32_t); i++) { - if (*(uint32_t*)((uintptr_t)readOnlyData->address + i) == rttiTDRva) + if (*(uint32_t*)(readOnlyData->address + i) == rttiTDRva) { - uintptr_t completeObjectLocatorHeader = (uintptr_t)readOnlyData->address + i - 0xC; + uintptr_t completeObjectLocatorHeader = readOnlyData->address + i - 0xC; if (*(int32_t*)completeObjectLocatorHeader != 1) continue; @@ -626,32 +713,30 @@ void* CModule::FindVirtualTable(const std::string& name) continue; completeObjectLocator = (void*)completeObjectLocatorHeader; - foundCompleteObjectLocator = true; break; } } - if (!foundCompleteObjectLocator) + if (!completeObjectLocator) { CSSHARP_CORE_ERROR("Failed to find complete object locator for {}", name); return nullptr; } - bool foundVTable = false; void* vtable = nullptr; - for (uintptr_t i = 0; i < readOnlyData->size - sizeof(void*); ++i) + for (size_t i = 0; i < readOnlyData->size - 0x8; i++) { - if (*(void**)((uintptr_t)readOnlyData->address + i) == completeObjectLocator) + if (*(void**)(readOnlyData->address + i) == completeObjectLocator) { - vtable = (void*)((uintptr_t)readOnlyData->address + i + 0x8); - foundVTable = true; + vtable = (void*)(readOnlyData->address + i + 0x8); break; } } - if (!foundVTable) + if (!vtable) { + // CSSHARP_CORE_ERROR("Failed to find vtable for {}", name); // not sure if we need to log this as an error as there is no use of it in unmanaged as of now return nullptr; } @@ -666,24 +751,27 @@ void* CModule::FindVirtualTable(const std::string& name) return reinterpret_cast(_vtables[name]); } - auto readOnlyData = GetSegment(".rodata"); - auto readOnlyRelocations = GetSegment(".data.rel.ro"); + auto readOnlyData = GetSection(".rodata"); + auto readOnlyRelocations = GetSection(".data.rel.ro"); if (!readOnlyData || !readOnlyRelocations) { - CSSHARP_CORE_ERROR("Failed to find .rodata or .data.rel.ro segment"); + CSSHARP_CORE_ERROR("Failed to find .rodata or .data.rel.ro section"); return nullptr; } std::string decoratedTableName = std::to_string(name.length()) + name; + const byte* pattern1 = reinterpret_cast(decoratedTableName.c_str()); + size_t pattern1Length = decoratedTableName.size() + 1; + void* classNameString = nullptr; - for (uintptr_t i = 0; i < readOnlyData->size - decoratedTableName.size(); ++i) + for (size_t i = 0; i + pattern1Length <= readOnlyData->size; i++) { - if (memcmp((void*)((uintptr_t)readOnlyData->address + i), decoratedTableName.c_str(), decoratedTableName.size()) == 0) + if (memcmp((void*)(readOnlyData->address + i), pattern1, pattern1Length) == 0) { - classNameString = (void*)((uintptr_t)readOnlyData->address + i); + classNameString = (void*)(readOnlyData->address + i); break; } } @@ -694,13 +782,14 @@ void* CModule::FindVirtualTable(const std::string& name) return nullptr; } + const byte* pattern2 = reinterpret_cast(&classNameString); void* typeName = nullptr; - for (uintptr_t i = 0; i < readOnlyRelocations->size - sizeof(void*); ++i) + for (size_t i = 0; i + 0x8 <= readOnlyRelocations->size; i++) { - if (*(void**)((uintptr_t)readOnlyRelocations->address + i) == classNameString) + if (memcmp((void*)(readOnlyRelocations->address + i), pattern2, 0x8) == 0) { - typeName = (void*)((uintptr_t)readOnlyRelocations->address + i); + typeName = (void*)(readOnlyRelocations->address + i); break; } } @@ -713,38 +802,49 @@ void* CModule::FindVirtualTable(const std::string& name) void* typeInfo = (void*)((uintptr_t)typeName - 0x8); + void* vtable = nullptr; + for (const auto& sectionName : { std::string_view(".data.rel.ro"), std::string_view(".data.rel.ro.local") }) { - auto section = GetSegment(sectionName); + auto section = GetSection(sectionName); if (!section) continue; - for (uintptr_t i = 0; i < section->size - sizeof(void*); ++i) + for (size_t i = 0; i + 0x8 <= section->size; i++) { - if (*(void**)((uintptr_t)section->address + i) == typeInfo) + void* currentPtr = (void*)(section->address + i); + + if (memcmp(currentPtr, &typeInfo, 0x8) == 0) { - void* vtable = (void*)((uintptr_t)section->address + i + 0x8); + int64_t* header = (int64_t*)((uintptr_t)currentPtr - 0x8); - if (*(int64_t*)((uintptr_t)vtable - 0x8) == 0) + if (header >= (int64_t*)section->address && header < (int64_t*)(section->address + section->size) && *header == 0) { - _vtables.insert({ name, reinterpret_cast(vtable) }); - return vtable; + vtable = (void*)((uintptr_t)currentPtr + 0x8); + break; } } } } - return nullptr; + if (!vtable) + { + // CSSHARP_CORE_ERROR("Failed to find vtable for {}", name); // not sure if we need to log this as an error as there is no use of it in unmanaged as of now + return nullptr; + } + + _vtables.insert({ name, reinterpret_cast(vtable) }); + return vtable; } #endif -Segments* CModule::GetSegment(std::string_view name) +Section* CModule::GetSection(std::string_view name) { - for (auto&& segment : m_vecSegments) + for (auto&& section : m_vecSections) { - if (segment.name == name) - return &segment; + if (section.name == name) + return §ion; } return nullptr; diff --git a/src/core/memory_module.h b/src/core/memory_module.h index 899192294..b79131c9c 100644 --- a/src/core/memory_module.h +++ b/src/core/memory_module.h @@ -44,9 +44,21 @@ struct Segments Segments& operator=(const Segments&) = default; Segments& operator=(Segments&&) = default; - std::string name{}; std::uintptr_t address{}; std::vector bytes{}; +}; + +struct Section +{ + Section() = default; + + Section(const Section&) = default; + Section(Section&&) = default; + Section& operator=(const Section&) = default; + Section& operator=(Section&&) = default; + + std::string name{}; + std::uintptr_t address{}; size_t size{}; }; @@ -67,18 +79,20 @@ class CModule void* FindVirtualTable(const std::string& name); - Segments* GetSegment(std::string_view name); + Section* GetSection(std::string_view name); [[nodiscard]] bool IsInitialized() const { return m_bInitialized; } std::string m_pszModule{}; std::string m_pszPath{}; + void* m_hModule{}; void* m_base{}; size_t m_size{}; private: bool m_bInitialized{}; std::vector m_vecSegments{}; + std::vector
m_vecSections{}; std::uintptr_t m_baseAddress{}; std::unordered_map _symbols{}; std::unordered_map _interfaces{}; @@ -88,8 +102,10 @@ class CModule #ifdef _WIN32 void DumpSymbols(); + void DumpSections(); #else void DumpSymbols(ElfW(Dyn) * dyn); + void DumpSections(); #endif std::optional> GetOriginalBytes(const std::vector& disk_data, std::uintptr_t rva, std::size_t size);