C# EasyHook calling the original function crashes the program

12/20/2016 16:13 matt69#1
Can anyone help me identify why this function always crashes the game?

I have been following tutorials on easyhook to hook the jump function and the game seems to crash when i call the original function. The program enters hkJump(x,y) and I can read the parameters correctly just fine. However, if I dont call the original function then the game doesnt call it either so there is no jump. When I try to call the original function after performing my function in hkJump(x,y), the game crashes?

What is wrong with my code.

Please help

Code:
public class Main : IEntryPoint
    {
        static IntPtr JumpAddress = new IntPtr(0x51478B);

        static COInterface Interface;
        static LocalHook JumpHook;
        static String ChannelName;

        public Main(RemoteHooking.IContext InContext, String InChannelName)
        {
            Interface = RemoteHooking.IpcConnectClient<COInterface>(InChannelName);
            Interface.Log("DLL Injected into target process.");
            
        }

        public unsafe void Run(RemoteHooking.IContext InContext, String InChannelName)
        {

           try
            {
                Interface.Log("Running hook");
                JumpHook = LocalHook.Create(JumpAddress, new dJumpFunction(hkJump), this);
                JumpHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
                Interface.Log("Jump function hooked");
            } catch ( Exception e )
            {
                Interface.ReportException(e);
            }
            try
            {
                RemoteHooking.WakeUpProcess();
            } catch(Exception e) {
                Interface.ReportException(e);
            }
            while (true)
            {
                Thread.Sleep(1000);
            }
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        public unsafe delegate int dJumpFunction([MarshalAs(UnmanagedType.I4)] int x, [MarshalAs(UnmanagedType.I4)] int y);

        public static unsafe dJumpFunction oDispatchMessage = (dJumpFunction)Marshal.GetDelegateForFunctionPointer(JumpAddress, typeof(dJumpFunction));
       
        static int hkJump([MarshalAs(UnmanagedType.I4)] int x, [MarshalAs(UnmanagedType.I4)] int y )
        {
            try
            {
                Interface.Log("X=" + x + ", Y=" + y);
                return oDispatchMessage(x, y);
            } catch(Exception e)
            {
                Interface.ReportException(e);
                return oDispatchMessage(x, y);
            }
        }
    }
12/20/2016 16:38 VestaPlay#2
I think you should use strackflow on Google
12/20/2016 18:16 Best Coder 2014#3
Isn't "jump" a method on a "Player" class or something?
If so, you probably need to change the signature from:
Code:
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
public unsafe delegate int dJumpFunction([MarshalAs(UnmanagedType.I4)] int x, [MarshalAs(UnmanagedType.I4)] int y);
to:
Code:
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Unicode, SetLastError = true)]
public unsafe delegate int dJumpFunction(IntPtr instance, [MarshalAs(UnmanagedType.I4)] int x, [MarshalAs(UnmanagedType.I4)] int y);
And, of course, adjust your "hkJump" function accordingly.
12/21/2016 02:35 matt69#4
Quote:
Originally Posted by Best Coder 2014 View Post
Isn't "jump" a method on a "Player" class or something?
If so, you probably need to change the signature from:
Code:
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
public unsafe delegate int dJumpFunction([MarshalAs(UnmanagedType.I4)] int x, [MarshalAs(UnmanagedType.I4)] int y);
to:
Code:
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Unicode, SetLastError = true)]
public unsafe delegate int dJumpFunction(IntPtr instance, [MarshalAs(UnmanagedType.I4)] int x, [MarshalAs(UnmanagedType.I4)] int y);
And, of course, adjust your "hkJump" function accordingly.
Thank you, this worked. However, I dont understand why i needed an IntPtr as a parameter since ollydbg guessed the function only needed two parameters?

How did you know to put that there? What did I miss?
12/21/2016 10:06 Best Coder 2014#5
Quote:
Originally Posted by matt69 View Post
Thank you, this worked. However, I dont understand why i needed an IntPtr as a parameter since ollydbg guessed the function only needed two parameters?

How did you know to put that there? What did I miss?
My guess is that OllyDbg probably isn't able to distinguish between an "StdCall" function with two parameters and a "ThisCall" function with three parameters. The reason is that they are pretty much identical, the only difference is that a "ThisCall" function has a "hidden" instance parameter which is passed in the ECX register.

If you look for places where the jump function is called, you'll probably find something like:
Code:
mov ecx, <instance>
push <y>
push <x>
call <jump>
The "mov ecx, ..." part is what indicates that the function being called is actually a "ThisCall" function with three parameters, and not an "StdCall" function with two parameters.