Updated randomizer towards kernel implementation
This commit is contained in:
parent
c336402225
commit
422c8d7562
@ -1,4 +1,4 @@
|
|||||||
add_library(spslr_selfpatch STATIC src/selfpatch.c src/targets.c src/env.c)
|
add_library(spslr_selfpatch STATIC src/selfpatch.c src/randomizer.c src/env.c)
|
||||||
|
|
||||||
target_include_directories(spslr_selfpatch PUBLIC
|
target_include_directories(spslr_selfpatch PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#define PAGE_MASK ~(0x1000ull - 1)
|
#define PAGE_MASK ~(0x1000ull - 1)
|
||||||
|
|
||||||
@ -107,3 +108,14 @@ void spslr_env_memcpy(void* dst, const void* src, uint32_t n) {
|
|||||||
memcpy(dst, src, n);
|
memcpy(dst, src, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rand_initialized = 0;
|
||||||
|
|
||||||
|
uint32_t spslr_env_random_u32() {
|
||||||
|
if (!rand_initialized) {
|
||||||
|
srand(time(NULL));
|
||||||
|
rand_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32_t)rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,5 +13,6 @@ void spslr_env_free(void* ptr);
|
|||||||
void spslr_env_poke_data(void* dst, const void* src, uint32_t n);
|
void spslr_env_poke_data(void* dst, const void* src, uint32_t n);
|
||||||
void spslr_env_memset(void* dst, int v, uint32_t n);
|
void spslr_env_memset(void* dst, int v, uint32_t n);
|
||||||
void spslr_env_memcpy(void* dst, const void* src, uint32_t n);
|
void spslr_env_memcpy(void* dst, const void* src, uint32_t n);
|
||||||
|
uint32_t spslr_env_random_u32();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
352
selfpatch/src/randomizer.c
Normal file
352
selfpatch/src/randomizer.c
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
#include "randomizer.h"
|
||||||
|
|
||||||
|
#include "spslr_list_link.h"
|
||||||
|
#include "env.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct Field {
|
||||||
|
uint32_t offset; /* Final field offset -> fields[i].offset = offset of field i in final layout */
|
||||||
|
uint32_t oidx; /* Original field idx -> fields[i].oidx = original position of field i in final layout */
|
||||||
|
uint32_t fidx; /* Final field idx -> fields[i].fidx = randomized/final position of original field i */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct Field* fields;
|
||||||
|
|
||||||
|
int spslr_randomizer_init() {
|
||||||
|
fields = (struct Field*)spslr_env_malloc(sizeof(struct Field) * spslr_target_field_cnt);
|
||||||
|
if (!fields)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (uint32_t tidx = 0; tidx < spslr_target_cnt; tidx++) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[tidx];
|
||||||
|
|
||||||
|
for (uint32_t fidx = 0; fidx < t->fieldcnt; fidx++) {
|
||||||
|
uint32_t gfidx = t->fieldoff + fidx;
|
||||||
|
|
||||||
|
const struct spslr_target_field* srcf = &spslr_target_fields[gfidx];
|
||||||
|
struct Field* dstf = &fields[gfidx];
|
||||||
|
|
||||||
|
dstf->offset = srcf->offset;
|
||||||
|
dstf->oidx = fidx;
|
||||||
|
dstf->fidx = fidx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spslr_randomizer_clear() {
|
||||||
|
if (!fields)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spslr_env_free(fields);
|
||||||
|
fields = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spslr_randomizer_get_target(uint32_t target, uint32_t* size, uint32_t* fieldcnt) {
|
||||||
|
if (target >= spslr_target_cnt)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
*size = t->size;
|
||||||
|
|
||||||
|
if (fieldcnt)
|
||||||
|
*fieldcnt = t->fieldcnt;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (target >= spslr_target_cnt)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
|
||||||
|
if (field >= t->fieldcnt)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const struct spslr_target_field* of = NULL;
|
||||||
|
const struct Field* rf = NULL;
|
||||||
|
|
||||||
|
switch (field_idx_mode) {
|
||||||
|
case SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL:
|
||||||
|
of = &spslr_target_fields[t->fieldoff + field];
|
||||||
|
rf = &fields[t->fieldoff + fields[t->fieldoff + field].fidx];
|
||||||
|
break;
|
||||||
|
case SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL:
|
||||||
|
of = &spslr_target_fields[t->fieldoff + fields[t->fieldoff + field].oidx];
|
||||||
|
rf = &fields[t->fieldoff + field];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
*size = of->size;
|
||||||
|
|
||||||
|
if (offset)
|
||||||
|
*offset = rf->offset;
|
||||||
|
|
||||||
|
if (initial_offset)
|
||||||
|
*initial_offset = of->offset;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RANDOMIZATION CODE
|
||||||
|
|
||||||
|
struct ShuffleRegion {
|
||||||
|
uint32_t begin;
|
||||||
|
uint32_t end;
|
||||||
|
uint32_t fill_begin;
|
||||||
|
uint32_t fill_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t rand_u32(void);
|
||||||
|
static struct Field* get_rfield(uint32_t target, uint32_t final_idx);
|
||||||
|
static const struct spslr_target_field* get_ofield(uint32_t target, uint32_t orig_idx);
|
||||||
|
static void get_origin_region(uint32_t target, uint32_t final_idx, struct ShuffleRegion* region);
|
||||||
|
static int pick_shuffle_option(uint32_t target, uint32_t origin_final_idx,
|
||||||
|
const struct ShuffleRegion* origin, uint32_t alignment, uint32_t* selected);
|
||||||
|
static void do_swap(uint32_t target, uint32_t origin_final_idx,
|
||||||
|
const struct ShuffleRegion* origin_region, uint32_t new_offset);
|
||||||
|
static void shuffle_one_target(uint32_t target);
|
||||||
|
static void shuffle_target(uint32_t target);
|
||||||
|
|
||||||
|
static uint32_t rand_u32(void) {
|
||||||
|
return spslr_env_random_u32();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct Field* get_rfield(uint32_t target, uint32_t final_idx) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
return &fields[t->fieldoff + final_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct spslr_target_field* get_ofield(uint32_t target, uint32_t orig_idx) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
return &spslr_target_fields[t->fieldoff + orig_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_origin_region(uint32_t target, uint32_t final_idx, struct ShuffleRegion* region) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
const struct Field* rf = get_rfield(target, final_idx);
|
||||||
|
const struct spslr_target_field* of = get_ofield(target, rf->oidx);
|
||||||
|
|
||||||
|
region->fill_begin = rf->offset;
|
||||||
|
region->fill_end = rf->offset + of->size;
|
||||||
|
|
||||||
|
if (final_idx == 0) {
|
||||||
|
region->begin = 0;
|
||||||
|
} else {
|
||||||
|
const struct Field* pred_rf = get_rfield(target, final_idx - 1);
|
||||||
|
const struct spslr_target_field* pred_of = get_ofield(target, pred_rf->oidx);
|
||||||
|
region->begin = pred_rf->offset + pred_of->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (final_idx + 1 >= t->fieldcnt) {
|
||||||
|
region->end = t->size;
|
||||||
|
} else {
|
||||||
|
const struct Field* succ_rf = get_rfield(target, final_idx + 1);
|
||||||
|
region->end = succ_rf->offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int option_is_valid(uint32_t target, uint32_t origin_final_idx, const struct ShuffleRegion* origin, uint32_t offset) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
const struct spslr_target_field* origin_of =
|
||||||
|
get_ofield(target, get_rfield(target, origin_final_idx)->oidx);
|
||||||
|
|
||||||
|
// When placed at offset, field will occupy [offset, option_would_end)
|
||||||
|
uint32_t option_would_end = offset + origin_of->size;
|
||||||
|
if (option_would_end > t->size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Field may overlap with origin region. Moving field to offset truly frees:
|
||||||
|
// [true_origin_region_begin, true_origin_region_end)
|
||||||
|
uint32_t true_origin_region_begin = origin->begin;
|
||||||
|
uint32_t true_origin_region_end = origin->end;
|
||||||
|
|
||||||
|
if (offset <= origin->fill_begin && option_would_end > true_origin_region_begin)
|
||||||
|
true_origin_region_begin = option_would_end;
|
||||||
|
|
||||||
|
if (offset >= origin->fill_begin && offset < true_origin_region_end)
|
||||||
|
true_origin_region_end = offset;
|
||||||
|
|
||||||
|
// Iterate over fields in target region [offset, option_would_end] and see if they fit into true origin region
|
||||||
|
uint32_t origin_region_ptr = true_origin_region_begin;
|
||||||
|
for (uint32_t it = 0; it < t->fieldcnt; it++) {
|
||||||
|
const struct Field* rf = get_rfield(target, it);
|
||||||
|
const struct spslr_target_field* of = get_ofield(target, rf->oidx);
|
||||||
|
|
||||||
|
// The field being moved does not need to go into origin region
|
||||||
|
if (it == origin_final_idx)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Field ends before target region -> must not be moved to origin region
|
||||||
|
if (rf->offset + of->size <= offset)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Field starts after target region -> must not be moved to origin region
|
||||||
|
if (rf->offset >= option_would_end)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Fixed fields in target region unconditionally deny option
|
||||||
|
if (of->flags & SPSLR_FLAG_FIELD_FIXED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Field from target region must be moved to aligned position in origin region
|
||||||
|
if (origin_region_ptr % of->alignment != 0)
|
||||||
|
origin_region_ptr += of->alignment - (origin_region_ptr % of->alignment);
|
||||||
|
|
||||||
|
origin_region_ptr += of->size;
|
||||||
|
|
||||||
|
// Field does not fit into origin region -> option not possible
|
||||||
|
if (origin_region_ptr > true_origin_region_end)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pick_shuffle_option(uint32_t target, uint32_t origin_final_idx, const struct ShuffleRegion* origin,
|
||||||
|
uint32_t alignment, uint32_t* selected) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
uint32_t seen = 0;
|
||||||
|
|
||||||
|
for (uint32_t offset = 0; offset < t->size; offset += alignment) {
|
||||||
|
if (!option_is_valid(target, origin_final_idx, origin, offset))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Reservoir sampling -> uniform distribution with O(1) memory consumption
|
||||||
|
seen++;
|
||||||
|
if ((rand_u32() % seen) == 0)
|
||||||
|
*selected = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return seen ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_swap(uint32_t target, uint32_t origin_idx,
|
||||||
|
const struct ShuffleRegion* origin_region, uint32_t new_offset) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
int pulled = 0;
|
||||||
|
|
||||||
|
uint32_t option_fill_end = new_offset + (origin_region->fill_end - origin_region->fill_begin);
|
||||||
|
|
||||||
|
uint32_t true_origin_region_begin = origin_region->begin;
|
||||||
|
if (new_offset <= origin_region->fill_begin && option_fill_end > true_origin_region_begin)
|
||||||
|
true_origin_region_begin = option_fill_end;
|
||||||
|
|
||||||
|
uint32_t origin_oidx = get_rfield(target, origin_idx)->oidx;
|
||||||
|
|
||||||
|
uint32_t origin_region_ptr = true_origin_region_begin;
|
||||||
|
for (uint32_t it = 0; it < t->fieldcnt; it++) {
|
||||||
|
struct Field* itf = get_rfield(target, it);
|
||||||
|
|
||||||
|
if (itf->oidx == origin_oidx)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const struct spslr_target_field* itof = get_ofield(target, itf->oidx);
|
||||||
|
|
||||||
|
if (itf->offset + itof->size <= new_offset)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (itf->offset >= option_fill_end)
|
||||||
|
break;
|
||||||
|
|
||||||
|
uint32_t falign = itof->alignment;
|
||||||
|
if (origin_region_ptr % falign != 0)
|
||||||
|
origin_region_ptr += falign - (origin_region_ptr % falign);
|
||||||
|
|
||||||
|
if (!pulled) {
|
||||||
|
pulled = 1;
|
||||||
|
|
||||||
|
struct Field tmp = *get_rfield(target, it);
|
||||||
|
*get_rfield(target, it) = *get_rfield(target, origin_idx);
|
||||||
|
*get_rfield(target, origin_idx) = tmp;
|
||||||
|
|
||||||
|
get_rfield(target, it)->offset = new_offset;
|
||||||
|
|
||||||
|
get_rfield(target, origin_idx)->offset = origin_region_ptr;
|
||||||
|
origin_region_ptr += get_ofield(target, get_rfield(target, origin_idx)->oidx)->size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct Field tmp = *get_rfield(target, it);
|
||||||
|
|
||||||
|
if (origin_idx >= it) {
|
||||||
|
for (uint32_t pull_it = it + 1; pull_it <= origin_idx; pull_it++)
|
||||||
|
*get_rfield(target, pull_it - 1) = *get_rfield(target, pull_it);
|
||||||
|
|
||||||
|
*get_rfield(target, origin_idx) = tmp;
|
||||||
|
get_rfield(target, origin_idx)->offset = origin_region_ptr;
|
||||||
|
origin_region_ptr += get_ofield(target, get_rfield(target, origin_idx)->oidx)->size;
|
||||||
|
} else {
|
||||||
|
for (uint32_t pull_it = it; pull_it > origin_idx + (uint32_t)pulled; pull_it--)
|
||||||
|
*get_rfield(target, pull_it) = *get_rfield(target, pull_it - 1);
|
||||||
|
|
||||||
|
*get_rfield(target, origin_idx + (uint32_t)pulled) = tmp;
|
||||||
|
get_rfield(target, origin_idx + (uint32_t)pulled)->offset = origin_region_ptr;
|
||||||
|
origin_region_ptr += get_ofield(target, get_rfield(target, origin_idx + (uint32_t)pulled)->oidx)->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pulled++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rebuild original->final mapping for this target.
|
||||||
|
*/
|
||||||
|
for (uint32_t final_idx = 0; final_idx < t->fieldcnt; final_idx++) {
|
||||||
|
struct Field* rf = get_rfield(target, final_idx);
|
||||||
|
fields[t->fieldoff + rf->oidx].fidx = final_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shuffle_one_target(uint32_t target) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
if (t->fieldcnt == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t origin_final_idx = rand_u32() % t->fieldcnt;
|
||||||
|
struct Field* origin_rf = get_rfield(target, origin_final_idx);
|
||||||
|
const struct spslr_target_field* origin_of = get_ofield(target, origin_rf->oidx);
|
||||||
|
|
||||||
|
if (origin_of->flags & SPSLR_FLAG_FIELD_FIXED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct ShuffleRegion origin_region;
|
||||||
|
uint32_t selected_option;
|
||||||
|
|
||||||
|
get_origin_region(target, origin_final_idx, &origin_region);
|
||||||
|
|
||||||
|
if (pick_shuffle_option(target, origin_final_idx, &origin_region,
|
||||||
|
origin_of->alignment, &selected_option) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
do_swap(target, origin_final_idx, &origin_region, selected_option);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shuffle_target(uint32_t target) {
|
||||||
|
const struct spslr_target* t = &spslr_targets[target];
|
||||||
|
uint32_t shuffle_count = t->fieldcnt * 2;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < shuffle_count; i++)
|
||||||
|
shuffle_one_target(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spslr_randomize() {
|
||||||
|
if (!fields)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (uint32_t tidx = 0; tidx < spslr_target_cnt; tidx++)
|
||||||
|
shuffle_target(tidx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
17
selfpatch/src/randomizer.h
Normal file
17
selfpatch/src/randomizer.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef SPSLR_RANDOMIZER_H
|
||||||
|
#define SPSLR_RANDOMIZER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL 1
|
||||||
|
#define SPSLR_RANDOMIZER_FIELD_IDX_MODE_FINAL 2
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,7 +1,7 @@
|
|||||||
#include <spslr.h>
|
#include <spslr.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "targets.h"
|
#include "randomizer.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
|
|
||||||
#include "spslr_list_link.h"
|
#include "spslr_list_link.h"
|
||||||
@ -18,49 +18,16 @@ static void reorder_object(void* dst, const void* src, uint32_t target);
|
|||||||
static int64_t spslr_calculate_ipin_value(uint32_t start);
|
static int64_t spslr_calculate_ipin_value(uint32_t start);
|
||||||
|
|
||||||
void spslr_selfpatch(void) {
|
void spslr_selfpatch(void) {
|
||||||
seed_rand_time();
|
if (spslr_randomizer_init() < 0)
|
||||||
|
spslr_env_panic("failed to initialize randomizer");
|
||||||
|
|
||||||
|
if (spslr_randomize() < 0)
|
||||||
|
spslr_env_panic("failed to randomize targets");
|
||||||
|
|
||||||
spslr_selfpatch_load_targets();
|
|
||||||
spslr_selfpatch_randomize_targets();
|
|
||||||
spslr_selfpatch_patch_dpins();
|
spslr_selfpatch_patch_dpins();
|
||||||
spslr_selfpatch_patch_ipins();
|
spslr_selfpatch_patch_ipins();
|
||||||
spslr_clear_targets();
|
|
||||||
}
|
|
||||||
|
|
||||||
void spslr_selfpatch_load_targets(void) {
|
spslr_randomizer_clear();
|
||||||
for (uint32_t tidx = 0; tidx < spslr_target_cnt; tidx++) {
|
|
||||||
const struct spslr_target* t = &spslr_targets[tidx];
|
|
||||||
|
|
||||||
#ifdef SPSLR_SANITY_CHECK
|
|
||||||
if (t->fieldoff + t->fieldcnt > spslr_target_field_cnt)
|
|
||||||
spslr_env_panic("target field offset and count reference invalid fields");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (spslr_register_target(tidx, t->size, t->fieldcnt) < 0)
|
|
||||||
spslr_env_panic("failed to register target");
|
|
||||||
|
|
||||||
for (uint32_t fidx = 0; fidx < t->fieldcnt; fidx++) {
|
|
||||||
const struct spslr_target_field* f = &spslr_target_fields[t->fieldoff + fidx];
|
|
||||||
|
|
||||||
#ifdef SPSLR_SANITY_CHECK
|
|
||||||
if (f->offset + f->size > t->size)
|
|
||||||
spslr_env_panic("target field resides beyond target size");
|
|
||||||
|
|
||||||
if (f->offset % f->alignment != 0)
|
|
||||||
spslr_env_panic("target field is misaligned");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (spslr_register_target_field(tidx, f->offset, f->size, f->alignment, f->flags) < 0)
|
|
||||||
spslr_env_panic("failed to register target field");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void spslr_selfpatch_randomize_targets(void) {
|
|
||||||
for (uint32_t tidx = 0; tidx < spslr_target_cnt; tidx++) {
|
|
||||||
if (spslr_randomize(tidx) < 0)
|
|
||||||
spslr_env_panic("failed to randomize target");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spslr_selfpatch_patch_dpins(void) {
|
void spslr_selfpatch_patch_dpins(void) {
|
||||||
@ -72,7 +39,7 @@ void spslr_selfpatch_patch_dpins(void) {
|
|||||||
|
|
||||||
void reorder_object(void* dst, const void* src, uint32_t target) {
|
void reorder_object(void* dst, const void* src, uint32_t target) {
|
||||||
uint32_t field_count;
|
uint32_t field_count;
|
||||||
if (spslr_get_target_fieldcnt(target, &field_count))
|
if (spslr_randomizer_get_target(target, NULL, &field_count))
|
||||||
spslr_env_panic("failed to get target field count");
|
spslr_env_panic("failed to get target field count");
|
||||||
|
|
||||||
const uint8_t* src_countable = (const uint8_t*)src;
|
const uint8_t* src_countable = (const uint8_t*)src;
|
||||||
@ -80,7 +47,8 @@ void reorder_object(void* dst, const void* src, uint32_t target) {
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < field_count; i++) {
|
for (uint32_t i = 0; i < field_count; i++) {
|
||||||
uint32_t field_offset, field_size, field_initial_offset;
|
uint32_t field_offset, field_size, field_initial_offset;
|
||||||
if (spslr_get_target_field_ordered(target, i, &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))
|
||||||
spslr_env_panic("failed to get ordered field descriptor");
|
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 + field_offset, src_countable + field_initial_offset, field_size);
|
||||||
@ -151,8 +119,9 @@ int64_t spslr_calculate_ipin_value(uint32_t start) {
|
|||||||
case SPSLR_IPIN_OP_ADD_INITIAL_OFFSET:
|
case SPSLR_IPIN_OP_ADD_INITIAL_OFFSET:
|
||||||
{
|
{
|
||||||
uint32_t initial_offset;
|
uint32_t initial_offset;
|
||||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||||
op->op1.add_initial_offset_field, NULL, &initial_offset))
|
op->op1.add_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL,
|
||||||
|
NULL, NULL, &initial_offset))
|
||||||
spslr_env_panic("failed to get initial field offset");
|
spslr_env_panic("failed to get initial field offset");
|
||||||
|
|
||||||
res += initial_offset;
|
res += initial_offset;
|
||||||
@ -161,8 +130,9 @@ int64_t spslr_calculate_ipin_value(uint32_t start) {
|
|||||||
case SPSLR_IPIN_OP_ADD_OFFSET:
|
case SPSLR_IPIN_OP_ADD_OFFSET:
|
||||||
{
|
{
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||||
op->op1.add_initial_offset_field, &offset, NULL))
|
op->op1.add_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL,
|
||||||
|
NULL, &offset, NULL))
|
||||||
spslr_env_panic("failed to get initial field offset");
|
spslr_env_panic("failed to get initial field offset");
|
||||||
|
|
||||||
res += offset;
|
res += offset;
|
||||||
@ -171,8 +141,9 @@ int64_t spslr_calculate_ipin_value(uint32_t start) {
|
|||||||
case SPSLR_IPIN_OP_SUB_INITIAL_OFFSET:
|
case SPSLR_IPIN_OP_SUB_INITIAL_OFFSET:
|
||||||
{
|
{
|
||||||
uint32_t initial_offset;
|
uint32_t initial_offset;
|
||||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||||
op->op1.add_initial_offset_field, NULL, &initial_offset))
|
op->op1.sub_initial_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL,
|
||||||
|
NULL, NULL, &initial_offset))
|
||||||
spslr_env_panic("failed to get initial field offset");
|
spslr_env_panic("failed to get initial field offset");
|
||||||
|
|
||||||
res -= initial_offset;
|
res -= initial_offset;
|
||||||
@ -181,8 +152,9 @@ int64_t spslr_calculate_ipin_value(uint32_t start) {
|
|||||||
case SPSLR_IPIN_OP_SUB_OFFSET:
|
case SPSLR_IPIN_OP_SUB_OFFSET:
|
||||||
{
|
{
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
if (spslr_randomizer_get_field(op->op0.add_initial_offset_target,
|
||||||
op->op1.add_initial_offset_field, &offset, NULL))
|
op->op1.sub_offset_field, SPSLR_RANDOMIZER_FIELD_IDX_MODE_ORIGINAL,
|
||||||
|
NULL, &offset, NULL))
|
||||||
spslr_env_panic("failed to get initial field offset");
|
spslr_env_panic("failed to get initial field offset");
|
||||||
|
|
||||||
res -= offset;
|
res -= offset;
|
||||||
|
|||||||
@ -1,422 +0,0 @@
|
|||||||
#include "targets.h"
|
|
||||||
|
|
||||||
#include "spslr_list.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
void seed_rand_time() {
|
|
||||||
srand(time(NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t rand_uint32() {
|
|
||||||
return (uint32_t)rand();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Field {
|
|
||||||
uint32_t initial_offset;
|
|
||||||
uint32_t initial_idx;
|
|
||||||
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t alignment;
|
|
||||||
uint32_t flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FinalField {
|
|
||||||
uint32_t initial_offset;
|
|
||||||
uint32_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Target {
|
|
||||||
uint32_t uid;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t field_count;
|
|
||||||
|
|
||||||
uint32_t present_field_count;
|
|
||||||
struct Field* fields;
|
|
||||||
struct FinalField* final_fields; // After rand (indexable by initial layout)
|
|
||||||
|
|
||||||
struct Target* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct Target* targets = NULL;
|
|
||||||
|
|
||||||
static struct Target* find_target(uint32_t uid) {
|
|
||||||
struct Target* cur = targets;
|
|
||||||
while (cur) {
|
|
||||||
if (cur->uid == uid)
|
|
||||||
return cur;
|
|
||||||
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int add_target(uint32_t uid, uint32_t size, uint32_t fieldcnt) {
|
|
||||||
if (find_target(uid))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
struct Target* new_target = (struct Target*)malloc(sizeof(struct Target));
|
|
||||||
if (!new_target)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
new_target->uid = uid;
|
|
||||||
new_target->size = size;
|
|
||||||
new_target->field_count = fieldcnt;
|
|
||||||
|
|
||||||
new_target->present_field_count = 0;
|
|
||||||
new_target->final_fields = NULL;
|
|
||||||
new_target->fields = (struct Field*)malloc(sizeof(struct Field) * fieldcnt);
|
|
||||||
|
|
||||||
if (!new_target->fields) {
|
|
||||||
free(new_target);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_target->next = targets;
|
|
||||||
targets = new_target;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_targets() {
|
|
||||||
struct Target* cur = targets;
|
|
||||||
while (cur) {
|
|
||||||
if (cur->fields)
|
|
||||||
free(cur->fields);
|
|
||||||
if (cur->final_fields)
|
|
||||||
free(cur->final_fields);
|
|
||||||
|
|
||||||
struct Target* tmp = cur;
|
|
||||||
cur = cur->next;
|
|
||||||
|
|
||||||
free(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
targets = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int spslr_register_target(uint32_t uid, uint32_t size, uint32_t fieldcnt) {
|
|
||||||
if (find_target(uid))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return add_target(uid, size, fieldcnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
int spslr_register_target_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t alignment, uint32_t flags) {
|
|
||||||
struct Target* t = find_target(target);
|
|
||||||
if (!t)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (offset + size > t->size)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (t->present_field_count >= t->field_count)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (offset % alignment != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (t->present_field_count) {
|
|
||||||
struct Field* pred = &t->fields[t->present_field_count - 1];
|
|
||||||
if (offset < pred->offset + pred->size)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t idx = t->present_field_count++;
|
|
||||||
|
|
||||||
struct Field* f = &t->fields[idx];
|
|
||||||
f->initial_offset = offset;
|
|
||||||
f->initial_idx = idx;
|
|
||||||
f->offset = offset;
|
|
||||||
f->size = size;
|
|
||||||
f->alignment = alignment;
|
|
||||||
f->flags = flags;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ShuffleRegion {
|
|
||||||
uint32_t begin, end;
|
|
||||||
uint32_t fill_begin, fill_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void target_get_origin_region(const struct Target* target, struct ShuffleRegion* region, uint32_t idx) {
|
|
||||||
region->fill_begin = target->fields[idx].offset;
|
|
||||||
region->fill_end = region->fill_begin + target->fields[idx].size;
|
|
||||||
|
|
||||||
if (idx <= 0)
|
|
||||||
region->begin = 0;
|
|
||||||
else
|
|
||||||
region->begin = target->fields[idx - 1].offset + target->fields[idx - 1].size;
|
|
||||||
|
|
||||||
if (idx >= target->field_count - 1)
|
|
||||||
region->end = target->size;
|
|
||||||
else
|
|
||||||
region->end = target->fields[idx + 1].offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t* options,
|
|
||||||
const struct ShuffleRegion* origin, uint32_t alignment) {
|
|
||||||
uint32_t count = 0;
|
|
||||||
|
|
||||||
uint32_t current_field = 0;
|
|
||||||
for (uint32_t offset = 0; offset < target->size; offset += alignment) {
|
|
||||||
// Placing the origin region here or further would exceed struct boundaries
|
|
||||||
uint32_t option_would_end = offset + (origin->fill_end - origin->fill_begin);
|
|
||||||
if (option_would_end > target->size)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Fields that end before offset are irrelevant at this point
|
|
||||||
while (current_field < target->field_count && target->fields[current_field].offset
|
|
||||||
+ target->fields[current_field].size <= offset) current_field++;
|
|
||||||
|
|
||||||
// If origin->fill_begin was placed at offset, could all fields that overlap with range swap with origin?
|
|
||||||
uint32_t true_origin_region_begin = origin->begin;
|
|
||||||
uint32_t true_origin_region_end = origin->end;
|
|
||||||
|
|
||||||
if (offset <= origin->fill_begin && option_would_end > true_origin_region_begin)
|
|
||||||
true_origin_region_begin = option_would_end;
|
|
||||||
|
|
||||||
if (offset >= origin->fill_begin && offset < true_origin_region_end)
|
|
||||||
true_origin_region_end = offset;
|
|
||||||
|
|
||||||
int conflict = 0;
|
|
||||||
uint32_t origin_region_ptr = true_origin_region_begin;
|
|
||||||
for (uint32_t it = current_field; it < target->field_count; it++) {
|
|
||||||
struct Field* f = &target->fields[it];
|
|
||||||
|
|
||||||
if (f->offset == origin->fill_begin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (f->offset >= option_would_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (f->flags & SPSLR_FLAG_FIELD_FIXED) {
|
|
||||||
conflict = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Could field be placed in origin?
|
|
||||||
if (origin_region_ptr % f->alignment != 0)
|
|
||||||
origin_region_ptr += f->alignment - (origin_region_ptr % f->alignment);
|
|
||||||
|
|
||||||
origin_region_ptr += f->size;
|
|
||||||
|
|
||||||
if (origin_region_ptr > true_origin_region_end) {
|
|
||||||
conflict = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conflict)
|
|
||||||
options[count++] = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void target_swap(struct Target* target, uint32_t origin_idx, const struct ShuffleRegion* origin_region,
|
|
||||||
uint32_t new_offset) {
|
|
||||||
int pulled = 0;
|
|
||||||
|
|
||||||
uint32_t option_fill_end = new_offset + (origin_region->fill_end - origin_region->fill_begin);
|
|
||||||
|
|
||||||
// If origin->fill_begin was placed at offset, could all fields that overlap with range swap with origin?
|
|
||||||
uint32_t true_origin_region_begin = origin_region->begin;
|
|
||||||
|
|
||||||
if (new_offset <= origin_region->fill_begin && option_fill_end > true_origin_region_begin)
|
|
||||||
true_origin_region_begin = option_fill_end;
|
|
||||||
|
|
||||||
uint32_t origin_initial_index = target->fields[origin_idx].initial_idx;
|
|
||||||
|
|
||||||
uint32_t origin_region_ptr = true_origin_region_begin;
|
|
||||||
for (uint32_t it = 0; it < target->field_count; it++) {
|
|
||||||
if (target->fields[it].initial_idx == origin_initial_index)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Fields that end before new_offset can stay there
|
|
||||||
if (target->fields[it].offset + target->fields[it].size <= new_offset)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Fields that start after where origin goes are irrelevant
|
|
||||||
if (target->fields[it].offset >= option_fill_end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
uint32_t falign = target->fields[it].alignment;
|
|
||||||
if (origin_region_ptr % falign != 0)
|
|
||||||
origin_region_ptr += falign - (origin_region_ptr % falign);
|
|
||||||
|
|
||||||
// First field in swap region is exchanged with origin
|
|
||||||
if (!pulled) {
|
|
||||||
pulled = 1;
|
|
||||||
|
|
||||||
struct Field tmp = target->fields[it];
|
|
||||||
target->fields[it] = target->fields[origin_idx];
|
|
||||||
target->fields[origin_idx] = tmp;
|
|
||||||
|
|
||||||
// Update origin field
|
|
||||||
target->fields[it].offset = new_offset;
|
|
||||||
|
|
||||||
// Update swapped field
|
|
||||||
target->fields[origin_idx].offset = origin_region_ptr;
|
|
||||||
origin_region_ptr += target->fields[origin_idx].size;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For all other fields in swap region, pull all until origin_idx one forward and place at origin_idx
|
|
||||||
struct Field tmp = target->fields[it];
|
|
||||||
|
|
||||||
if (origin_idx >= it) {
|
|
||||||
for (uint32_t pull_it = it + 1; pull_it <= origin_idx; pull_it++)
|
|
||||||
target->fields[pull_it - 1] = target->fields[pull_it];
|
|
||||||
|
|
||||||
target->fields[origin_idx] = tmp;
|
|
||||||
target->fields[origin_idx].offset = origin_region_ptr;
|
|
||||||
origin_region_ptr += target->fields[origin_idx].size;
|
|
||||||
} else {
|
|
||||||
// O X A B C -> pulled=0
|
|
||||||
// A X O B C -> pulled=1
|
|
||||||
// A B X O C -> pulled=2
|
|
||||||
// A B C X O -> pulled=3
|
|
||||||
for (uint32_t pull_it = it; pull_it > origin_idx + pulled; pull_it--)
|
|
||||||
target->fields[pull_it] = target->fields[pull_it - 1];
|
|
||||||
|
|
||||||
target->fields[origin_idx + pulled] = tmp;
|
|
||||||
target->fields[origin_idx + pulled].offset = origin_region_ptr;
|
|
||||||
origin_region_ptr += target->fields[origin_idx + pulled].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
pulled++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void target_shuffle_one(struct Target* target) {
|
|
||||||
if (!target || !target->field_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32_t origin = rand_uint32() % target->field_count;
|
|
||||||
|
|
||||||
if (target->fields[origin].flags & SPSLR_FLAG_FIELD_FIXED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32_t origin_alignment = target->fields[origin].alignment;
|
|
||||||
|
|
||||||
uint32_t max_options = target->size / origin_alignment;
|
|
||||||
uint32_t* swap_options = (uint32_t*)malloc(sizeof(uint32_t) * max_options); // match fill_begin
|
|
||||||
|
|
||||||
struct ShuffleRegion origin_region;
|
|
||||||
target_get_origin_region(target, &origin_region, origin);
|
|
||||||
|
|
||||||
uint32_t option_count = target_get_shuffle_options(target, swap_options, &origin_region, origin_alignment);
|
|
||||||
|
|
||||||
if (!option_count) {
|
|
||||||
free(swap_options);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t selected_option_idx = rand_uint32() % option_count;
|
|
||||||
uint32_t selected_option = swap_options[selected_option_idx];
|
|
||||||
|
|
||||||
free(swap_options);
|
|
||||||
|
|
||||||
target_swap(target, origin, &origin_region, selected_option);
|
|
||||||
}
|
|
||||||
|
|
||||||
int spslr_randomize(uint32_t target) {
|
|
||||||
struct Target* t = find_target(target);
|
|
||||||
if (!t)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (t->field_count != t->present_field_count)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uint32_t shuffle_count = t->field_count * 2;
|
|
||||||
for (uint32_t i = 0; i < shuffle_count; i++)
|
|
||||||
target_shuffle_one(t);
|
|
||||||
|
|
||||||
// Compile array of final fields
|
|
||||||
t->final_fields = (struct FinalField*)malloc(sizeof(struct FinalField) * t->field_count);
|
|
||||||
if (!t->final_fields)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < t->field_count; i++) {
|
|
||||||
const struct Field* f = &t->fields[i];
|
|
||||||
struct FinalField* ff = &t->final_fields[f->initial_idx];
|
|
||||||
|
|
||||||
ff->initial_offset = f->initial_offset;
|
|
||||||
ff->offset = f->offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int spslr_get_randomized_field_offset(uint32_t target, uint32_t field, uint32_t* offset, uint32_t* initial_offset) {
|
|
||||||
const struct Target* t = find_target(target);
|
|
||||||
if (!t)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (field >= t->field_count)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!t->final_fields)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (offset)
|
|
||||||
*offset = t->final_fields[field].offset;
|
|
||||||
|
|
||||||
if (initial_offset)
|
|
||||||
*initial_offset = t->final_fields[field].initial_offset;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int spslr_get_target_size(uint32_t target, uint32_t* size) {
|
|
||||||
const struct Target* t = find_target(target);
|
|
||||||
if (!t || !size)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
*size = t->size;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int spslr_get_target_fieldcnt(uint32_t target, uint32_t* cnt) {
|
|
||||||
const struct Target* t = find_target(target);
|
|
||||||
if (!t)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (cnt)
|
|
||||||
*cnt = t->field_count;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int spslr_get_target_field_ordered(uint32_t target, uint32_t field, uint32_t* offset,
|
|
||||||
uint32_t* size, uint32_t* initial_offset) {
|
|
||||||
const struct Target* t = find_target(target);
|
|
||||||
if (!t)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (field >= t->field_count)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
const struct Field* f = &t->fields[field];
|
|
||||||
|
|
||||||
if (offset)
|
|
||||||
*offset = f->offset;
|
|
||||||
|
|
||||||
if (size)
|
|
||||||
*size = f->size;
|
|
||||||
|
|
||||||
if (initial_offset)
|
|
||||||
*initial_offset = f->initial_offset;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spslr_clear_targets() {
|
|
||||||
clear_targets();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
#ifndef SPSLR_TARGETS_H
|
|
||||||
#define SPSLR_TARGETS_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void seed_rand_time();
|
|
||||||
|
|
||||||
int spslr_register_target(uint32_t uid, uint32_t size, uint32_t fieldcnt);
|
|
||||||
int spslr_register_target_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t alignment, uint32_t flags);
|
|
||||||
int spslr_randomize(uint32_t target);
|
|
||||||
|
|
||||||
int spslr_get_randomized_field_offset(uint32_t target, uint32_t field, uint32_t* offset, uint32_t* initial_offset);
|
|
||||||
int spslr_get_target_size(uint32_t target, uint32_t* size);
|
|
||||||
int spslr_get_target_fieldcnt(uint32_t target, uint32_t* cnt);
|
|
||||||
int spslr_get_target_field_ordered(uint32_t target, uint32_t field, uint32_t* offset,
|
|
||||||
uint32_t* size, uint32_t* initial_offset);
|
|
||||||
|
|
||||||
void spslr_clear_targets();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -65,8 +65,8 @@ int main(void)
|
|||||||
printf(" pid=%d, comm=%s\n", task->pid, task->comm);
|
printf(" pid=%d, comm=%s\n", task->pid, task->comm);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t myOffset = ((size_t)&((struct task_struct*)0)->tasks);
|
size_t myOffset = ((size_t)&((struct task_struct*)0)->pid);
|
||||||
printf("DIY offsetof(task_struct, tasks) yiels %2llu\n", myOffset);
|
printf("DIY offsetof(task_struct, pid) yiels %2llu\n", myOffset);
|
||||||
|
|
||||||
printf("Global: pid=%d comm=\"%s\"\n", global.pid, global.comm);
|
printf("Global: pid=%d comm=\"%s\"\n", global.pid, global.comm);
|
||||||
printf("Second global: pid=%d comm=\"%s\"\n", second_pid(), second_comm());
|
printf("Second global: pid=%d comm=\"%s\"\n", second_pid(), second_comm());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user