diff --git a/selfpatch/CMakeLists.txt b/selfpatch/CMakeLists.txt index acd075e..5b26d44 100644 --- a/selfpatch/CMakeLists.txt +++ b/selfpatch/CMakeLists.txt @@ -1,8 +1,20 @@ +add_library(spslr_randomizer STATIC + src/randomizer.c +) + +target_include_directories(spslr_randomizer PUBLIC + $ +) + add_library(spslr_selfpatch STATIC src/selfpatch.c src/randomizer.c src/env.c) +target_link_libraries(spslr_selfpatch PUBLIC spslr_randomizer) + target_include_directories(spslr_selfpatch PUBLIC $ $ ) target_include_directories(spslr_patchcompile PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) # For spslr_list.h + +add_subdirectory(test) diff --git a/selfpatch/src/randomizer.c b/selfpatch/src/randomizer.c index a162edd..d51a01c 100644 --- a/selfpatch/src/randomizer.c +++ b/selfpatch/src/randomizer.c @@ -60,10 +60,13 @@ int spslr_randomizer_get_target(uint32_t target, uint32_t* size, uint32_t* field } int spslr_randomizer_get_field(uint32_t target, uint32_t field, int field_idx_mode, - uint32_t* size, uint32_t* offset, uint32_t* initial_offset) { + struct spslr_randomizer_field_info* info) { if (target >= spslr_target_cnt) return -1; + if (!info) + return 0; + const struct spslr_target* t = &spslr_targets[target]; if (field >= t->fieldcnt) @@ -85,14 +88,11 @@ int spslr_randomizer_get_field(uint32_t target, uint32_t field, int field_idx_mo return -1; } - if (size) - *size = of->size; - - if (offset) - *offset = rf->offset; - - if (initial_offset) - *initial_offset = of->offset; + info->size = of->size; + info->offset = rf->offset; + info->initial_offset = of->offset; + info->alignment = of->alignment; + info->flags = of->flags; return 0; } diff --git a/selfpatch/src/randomizer.h b/selfpatch/src/randomizer.h index 34dbb76..d2bafaf 100644 --- a/selfpatch/src/randomizer.h +++ b/selfpatch/src/randomizer.h @@ -6,12 +6,20 @@ #define SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL 1 #define SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL 2 +struct spslr_randomizer_field_info { + uint32_t size; + uint32_t offset; + uint32_t initial_offset; + uint32_t alignment; + uint32_t flags; +}; + int spslr_randomizer_init(); int spslr_randomize(); void spslr_randomizer_clear(); int spslr_randomizer_get_target(uint32_t target, uint32_t* size, uint32_t* fieldcnt); int spslr_randomizer_get_field(uint32_t target, uint32_t field, int field_idx_mode, - uint32_t* size, uint32_t* offset, uint32_t* initial_offset); + struct spslr_randomizer_field_info* info); #endif diff --git a/selfpatch/src/selfpatch.c b/selfpatch/src/selfpatch.c index 7a02aee..3b2cf6c 100644 --- a/selfpatch/src/selfpatch.c +++ b/selfpatch/src/selfpatch.c @@ -46,12 +46,11 @@ void reorder_object(void* dst, const void* src, uint32_t target) { uint8_t* dst_countable = (uint8_t*)dst; for (uint32_t i = 0; i < field_count; i++) { - uint32_t field_offset, field_size, field_initial_offset; - if (spslr_randomizer_get_field(target, i, SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL, - &field_size, &field_offset, &field_initial_offset)) + struct spslr_randomizer_field_info finfo; + if (spslr_randomizer_get_field(target, i, SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL, &finfo)) spslr_env_panic("failed to get ordered field descriptor"); - spslr_env_memcpy(dst_countable + field_offset, src_countable + field_initial_offset, field_size); + spslr_env_memcpy(dst_countable + finfo.offset, src_countable + finfo.initial_offset, finfo.size); } } @@ -118,46 +117,42 @@ int64_t spslr_calculate_ipin_value(uint32_t start) { break; case SPSLR_IPIN_OP_ADD_INITIAL_OFFSET: { - uint32_t initial_offset; + struct spslr_randomizer_field_info finfo; if (spslr_randomizer_get_field(op->op0.add_initial_offset_target, - op->op1.add_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, - NULL, NULL, &initial_offset)) + op->op1.add_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo)) spslr_env_panic("failed to get initial field offset"); - res += initial_offset; + res += finfo.initial_offset; } break; case SPSLR_IPIN_OP_ADD_OFFSET: { - uint32_t offset; + struct spslr_randomizer_field_info finfo; if (spslr_randomizer_get_field(op->op0.add_initial_offset_target, - op->op1.add_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, - NULL, &offset, NULL)) + op->op1.add_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo)) spslr_env_panic("failed to get initial field offset"); - res += offset; + res += finfo.offset; } break; case SPSLR_IPIN_OP_SUB_INITIAL_OFFSET: { - uint32_t initial_offset; + struct spslr_randomizer_field_info finfo; if (spslr_randomizer_get_field(op->op0.add_initial_offset_target, - op->op1.sub_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, - NULL, NULL, &initial_offset)) + op->op1.sub_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo)) spslr_env_panic("failed to get initial field offset"); - res -= initial_offset; + res -= finfo.initial_offset; } break; case SPSLR_IPIN_OP_SUB_OFFSET: { - uint32_t offset; + struct spslr_randomizer_field_info finfo; if (spslr_randomizer_get_field(op->op0.add_initial_offset_target, - op->op1.sub_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, - NULL, &offset, NULL)) + op->op1.sub_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL, &finfo)) spslr_env_panic("failed to get initial field offset"); - res -= offset; + res -= finfo.offset; } break; case SPSLR_IPIN_OP_ADD_CONST: diff --git a/selfpatch/src/spslr_list_link.h b/selfpatch/src/spslr_list_link.h index 0486861..0418a3f 100644 --- a/selfpatch/src/spslr_list_link.h +++ b/selfpatch/src/spslr_list_link.h @@ -3,19 +3,19 @@ #include "spslr_list.h" -extern uint32_t spslr_target_cnt; -extern struct spslr_target spslr_targets[]; +extern const uint32_t spslr_target_cnt; +extern const struct spslr_target spslr_targets[]; -extern uint32_t spslr_target_field_cnt; -extern struct spslr_target_field spslr_target_fields[]; +extern const uint32_t spslr_target_field_cnt; +extern const struct spslr_target_field spslr_target_fields[]; -extern uint32_t spslr_ipin_cnt; -extern struct spslr_ipin spslr_ipins[]; +extern const uint32_t spslr_ipin_cnt; +extern const struct spslr_ipin spslr_ipins[]; -extern uint32_t spslr_ipin_op_cnt; -extern struct spslr_ipin_op spslr_ipin_ops[]; +extern const uint32_t spslr_ipin_op_cnt; +extern const struct spslr_ipin_op spslr_ipin_ops[]; -extern uint32_t spslr_dpin_cnt; -extern struct spslr_dpin spslr_dpins[]; +extern const uint32_t spslr_dpin_cnt; +extern const struct spslr_dpin spslr_dpins[]; #endif diff --git a/selfpatch/test/CMakeLists.txt b/selfpatch/test/CMakeLists.txt new file mode 100644 index 0000000..daf43cd --- /dev/null +++ b/selfpatch/test/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(spslr_randomizer_test randomizer_test.c) +target_link_libraries(spslr_randomizer_test PRIVATE spslr_randomizer) diff --git a/selfpatch/test/randomizer_test.c b/selfpatch/test/randomizer_test.c new file mode 100644 index 0000000..73db796 --- /dev/null +++ b/selfpatch/test/randomizer_test.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +#include +#include + +void *spslr_env_malloc(size_t size) { + return malloc(size); +} + +void spslr_env_free(void *ptr) { + free(ptr); +} + +uint32_t spslr_env_random_u32(void) { + return ((uint32_t)rand() << 16) ^ (uint32_t)rand(); +} + +const uint32_t spslr_target_cnt = 1; +const uint32_t spslr_target_field_cnt = 4; + +const struct spslr_target spslr_targets[] = { + { + .size = 24, + .fieldcnt = 4, + .fieldoff = 0, + }, +}; + +const struct spslr_target_field spslr_target_fields[] = { + { .offset = 0, .size = 4, .alignment = 4, .flags = 0 }, + { .offset = 4, .size = 4, .alignment = 4, .flags = 0 }, + { .offset = 8, .size = 4, .alignment = 4, .flags = 0 }, + { .offset = 16, .size = 8, .alignment = 8, .flags = 0 }, +}; + +static int check_target(uint32_t tidx) { + uint32_t tsize, fieldcnt; + + if (spslr_randomizer_get_target(tidx, &tsize, &fieldcnt) < 0) + return -1; + + uint32_t cur_end = 0; + + for (uint32_t i = 0; i < fieldcnt; i++) { + struct spslr_randomizer_field_info finfo; + if (spslr_randomizer_get_field(tidx, i, SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL, &finfo) < 0) + return -1; + + if (finfo.offset < cur_end) + return -1; + + if (finfo.offset % finfo.alignment != 0) + return -1; + + if ((finfo.flags & SPSLR_FLAG_FIELD_FIXED) && finfo.offset != finfo.initial_offset) + return -1; + + if (finfo.offset + finfo.size > tsize) + return -1; + + cur_end = finfo.offset + finfo.size; + } + + return 0; +} + +int main(void) { + srand((unsigned)time(NULL)); + + for (uint32_t iter = 0; iter < 1000000; iter++) { + if (spslr_randomizer_init() < 0) { + fprintf(stderr, "init failed\n"); + return 1; + } + + if (spslr_randomize() < 0) { + fprintf(stderr, "randomize failed at iter %u\n", iter); + return 1; + } + + for (uint32_t tidx = 0; tidx < spslr_target_cnt; tidx++) { + if (check_target(tidx) < 0) { + fprintf(stderr, "check failed at iter %u target %u\n", iter, tidx); + return 1; + } + } + + spslr_randomizer_clear(); + } + + printf("ok: 1000000 iterations\n"); + return 0; +}