Пример #1
0
        public void TestVTableCall()
        {
            var vTable = VirtualFunctionTable.FromAddress(_nativeCalculator.VTable, Enum.GetNames(typeof(NativeCalculator.VTableFunctions)).Length);

            // Setup calling functions.
            var addFunction      = vTable.CreateWrapperFunction <NativeCalculator.AddFunction>((int)NativeCalculator.VTableFunctions.Add);
            var subtractFunction = vTable.CreateWrapperFunction <NativeCalculator.SubtractFunction>((int)NativeCalculator.VTableFunctions.Subtract);
            var multiplyFunction = vTable.CreateWrapperFunction <NativeCalculator.MultiplyFunction>((int)NativeCalculator.VTableFunctions.Multiply);
            var divideFunction   = vTable.CreateWrapperFunction <NativeCalculator.DivideFunction>((int)NativeCalculator.VTableFunctions.Divide);

            // Test Calling
            for (int x = 1; x < 100; x++)
            {
                for (int y = 100; y > 0; y--)
                {
                    int add      = x + y;
                    int subtract = x - y;
                    int multiply = x * y;
                    int divide   = x / y;

                    Assert.Equal(add, addFunction(x, y));
                    Assert.Equal(subtract, subtractFunction(x, y));
                    Assert.Equal(multiply, multiplyFunction(x, y));
                    Assert.Equal(divide, divideFunction(x, y));
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Copies Crosire's D3D8To9 and hooks the DX9 device creation.
        /// </summary>
        /// <param name="dllDirectory">Directory containing Crosire's d3d8to9.</param>
        public void HookDevice(string dllDirectory)
        {
            // Copy crosire's d3d8to9 to game directory and then load it. (Game should use D3D9 now).
            if (!File.Exists("d3d8.dll"))
            {
                File.Copy(dllDirectory + $"\\d3d8.dll", "d3d8.dll", true);
            }

            // Load Crosire's D3D8To9 (which in turn loads D3D9 internally)
            LoadLibraryW("d3d8.dll");

            // Get our D3D Interface VTable
            using (Direct3D direct3D = new Direct3D())
                using (Form renderForm = new Form())
                    using (SharpDX.Direct3D9.Device device = new SharpDX.Direct3D9.Device(direct3D, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters()
                    {
                        BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle
                    }))
                    {
                        _direct3DVirtualFunctionTable       = new VirtualFunctionTable(direct3D.NativePointer, Enum.GetNames(typeof(Interfaces.IDirect3D9)).Length);
                        _direct3DDeviceVirtualFunctionTable = new VirtualFunctionTable(device.NativePointer, Enum.GetNames(typeof(Interfaces.IDirect3DDevice9)).Length);
                    }

            // Hook D3D9 device creation.
            _createDeviceHook = _direct3DVirtualFunctionTable.TableEntries[(int)Interfaces.IDirect3D9.CreateDevice].CreateFunctionHook86 <CreateDevice>(CreateDeviceImpl).Activate();
            //_resetDeviceHook = _direct3DDeviceVirtualFunctionTable.TableEntries[(int)Interfaces.IDirect3DDevice9.Reset].CreateFunctionHook86<Direct3D9DeviceResetDelegate>(ResetDeviceImpl).Activate();
        }
Пример #3
0
        /// <summary>
        /// Constructor for the hooking class.
        /// Creates the Direct3D9/Direct3D9Ex devices inside the function to get their
        /// native pointer for hooking purposes.
        /// </summary>
        public DX9Hook()
        {
            // Obtain the pointer to the IDirect3DDevice9 instance
            // by creating our own blank windows form and creating a IDirect3DDevice9
            // targeting that form. The returned device should be the same one as used by the game.
            using (Direct3D direct3D = new Direct3D())
                using (Form renderForm = new Form())
                    using (Device device = new Device(direct3D, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters()
                    {
                        BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle
                    }))
                    {
                        DirectXFunctions = new VirtualFunctionTable(device.NativePointer, Enum.GetNames(typeof(Direct3DDevice9)).Length);
                    }

            // Obtain the pointer to the IDirect3DDevice9Ex instance
            // by creating our own blank windows form and creating a IDirect3DDevice9Ex
            // targeting that form. The returned device should be the same one as used by the game.
            using (Direct3DEx direct3D = new Direct3DEx())
                using (var renderForm = new Form())
                    using (DeviceEx device = new DeviceEx(direct3D, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters()
                    {
                        BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle
                    }))
                    {
                        try
                        {
                            DirectXFunctions.TableEntries.AddRange(VirtualFunctionTable.GetObjectVTableAddresses(device.NativePointer, Enum.GetNames(typeof(Direct3DDevice9Ex)).Length));
                            SupportsDirect3D9Ex = true;
                        }
                        catch { SupportsDirect3D9Ex = false; }
                    }
        }
Пример #4
0
        public void TestVTableHook()
        {
            var vTable = VirtualFunctionTable.FromAddress(_nativeCalculator.VTable, Enum.GetNames(typeof(NativeCalculator.VTableFunctions)).Length);

            var addFunction      = vTable.CreateWrapperFunction <NativeCalculator.AddFunction>((int)NativeCalculator.VTableFunctions.Add);
            var subtractFunction = vTable.CreateWrapperFunction <NativeCalculator.SubtractFunction>((int)NativeCalculator.VTableFunctions.Subtract);
            var multiplyFunction = vTable.CreateWrapperFunction <NativeCalculator.MultiplyFunction>((int)NativeCalculator.VTableFunctions.Multiply);
            var divideFunction   = vTable.CreateWrapperFunction <NativeCalculator.DivideFunction>((int)NativeCalculator.VTableFunctions.Divide);

            int addHook(int a, int b)
            {
                return(_addHook.OriginalFunction(a, b) + 1);
            }

            int subHook(int a, int b)
            {
                return(_subHook.OriginalFunction(a, b) - 1);
            }

            int mulHook(int a, int b)
            {
                return(_multiplyHook.OriginalFunction(a, b) * 2);
            }

            int divHook(int a, int b)
            {
                return(_divideHook.OriginalFunction(a, b) * 2);
            }

            _addHook      = vTable.CreateFunctionHook <NativeCalculator.AddFunction>((int)NativeCalculator.VTableFunctions.Add, addHook).Activate();
            _subHook      = vTable.CreateFunctionHook <NativeCalculator.SubtractFunction>((int)NativeCalculator.VTableFunctions.Subtract, subHook).Activate();
            _multiplyHook = vTable.CreateFunctionHook <NativeCalculator.MultiplyFunction>((int)NativeCalculator.VTableFunctions.Multiply, mulHook).Activate();
            _divideHook   = vTable.CreateFunctionHook <NativeCalculator.DivideFunction>((int)NativeCalculator.VTableFunctions.Divide, divHook).Activate();

            for (int x = 1; x < 100; x++)
            {
                for (int y = 100; y > 0; y--)
                {
                    int add      = (x + y) + 1;
                    int subtract = (x - y) - 1;
                    int multiply = (x * y) * 2;
                    int divide   = (x / y) * 2;

                    Assert.Equal(add, addFunction(x, y));
                    Assert.Equal(subtract, subtractFunction(x, y));
                    Assert.Equal(multiply, multiplyFunction(x, y));
                    Assert.Equal(divide, divideFunction(x, y));
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Constructor for the DX11 hooking class.
        /// Creates the Direct3D11 device and DXGI swapchain inside the function to get their
        /// native pointer for hooking purposes.
        /// </summary>
        public DX11Hook()
        {
            /*
             *  Target: Obtain the pointer to the ID3D11Device and IDXGISwapChain instances
             *  by creating our own blank windows form and creating a ID3D11Device with Swapchain
             *  targeting that form. The returned device should be the same one as used by the game.
             */

            // Declare the Swapchain, Windows form, DX11 device.
            Form      renderForm = new Form();
            SwapChain dxgiSwapChain;
            Device    dx11Device;

            // Create the Device and SwapChain
            Device.CreateWithSwapChain(
                DriverType.Hardware,
                DeviceCreationFlags.BgraSupport,
                new SharpDX.DXGI.SwapChainDescription
            {
                BufferCount       = 1,
                Flags             = SharpDX.DXGI.SwapChainFlags.None,
                IsWindowed        = true,
                ModeDescription   = new SharpDX.DXGI.ModeDescription(100, 100, new Rational(60, 1), SharpDX.DXGI.Format.R8G8B8A8_UNorm),
                OutputHandle      = renderForm.Handle,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                SwapEffect        = SharpDX.DXGI.SwapEffect.Discard,
                Usage             = SharpDX.DXGI.Usage.RenderTargetOutput
            },
                out dx11Device,
                out dxgiSwapChain
                );

            // Get our VTable function pointers.
            DirectX11DeviceFunctions = new VirtualFunctionTable(dx11Device.NativePointer, Enum.GetNames(typeof(ID3D11Device)).Length);
            DXGISwapChainFunctions   = new VirtualFunctionTable(dxgiSwapChain.NativePointer, Enum.GetNames(typeof(IDXGISwapChain)).Length);

            // Dispose of the native objects.
            renderForm.Dispose();
            dxgiSwapChain.Dispose();
            dx11Device.Dispose();;
        }
        public unsafe void TestExternalVTableCallAfterVTablePointerIsHooked()
        {
            // HookedObjectVirtualFunctionTable only supports hooking objects
            // where the vtable pointer is at [objectbaseadress]
            // to test this, we create a pointer to our vtable.
            // this serves as a fake object, which we can hook
            nuint  vTableOriginal = _nativeCalculator.VTable;
            IntPtr fakeObject     = new IntPtr(&vTableOriginal);
            // We hook the vtable pointer(fakeObject), this changes the vtable pointer but does not hook any functions yet
            // Checking if this corrupts anything is done in TestVTableHookExternalCallBeforeHook
            var vTableHook = HookedObjectVirtualFunctionTable.FromObject(fakeObject.ToUnsigned(), Enum.GetNames(typeof(NativeCalculator.VTableFunctions)).Length);;

            // We create a VirtualFunctionTable from our fakeObject
            // Calling the functions should call our hooks

            var vTable           = VirtualFunctionTable.FromObject(fakeObject.ToUnsigned(), Enum.GetNames(typeof(NativeCalculator.VTableFunctions)).Length);
            var addFunction      = vTable.CreateWrapperFunction <NativeCalculator.AddFunction>((int)NativeCalculator.VTableFunctions.Add);
            var subtractFunction = vTable.CreateWrapperFunction <NativeCalculator.SubtractFunction>((int)NativeCalculator.VTableFunctions.Subtract);
            var multiplyFunction = vTable.CreateWrapperFunction <NativeCalculator.MultiplyFunction>((int)NativeCalculator.VTableFunctions.Multiply);
            var divideFunction   = vTable.CreateWrapperFunction <NativeCalculator.DivideFunction>((int)NativeCalculator.VTableFunctions.Divide);

            // Test Calling after we hook the vtable pointer using an 'external' class (VirtualFunctionTable)
            // This should not modify any results
            for (int x = 1; x < 100; x++)
            {
                for (int y = 100; y > 0; y--)
                {
                    int add      = x + y;
                    int subtract = x - y;
                    int multiply = x * y;
                    int divide   = x / y;

                    Assert.Equal(add, addFunction(x, y));
                    Assert.Equal(subtract, subtractFunction(x, y));
                    Assert.Equal(multiply, multiplyFunction(x, y));
                    Assert.Equal(divide, divideFunction(x, y));
                }
            }
        }
Пример #7
0
 public IVirtualFunctionTable VirtualFunctionTableFromAddress(IntPtr tableAddress, int numberOfMethods) => VirtualFunctionTable.FromAddress(tableAddress, numberOfMethods);
Пример #8
0
 public IVirtualFunctionTable VirtualFunctionTableFromObject(IntPtr objectAddress, int numberOfMethods) => VirtualFunctionTable.FromObject(objectAddress, numberOfMethods);
        public unsafe void TestExternalVTableCallAfterFunctionHookButWithDirectCall()
        {
            int addHook(int a, int b)
            {
                return(_addHook.OriginalFunction(a, b) + 1);
            }

            int subHook(int a, int b)
            {
                return(_subHook.OriginalFunction(a, b) - 1);
            }

            int mulHook(int a, int b)
            {
                return(_multiplyHook.OriginalFunction(a, b) * 2);
            }

            int divHook(int a, int b)
            {
                return(_divideHook.OriginalFunction(a, b) * 2);
            }

            // HookedObjectVirtualFunctionTable only supports hooking objects
            // where the vtable pointer is at [objectbaseadress]
            // to test this, we create a pointer to our vtable.
            // this serves as a fake object, which we can hook
            nuint  vTableOriginal = _nativeCalculator.VTable;
            IntPtr fakeObject     = new IntPtr(&vTableOriginal);

            // We hook the vtable pointer(fakeObject), this changes the vtable pointer but does not hook any functions yet
            // Checking if this corrupts anything is done in TestVTableCallsAfterHookingVTablePointer
            var vTableHook = HookedObjectVirtualFunctionTable.FromObject(fakeObject.ToUnsigned(), Enum.GetNames(typeof(NativeCalculator.VTableFunctions)).Length);;

            _addHook      = vTableHook.CreateFunctionHook <NativeCalculator.AddFunction>((int)NativeCalculator.VTableFunctions.Add, addHook).Activate();
            _subHook      = vTableHook.CreateFunctionHook <NativeCalculator.SubtractFunction>((int)NativeCalculator.VTableFunctions.Subtract, subHook).Activate();
            _multiplyHook = vTableHook.CreateFunctionHook <NativeCalculator.MultiplyFunction>((int)NativeCalculator.VTableFunctions.Multiply, mulHook).Activate();
            _divideHook   = vTableHook.CreateFunctionHook <NativeCalculator.DivideFunction>((int)NativeCalculator.VTableFunctions.Divide, divHook).Activate();

            // In this test we access our vtable directly
            // As the vtable itself is never changed, this should not hook any functions
            var vTable = VirtualFunctionTable.FromAddress(_nativeCalculator.VTable, Enum.GetNames(typeof(NativeCalculator.VTableFunctions)).Length);

            var addFunction      = vTable.CreateWrapperFunction <NativeCalculator.AddFunction>((int)NativeCalculator.VTableFunctions.Add);
            var subtractFunction = vTable.CreateWrapperFunction <NativeCalculator.SubtractFunction>((int)NativeCalculator.VTableFunctions.Subtract);
            var multiplyFunction = vTable.CreateWrapperFunction <NativeCalculator.MultiplyFunction>((int)NativeCalculator.VTableFunctions.Multiply);
            var divideFunction   = vTable.CreateWrapperFunction <NativeCalculator.DivideFunction>((int)NativeCalculator.VTableFunctions.Divide);

            // Test Calling after we hook the vtable function pointers using an 'external' class (VirtualFunctionTable)
            // This should not modify any results
            for (int x = 1; x < 100; x++)
            {
                for (int y = 100; y > 0; y--)
                {
                    int add      = x + y;
                    int subtract = x - y;
                    int multiply = x * y;
                    int divide   = x / y;

                    Assert.Equal(add, addFunction(x, y));
                    Assert.Equal(subtract, subtractFunction(x, y));
                    Assert.Equal(multiply, multiplyFunction(x, y));
                    Assert.Equal(divide, divideFunction(x, y));
                }
            }
        }