// Copyright (c) Lysann Tranvouez. All rights reserved. #include #include #include "lib_function.h" static int (*realLibFunction)() = libFunction; static int libFunctionDetourCounter = 0; static int libFunctionDetour() { libFunctionDetourCounter++; return 94; } TEST_CASE( "Overriding custom function in dylib", "[attach][detach][dylib]" ) { libFunctionCounter = 0; libFunctionDetourCounter = 0; SECTION( "attaching installs a detour" ) { REQUIRE( realLibFunction == libFunction ); REQUIRE( libFunction() == 42 ); REQUIRE( libFunctionCounter == 1 ); REQUIRE( libFunctionDetourCounter == 0 ); REQUIRE( detour_transaction_begin() == err_none ); SECTION( "attach + transaction_commit" ) { REQUIRE( detour_attach(reinterpret_cast(&realLibFunction), reinterpret_cast(libFunctionDetour)) == err_none ); CHECK( detour_transaction_commit() == err_none ); } SECTION( "attach_and_commit" ) { CHECK( detour_attach_and_commit(reinterpret_cast(&realLibFunction), reinterpret_cast(libFunctionDetour)) == err_none ); } CHECK( realLibFunction != libFunction ); CHECK( libFunctionCounter == 1 ); CHECK( libFunctionDetourCounter == 0 ); CHECK( libFunction() == 94 ); CHECK( libFunctionCounter == 1 ); CHECK( libFunctionDetourCounter == 1 ); // clean up REQUIRE( detour_transaction_begin() == err_none ); CHECK( detour_detach_and_commit(reinterpret_cast(&realLibFunction), reinterpret_cast(libFunctionDetour)) == err_none ); } SECTION( "detaching in separate transaction removes detour" ) { REQUIRE( detour_transaction_begin() == err_none ); REQUIRE( detour_attach_and_commit(reinterpret_cast(&realLibFunction), reinterpret_cast(libFunctionDetour)) == err_none ); REQUIRE( realLibFunction != libFunction ); REQUIRE( detour_transaction_begin() == err_none ); SECTION( "detach + transaction_commit" ) { REQUIRE( detour_detach(reinterpret_cast(&realLibFunction), reinterpret_cast(libFunctionDetour)) == err_none ); CHECK( detour_transaction_commit() == err_none ); } SECTION( "detach_and_commit" ) { CHECK( detour_detach_and_commit(reinterpret_cast(&realLibFunction), reinterpret_cast(libFunctionDetour)) == err_none ); } CHECK( realLibFunction == libFunction ); CHECK( libFunctionCounter == 0 ); CHECK( libFunctionDetourCounter == 0 ); CHECK( libFunction() == 42 ); CHECK( libFunctionCounter == 1 ); CHECK( libFunctionDetourCounter == 0 ); } }