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

PLH::BreakPointHook crashes when exception handled #90

Closed
automata172 opened this issue Jan 8, 2021 · 3 comments
Closed

PLH::BreakPointHook crashes when exception handled #90

automata172 opened this issue Jan 8, 2021 · 3 comments
Labels

Comments

@automata172
Copy link

PLH::BreakPointHook crashes the program when the hooked function is called.

Environment

OS: Windows 10 Pro (20H2)
Memory: 32,0 GB
Processor: AMD Ryzen 7 3700X

Code (x64 Release)

#include <string>
#include <cstdio>
#include <Windows.h>
#include <polyhook2/Exceptions/BreakPointHook.hpp>

std::shared_ptr<PLH::BreakPointHook> bpHook;

NOINLINE int hookMe() {
	volatile int i = 0;
	i += 1;
	i += 2;
	return i;
}

NOINLINE int hookMeCallback() {
	auto protObj = bpHook->getProtectionObject();
	volatile int i = 0;
	i += 1;

	return hookMe();
}

int main(int, const char*[])
{
	bpHook = std::make_shared<PLH::BreakPointHook>(reinterpret_cast<char*>(&hookMe), reinterpret_cast<char*>(&hookMeCallback));

	if (!bpHook->hook())
	{
		std::cout << "[!] hook failed" << std::endl;
		return 1;
	}

	std::cout << "[+] calling hooked fn" << std::endl;

	// >>> Crash
	const int result = hookMe();

	if (result == 3) {
		std::cout << "[+] test succeeded" << std::endl;
	}

	bpHook->unHook();
	getchar();

	return 0;
}

Repository: https://github.com/automata172/polyhook-veh-crash

@stevemk14ebr
Copy link
Owner

Hi, thanks for reporting this and providing such a clean reproduction case! I've identified the bug, in a recent commit I introduced the ability to provide a custom filter callback so users gain more control over how the root exception handler works. This handler is invoked here:

if (m_onException.Invoke(ExceptionInfo, &code))

Unfortunately I somehow forgot the case of when users do not use this. What occurs is that an empty std::function eventually gets invoked which is a big no-no and that then throws a C++ exception. But this exception isn't obvious because we threw it from an exception handler, which tries to handle it by calling into the exception handler again, which throws another one! This cycle of throwing and catching occurs forever until the stack overflows and eventually is caught by _chkstack which crashes the program with an invalid read. Fun!

I will fix this soon. In the meantime as a workaround, please try to define an empty handler with this logic:

PLH::AVehHook::EventException() += [](EXCEPTION_POINTERS* exInfo, DWORD* returnCode) noexcept {
        DWORD exCode = exInfo->ExceptionRecord->ExceptionCode;

        if (exCode == EXCEPTION_BREAKPOINT) {
            printf("PolyHook2 about to handle breakpoint exception at %I64X\n", exInfo->ContextRecord->XIP);
        }

        // false tells it to continue as normal
        return false;
    };

@stevemk14ebr stevemk14ebr changed the title [Bug] PLH::BreakPointHook crashes the program when the function is called PLH::BreakPointHook crashes when exception handled Jan 9, 2021
@stevemk14ebr
Copy link
Owner

Resolved :)
image

ee07729

You will need to wait for microsoft to merge this PR before you can use vcpkg to install polyhook. Though you can mirror these changes locally in your own portfile and uninstall then reinstall polyhook via vcpkg to immediately get the update.

microsoft/vcpkg#15537

@stevemk14ebr
Copy link
Owner

Top notch report, thanks!

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

No branches or pull requests

2 participants