diff --git a/selfpatch/src/selfpatch.c b/selfpatch/src/selfpatch.c index 3b2cf6c..7229f7e 100644 --- a/selfpatch/src/selfpatch.c +++ b/selfpatch/src/selfpatch.c @@ -17,6 +17,11 @@ static void spslr_selfpatch_patch_ipins(void); static void reorder_object(void* dst, const void* src, uint32_t target); static int64_t spslr_calculate_ipin_value(uint32_t start); +static void* reorder_buffer = NULL; + +static void allocate_reorder_buffer(); +static void release_reorder_buffer(); + void spslr_selfpatch(void) { if (spslr_randomizer_init() < 0) spslr_env_panic("failed to initialize randomizer"); @@ -24,20 +29,46 @@ void spslr_selfpatch(void) { if (spslr_randomize() < 0) spslr_env_panic("failed to randomize targets"); + allocate_reorder_buffer(); spslr_selfpatch_patch_dpins(); + release_reorder_buffer(); + spslr_selfpatch_patch_ipins(); spslr_randomizer_clear(); } -void spslr_selfpatch_patch_dpins(void) { +static void allocate_reorder_buffer() { + if (reorder_buffer) + return; + + uint32_t max_target_size = 0; + for (uint32_t i = 0; i < spslr_target_cnt; i++) { + if (spslr_targets[i].size > max_target_size) + max_target_size = spslr_targets[i].size; + } + + reorder_buffer = spslr_env_malloc(max_target_size); + if (!reorder_buffer) + spslr_env_panic("failed to allocate reorder buffer"); +} + +static void release_reorder_buffer() { + if (!reorder_buffer) + return; + + spslr_env_free(reorder_buffer); + reorder_buffer = NULL; +} + +static void spslr_selfpatch_patch_dpins(void) { for (uint32_t dpidx = 0; dpidx < spslr_dpin_cnt; dpidx++) { const struct spslr_dpin* dp = &spslr_dpins[dpidx]; spslr_selfpatch_patch_dpin((void*)dp->addr, dp->target); } } -void reorder_object(void* dst, const void* src, uint32_t target) { +static void reorder_object(void* dst, const void* src, uint32_t target) { uint32_t field_count; if (spslr_randomizer_get_target(target, NULL, &field_count)) spslr_env_panic("failed to get target field count"); @@ -54,7 +85,7 @@ void reorder_object(void* dst, const void* src, uint32_t target) { } } -void spslr_selfpatch_patch_dpin(void* addr, uint32_t target) { +static void spslr_selfpatch_patch_dpin(void* addr, uint32_t target) { #ifdef SPSLR_SANITY_CHECK if (target >= spslr_target_cnt) spslr_env_panic("dpin refers to invalid target"); @@ -62,16 +93,12 @@ void spslr_selfpatch_patch_dpin(void* addr, uint32_t target) { const struct spslr_target* t = &spslr_targets[target]; - void* reorder_buffer = spslr_env_malloc(t->size); spslr_env_memset(reorder_buffer, 0, t->size); reorder_object(reorder_buffer, addr, target); - spslr_env_poke_data(addr, reorder_buffer, t->size); - - spslr_env_free(reorder_buffer); } -void spslr_selfpatch_patch_ipins(void) { +static void spslr_selfpatch_patch_ipins(void) { for (uint32_t ipidx = 0; ipidx < spslr_ipin_cnt; ipidx++) { const struct spslr_ipin* ip = &spslr_ipins[ipidx]; @@ -98,7 +125,7 @@ void spslr_selfpatch_patch_ipins(void) { } } -int64_t spslr_calculate_ipin_value(uint32_t start) { +static int64_t spslr_calculate_ipin_value(uint32_t start) { int64_t res = 0; uint32_t pc = start;