From 10e56ffd473a2a388dbb690f074ce02e77a2b345 Mon Sep 17 00:00:00 2001 From: York Jasper Niebuhr Date: Sun, 26 Oct 2025 22:06:03 +0100 Subject: [PATCH] selfpatch instruction dispatcher --- selfpatch/src/selfpatch.c | 53 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/selfpatch/src/selfpatch.c b/selfpatch/src/selfpatch.c index b5486ae..2aa307c 100644 --- a/selfpatch/src/selfpatch.c +++ b/selfpatch/src/selfpatch.c @@ -4,14 +4,59 @@ #include +// TODO +static int spslr_target(uint32_t uid, uint32_t size, uint32_t fieldcnt) { return 0; } +static int spslr_field(uint32_t offset, uint32_t size, uint32_t flags) { return 0; } +static int spslr_randomize(uint32_t target) { return 0; } +static int spslr_mprot(void* base, uint32_t pagecnt, uint8_t perm) { return 0; } +static int spslr_ipatch(void* ptr, uint32_t target, uint32_t field) { return 0; } +static int spslr_dpatch(void* ptr, uint32_t target) { return 0; } + /* -To allow ASLR, all patcher addresses are relative to &__spslr_program +Postprocessing tool patches the value of __spslr_program to point to the SPSLR program section. +With ASLR, there are 2 options to make it function correctly: + 1. Make sure __spslr_program is relocated with program image shift (preferred) + 2. __spslr_program = spslr_ptr_absolute((uint64_t)__spslr_program) and postprocessor inserts relative value (kinda weird) */ -const uint8_t* __spslr_program = NULL; +static const uint8_t* __spslr_program = NULL; + +static void* spslr_ptr_absolute(uint64_t relative) { + // To allow ASLR, all patcher addresses are relative to &__spslr_program + return ((uint8_t*)&__spslr_program) + relative; +} static int spslr_do(const struct SPSLR_INST* inst) { - // TODO -> dispatch different instructions, make args/pointers absolute - return 0; + if (!inst) + return -1; + + static uint32_t pending_fields = 0; + + if (pending_fields) { + if (inst->opcode != SPSLR_FIELD) { + fprintf(stderr, "spslr_do encountered non field instruction where a field instruction was expected\n"); + return -1; + } + + pending_fields--; + } + + switch (inst->opcode) { + case SPSLR_TARGET: + pending_fields = inst->op2.target_fieldcnt; + return spslr_target(inst->op0.target_uid, inst->op1.target_size, inst->op2.target_fieldcnt); + case SPSLR_FIELD: + return spslr_field(inst->op0.field_offset, inst->op1.field_size, inst->op2.field_flags); + case SPSLR_RANDOMIZE: + return spslr_randomize(inst->op0.randomize_target); + case SPSLR_MPROT: + return spslr_mprot(spslr_ptr_absolute(inst->op0.mprot_ptr), inst->op1.mprot_pagecnt, inst->op2.mprot_perm); + case SPSLR_IPATCH: + return spslr_ipatch(spslr_ptr_absolute(inst->op0.ipatch_ptr), inst->op1.ipatch_target, inst->op2.ipatch_field); + case SPSLR_DPATCH: + return spslr_dpatch(spslr_ptr_absolute(inst->op0.dpatch_ptr), inst->op1.dpatch_target); + default: + return -1; + } } void spslr_selfpatch() {