Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Void hook skips original function causing crash #401

Open
ATLaptic opened this issue Sep 21, 2022 · 3 comments
Open

Void hook skips original function causing crash #401

ATLaptic opened this issue Sep 21, 2022 · 3 comments

Comments

@ATLaptic
Copy link

I am a beginner with this library and I'm trying to hook onto a void while following the c# remote file monitor tutorial. And the hook works with it queueing all the messages but then crashing the program immediately after. When I used a debugger to figure out what went wrong.

I learned the hook returns to the place the original function was called instead of the function itself, this causes the next return to go to FFFFFFFF and the crashes the program.
Untitled

The hook delegate I used is below. I'm fairly confident about the calling convention and the parameters. But I'm not sure if I am returning it correctly to make it not skip the original function.

Thanks in advance for any help you can give!

[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)]
        delegate void LoadRoom_Delegate(
            float idk,
            float idk2,
            float levelid,
            float roomid,
            float idk3
            );
        [DllImport("Game.exe",
    CharSet = CharSet.Unicode,
    SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        static extern void Loadroom(
            float idk,
            float idk2,
            float levelid,
            float roomid,
            float idk3
            );
        void LoadRoom_hook(
            float idk,
            float idk2,
            float levelid,
            float roomid,
            float idk3
            )
        {
            try
            {
                if (roomid == 640)
                {
                    this._messagequeue.Enqueue("Now Playing Level 1: Room 1!");
                }
                this._messagequeue.Enqueue(roomid.ToString());
                lock (this._messagequeue)
                {
                    if (this._messagequeue.Count < 1000)
                    {
                        this._messagequeue.Enqueue("this part works");

                    }
                }
                
            }
            catch {
            }
            this._messagequeue.Enqueue("function cleared");
            return;
        }
@justinstenning
Copy link
Member

If you want to call the original, call the function before you return.

EasyHook detects you are already in your hook and will just skip the hook

@ATLaptic
Copy link
Author

When I try that, it calls the function. But at the end of the original function, it returns to the hook causing the same thing to happen as before.

Here's what I'm doing (ignore janky way of getting the original function)
I have done it with and without the return line at the end.

[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)]
        delegate void LoadRoom_Delegate(
            float idk,
            float idk2,
            float levelid,
            float roomid,
            float idk3
            );
        void LoadRoom_hook(
            float idk,
            float idk2,
            float levelid,
            float roomid,
            float idk3
            )
        {
            try
            {
                if (roomid == 640)
                {
                    this._messagequeue.Enqueue("Now Playing Level 1: Room 1!");
                }
                this._messagequeue.Enqueue(roomid.ToString());
                lock (this._messagequeue)
                {
                    if (this._messagequeue.Count < 1000)
                    {
                        this._messagequeue.Enqueue("this part works");
                    }
                }
                
            }
            catch {
            }
            this._messagequeue.Enqueue("function cleared");
            var returnVoid = Marshal.GetDelegateForFunctionPointer<LoadRoom_Delegate>(new IntPtr(Process.GetProcessesByName("HotlineMiami2")[0].Modules[0].BaseAddress.ToInt64() + 0x00EBDBF0));
            returnVoid(
             idk,
             idk2,
             levelid,
             roomid,
             idk3
            );
            return;
        }

@justinstenning
Copy link
Member

Are you 100% sure that the calling convention and method signature are correct?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants