Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ option(SAFETYHOOK_BUILD_EXAMPLES "" OFF)
option(SAFETYHOOK_AMALGAMATE "" OFF)
option(SAFETYHOOK_FETCH_ZYDIS "" ON)
option(SAFETYHOOK_USE_CXXMODULES "" OFF)
option(SAFETYHOOK_BUILD_MODULE "" OFF)

project(safetyhook)

Expand Down Expand Up @@ -268,6 +269,40 @@ if(SAFETYHOOK_AMALGAMATE) # amalgamate
target_sources(amalgamation PRIVATE ${amalgamation_SOURCES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${amalgamation_SOURCES})

endif()
# Target: safetyhook-module
if(SAFETYHOOK_BUILD_MODULE) # build-module
set(safetyhook-module_SOURCES
"module/safetyhook.cppm"
cmake.toml
)

add_library(safetyhook-module STATIC)

target_sources(safetyhook-module PRIVATE ${safetyhook-module_SOURCES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${safetyhook-module_SOURCES})

add_library(safetyhook::safetyhook-module ALIAS safetyhook-module)
target_link_libraries(safetyhook-module PUBLIC
safetyhook::safetyhook
)

set(CMKR_TARGET safetyhook-module)
target_sources(safetyhook-module PUBLIC
FILE_SET CXX_MODULES
FILES module/safetyhook.cppm
)

install(
TARGETS safetyhook-module
EXPORT safetyhook-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/safetyhook
)

endif()
# Target: example-minimal
if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
Expand Down Expand Up @@ -420,6 +455,43 @@ if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
endif()

endif()
# Target: example-module
if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
if(SAFETYHOOK_BUILD_MODULE) # build-module
set(example-module_SOURCES
"example/module.cpp"
cmake.toml
)

add_executable(example-module)

target_sources(example-module PRIVATE ${example-module_SOURCES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${example-module_SOURCES})

target_compile_features(example-module PRIVATE
cxx_std_23
)

target_link_libraries(example-module PRIVATE
safetyhook::safetyhook
)

target_link_libraries(example-module PRIVATE
safetyhook::safetyhook-module
)

set_target_properties(example-module PROPERTIES
CXX_SCAN_FOR_MODULES
ON
)

get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
if(NOT CMKR_VS_STARTUP_PROJECT)
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT example-module)
endif()

endif()
endif()
# Target: test
if(SAFETYHOOK_BUILD_TEST) # build-test
set(test_SOURCES
Expand Down
32 changes: 32 additions & 0 deletions cmake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SAFETYHOOK_BUILD_EXAMPLES = false
SAFETYHOOK_AMALGAMATE = false
SAFETYHOOK_FETCH_ZYDIS = true
SAFETYHOOK_USE_CXXMODULES = false
SAFETYHOOK_BUILD_MODULE = false

[conditions]
build-docs = "SAFETYHOOK_BUILD_DOCS"
Expand All @@ -23,6 +24,7 @@ amalgamate = "SAFETYHOOK_AMALGAMATE"
build-amalgamate-test = "SAFETYHOOK_BUILD_TEST AND SAFETYHOOK_AMALGAMATE"
fetch-zydis = "SAFETYHOOK_FETCH_ZYDIS"
find-zydis = "(NOT SAFETYHOOK_FETCH_ZYDIS)"
build-module = "SAFETYHOOK_BUILD_MODULE"

[fetch-content.ut]
condition = "build-test"
Expand Down Expand Up @@ -162,6 +164,29 @@ add_custom_command(
add_custom_target(Amalgamate ALL DEPENDS ${AMALGAMATED_FILE} ${AMALGAMATED_HEADER})
"""

[target.safetyhook-module]
condition = "build-module"
type = "static"
sources = ["module/safetyhook.cppm"]
link-libraries = ["safetyhook::safetyhook"]
alias = "safetyhook::safetyhook-module"
cmake-after = """
target_sources(safetyhook-module PUBLIC
FILE_SET CXX_MODULES
FILES module/safetyhook.cppm
)

install(
TARGETS safetyhook-module
EXPORT safetyhook-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/safetyhook
)
"""

[template.example]
condition = "build-examples"
type = "executable"
Expand Down Expand Up @@ -198,6 +223,13 @@ sources = ["example/dll.cpp"]
type = "example"
sources = ["example/vmthook.cpp"]

[target.example-module]
condition = "build-module"
type = "example"
sources = ["example/module.cpp"]
link-libraries = ["safetyhook::safetyhook-module"]
properties.CXX_SCAN_FOR_MODULES = true

[target.test]
condition = "build-test"
type = "executable"
Expand Down
30 changes: 30 additions & 0 deletions example/module.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <print>

#include <safetyhook/common.hpp> // SAFETYHOOK_NOINLINE macro

import safetyhook;

SAFETYHOOK_NOINLINE int add(int x, int y) {
return x + y;
}

SafetyHookInline g_add_hook{};

int hook_add(int x, int y) {
return g_add_hook.call<int>(x * 2, y * 2);
}

int main() {
std::println("unhooked add(2, 3) = {}", add(2, 3));

// Create a hook on add.
g_add_hook = safetyhook::create_inline(reinterpret_cast<void*>(add), reinterpret_cast<void*>(hook_add));

std::println("hooked add(3, 4) = {}", add(3, 4));

g_add_hook = {};

std::println("unhooked add(5, 6) = {}", add(5, 6));

return 0;
}
8 changes: 4 additions & 4 deletions include/safetyhook/os.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ struct VmAccess {
}
};

constexpr VmAccess VM_ACCESS_R{true, false, false};
constexpr VmAccess VM_ACCESS_RW{true, true, false};
constexpr VmAccess VM_ACCESS_RX{true, false, true};
constexpr VmAccess VM_ACCESS_RWX{true, true, true};
inline constexpr VmAccess VM_ACCESS_R{true, false, false};
inline constexpr VmAccess VM_ACCESS_RW{true, true, false};
inline constexpr VmAccess VM_ACCESS_RX{true, false, true};
inline constexpr VmAccess VM_ACCESS_RWX{true, true, true};

struct VmBasicInfo {
uint8_t* address;
Expand Down
75 changes: 75 additions & 0 deletions module/safetyhook.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
module;

#include <safetyhook.hpp>

export module safetyhook;

export {
namespace safetyhook {

// allocator.hpp
using safetyhook::Allocation;
using safetyhook::Allocator;

// context.hpp
using safetyhook::Context;
using safetyhook::Context32;
using safetyhook::Context64;
using safetyhook::Xmm;

// easy.hpp
using safetyhook::create_inline;
using safetyhook::create_mid;
using safetyhook::create_vm;
using safetyhook::create_vmt;

// inline_hook.hpp
using safetyhook::InlineHook;

// mid_hook.hpp
using safetyhook::MidHook;
using safetyhook::MidHookFn;

// os.hpp
using safetyhook::fix_ip;
using safetyhook::OsError;
using safetyhook::system_info;
using safetyhook::SystemInfo;
using safetyhook::ThreadContext;
using safetyhook::trap_threads;
using safetyhook::VM_ACCESS_R;
using safetyhook::VM_ACCESS_RW;
using safetyhook::VM_ACCESS_RWX;
using safetyhook::VM_ACCESS_RX;
using safetyhook::vm_allocate;
using safetyhook::vm_free;
using safetyhook::vm_is_executable;
using safetyhook::vm_is_readable;
using safetyhook::vm_is_writable;
using safetyhook::vm_protect;
using safetyhook::vm_query;
using safetyhook::VmAccess;
using safetyhook::VmBasicInfo;

// utility.hpp
using safetyhook::address_cast;
using safetyhook::align_down;
using safetyhook::align_up;
using safetyhook::is_executable;
using safetyhook::store;
using safetyhook::unprotect;
using safetyhook::UnprotectMemory;

// vmt_hook.hpp
using safetyhook::VmHook;
using safetyhook::VmtHook;

} // namespace safetyhook

// safetyhook.hpp
using ::SafetyHookContext;
using ::SafetyHookInline;
using ::SafetyHookMid;
using ::SafetyHookVm;
using ::SafetyHookVmt;
}
Loading