13 const uint8_t original[] = {0x10, 0x20, 0x30, 0x40};
14 const uint8_t patch[] = {0xAA, 0xBB, 0xCC, 0xDD};
22 assert_non_null(hook);
26 assert_memory_equal(
patch_target, original,
sizeof(original));
32 void *original = (
void *)0x11112222u;
33 void *replacement = (
void *)0x33334444u;
34 void *out_original =
NULL;
42 assert_non_null(hook);
43 assert_ptr_equal(out_original, original);
54 uint8_t second = 0x22;
55 const uint8_t first_patch = 0xA1;
56 const uint8_t second_patch = 0xB2;
66 assert_non_null(first_hook);
73 assert_non_null(second_hook);
77 assert_int_equal(first, 0x11);
78 assert_int_equal(second, second_patch);
81 assert_int_equal(second, 0x22);
88 const uint8_t patch = 0x66;
90 assert_non_null(hook);
91 assert_int_equal(
target, patch);
94 assert_int_equal(
target, 0x55);
97 assert_non_null(second_hook);
98 assert_int_equal(
target, patch);
100 assert_int_equal(
target, 0x55);
106 uint8_t
target[4] = {0x10, 0x20, 0x30, 0x40};
107 const uint8_t first_patch[] = {0xAA, 0xBB};
108 const uint8_t overlapping_patch[] = {0xCC, 0xDD};
115 assert_non_null(first_hook);
116 assert_memory_equal(&
target[1], first_patch,
sizeof(first_patch));
121 sizeof(overlapping_patch)
123 assert_null(overlapping_hook);
124 assert_int_equal(
target[2], 0xBB);
127 assert_memory_equal(
target, ((uint8_t[]){0x10, 0x20, 0x30, 0x40}),
sizeof(
target));
137 volatile int extra = 7;
138 return value + extra;
164 assert_int_equal(hook_target(5), 12);
167 (uintptr_t)hook_target,
172 assert_non_null(hook_a);
176 (uintptr_t)hook_target,
181 assert_non_null(hook_b);
184 assert_int_equal(hook_target(5), 122);
192 assert_int_equal(hook_target(5), 22);
198 assert_int_equal(hook_target(5), 12);
const DTTR_BackendState * state
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
DTTR_Graphics_COM_DirectDrawSurface7 DWORD DWORD void void DWORD flags DTTR_Graphics_COM_DirectDrawSurface7 void void *cb void * target
static const DTTR_TestCase TEST_CASES[]
#define DTTR_TEST_ARRAY_COUNT(TESTS)
#define DTTR_TEST_MAIN(TESTS)
static uint8_t patch_target[4]
DTTR_Core_Hook * DTTR_Core_HookAttachPointer(uintptr_t addr, void *new_value, void **out_original)
DTTR_Core_Hook * DTTR_Core_HookAttachFunction(uintptr_t addr, int prologue_size, void *handler, void **out_original)
DTTR_Core_Hook * DTTR_Core_HookPatchBytes(uintptr_t addr, const uint8_t *bytes, size_t size)
void DTTR_Core_HookCleanupAll()
Detach all remaining hooks and free the sigscan cache.
void DTTR_Core_HookDetach(DTTR_Core_Hook *hook)
void DTTR_Core_HookDetachOwner(void *owner)
void * DTTR_Core_HookSetOwner(void *owner)
static void test_owner_detach_only_detaches_matching_owner(void **state)
static void * pointer_target
int(* hook_target_fn)(int value)
static void test_patch_bytes_detach_restores_original(void **state)
static void chain_log(int id)
static int chain_call_log[2]
static void test_pointer_hook_detach_restores_original(void **state)
static void test_overlapping_byte_patches_are_rejected(void **state)
static void test_function_hooks_chain_and_detach(void **state)
static int chain_detour_b(int value)
static hook_target_fn chain_original_a
static hook_target_fn chain_original_b
static size_t chain_call_count
__attribute__((noinline))
static void test_cleanup_all_restores_hooks_and_allows_reuse(void **state)
static int chain_detour_a(int value)