Updated patcher program
This commit is contained in:
parent
49ebe6ed8e
commit
54002646b0
@ -1,5 +1,17 @@
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
TODO
|
||||
1. getopt -> --spslr=<dir>, --bin=<file>
|
||||
2. Recursively gather all spslr CU files
|
||||
3. Loop over all symbols of the binary
|
||||
-> associate blocks via CU uid symbol
|
||||
-> find __spslr_program symbol (spslr vaddr pivot)
|
||||
4. Find virtual address and file address for all pins
|
||||
5. Calculate target randomization order
|
||||
6. Emit patcher program into final executable and set __spslr_program
|
||||
*/
|
||||
|
||||
/*
|
||||
<sourcefile>.spslr:
|
||||
|
||||
@ -23,6 +35,8 @@ The CU uid symbol helps differentiating between e.g. "file.c" and "sub/file.c" (
|
||||
Between CUs, types with the same name HAVE TO HAVE the same layout -> randomized together
|
||||
To begin with, anonymous types are not allowed for randomization (later solved with hash(type) instead of name)!
|
||||
|
||||
Note -> field alignment should probably be gathered by pinpoint plugin!
|
||||
|
||||
*/
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@ -6,7 +6,7 @@ int spslr_mprot(void* base, uint32_t pagecnt, uint8_t perm) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spslr_ipatch(void* ptr, uint32_t target, uint32_t field) {
|
||||
int spslr_ipatch(void* ptr, uint32_t size, uint32_t target, uint32_t field) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int spslr_mprot(void* base, uint32_t pagecnt, uint8_t perm);
|
||||
int spslr_ipatch(void* ptr, uint32_t target, uint32_t field);
|
||||
int spslr_ipatch(void* ptr, uint32_t size, uint32_t target, uint32_t field);
|
||||
int spslr_dpatch(void* ptr, uint32_t target);
|
||||
|
||||
#endif
|
||||
|
||||
@ -45,13 +45,15 @@ static int spslr_do(const struct SPSLR_INST* inst) {
|
||||
pending_fields_target = inst->op0.target_uid;
|
||||
return spslr_target(inst->op0.target_uid, inst->op1.target_size, inst->op2.target_fieldcnt);
|
||||
case SPSLR_FIELD:
|
||||
return spslr_field(pending_fields_target, inst->op0.field_offset, inst->op1.field_size, inst->op2.field_flags);
|
||||
return spslr_field(pending_fields_target, inst->op0.field_offset, inst->op1.field_size,
|
||||
inst->op2.field_alignment, inst->op3.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);
|
||||
return spslr_ipatch(spslr_ptr_absolute(inst->op0.ipatch_ptr), inst->op1.ipatch_size,
|
||||
inst->op2.ipatch_target, inst->op3.ipatch_field);
|
||||
case SPSLR_DPATCH:
|
||||
return spslr_dpatch(spslr_ptr_absolute(inst->op0.dpatch_ptr), inst->op1.dpatch_target);
|
||||
default:
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
|
||||
enum SPSLR_OPCODE {
|
||||
SPSLR_TARGET, // uid, size, field count
|
||||
SPSLR_FIELD, // offset, size, flags
|
||||
SPSLR_FIELD, // offset, size, alignment, flags
|
||||
SPSLR_RANDOMIZE, // target uid
|
||||
SPSLR_MPROT, // ptr, page count, perm
|
||||
SPSLR_IPATCH, // ptr, target uid, field idx (not offset!)
|
||||
SPSLR_IPATCH, // ptr, size, target uid, field idx (not offset!)
|
||||
SPSLR_DPATCH, // ptr, target uid
|
||||
SPSLR_EXIT
|
||||
};
|
||||
@ -32,16 +32,21 @@ struct SPSLR_INST {
|
||||
uint32_t target_size;
|
||||
uint32_t field_size;
|
||||
uint32_t mprot_pagecnt;
|
||||
uint32_t ipatch_target;
|
||||
uint32_t ipatch_size;
|
||||
uint32_t dpatch_target;
|
||||
} op1;
|
||||
|
||||
union {
|
||||
uint32_t target_fieldcnt;
|
||||
uint32_t field_flags;
|
||||
uint32_t field_alignment;
|
||||
uint8_t mprot_perm;
|
||||
uint32_t ipatch_field;
|
||||
uint32_t ipatch_target;
|
||||
} op2;
|
||||
|
||||
union {
|
||||
uint32_t field_flags;
|
||||
uint32_t ipatch_field;
|
||||
} op3;
|
||||
};
|
||||
|
||||
static inline int spslr_inst_dump_opcode(const struct SPSLR_INST* inst, uint8_t* buf) {
|
||||
@ -155,7 +160,7 @@ static inline int spslr_inst_dump_op1(const struct SPSLR_INST* inst, uint8_t* bu
|
||||
case SPSLR_MPROT:
|
||||
DUMP_OP_RET(inst->op1.mprot_pagecnt);
|
||||
case SPSLR_IPATCH:
|
||||
DUMP_OP_RET(inst->op1.ipatch_target);
|
||||
DUMP_OP_RET(inst->op1.ipatch_size);
|
||||
case SPSLR_DPATCH:
|
||||
DUMP_OP_RET(inst->op1.dpatch_target);
|
||||
case SPSLR_RANDOMIZE:
|
||||
@ -178,7 +183,7 @@ static inline int spslr_inst_load_op1(struct SPSLR_INST* inst, const uint8_t* bu
|
||||
case SPSLR_MPROT:
|
||||
LOAD_OP_RET(inst->op1.mprot_pagecnt);
|
||||
case SPSLR_IPATCH:
|
||||
LOAD_OP_RET(inst->op1.ipatch_target);
|
||||
LOAD_OP_RET(inst->op1.ipatch_size);
|
||||
case SPSLR_DPATCH:
|
||||
LOAD_OP_RET(inst->op1.dpatch_target);
|
||||
case SPSLR_RANDOMIZE:
|
||||
@ -197,11 +202,11 @@ static inline int spslr_inst_dump_op2(const struct SPSLR_INST* inst, uint8_t* bu
|
||||
case SPSLR_TARGET:
|
||||
DUMP_OP_RET(inst->op2.target_fieldcnt);
|
||||
case SPSLR_FIELD:
|
||||
DUMP_OP_RET(inst->op2.field_flags);
|
||||
DUMP_OP_RET(inst->op2.field_alignment);
|
||||
case SPSLR_MPROT:
|
||||
DUMP_OP_RET(inst->op2.mprot_perm);
|
||||
case SPSLR_IPATCH:
|
||||
DUMP_OP_RET(inst->op2.ipatch_field);
|
||||
DUMP_OP_RET(inst->op2.ipatch_target);
|
||||
case SPSLR_DPATCH:
|
||||
case SPSLR_RANDOMIZE:
|
||||
case SPSLR_EXIT:
|
||||
@ -219,11 +224,51 @@ static inline int spslr_inst_load_op2(struct SPSLR_INST* inst, const uint8_t* bu
|
||||
case SPSLR_TARGET:
|
||||
LOAD_OP_RET(inst->op2.target_fieldcnt);
|
||||
case SPSLR_FIELD:
|
||||
LOAD_OP_RET(inst->op2.field_flags);
|
||||
LOAD_OP_RET(inst->op2.field_alignment);
|
||||
case SPSLR_MPROT:
|
||||
LOAD_OP_RET(inst->op2.mprot_perm);
|
||||
case SPSLR_IPATCH:
|
||||
LOAD_OP_RET(inst->op2.ipatch_field);
|
||||
LOAD_OP_RET(inst->op2.ipatch_target);
|
||||
case SPSLR_DPATCH:
|
||||
case SPSLR_RANDOMIZE:
|
||||
case SPSLR_EXIT:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int spslr_inst_dump_op3(const struct SPSLR_INST* inst, uint8_t* buf) {
|
||||
if (!inst || !buf)
|
||||
return -1;
|
||||
|
||||
switch (inst->opcode) {
|
||||
case SPSLR_FIELD:
|
||||
DUMP_OP_RET(inst->op3.field_flags);
|
||||
case SPSLR_IPATCH:
|
||||
DUMP_OP_RET(inst->op3.ipatch_field);
|
||||
case SPSLR_TARGET:
|
||||
case SPSLR_MPROT:
|
||||
case SPSLR_DPATCH:
|
||||
case SPSLR_RANDOMIZE:
|
||||
case SPSLR_EXIT:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int spslr_inst_load_op3(struct SPSLR_INST* inst, const uint8_t* buf) {
|
||||
if (!inst || !buf)
|
||||
return -1;
|
||||
|
||||
switch (inst->opcode) {
|
||||
case SPSLR_FIELD:
|
||||
LOAD_OP_RET(inst->op3.field_flags);
|
||||
case SPSLR_IPATCH:
|
||||
LOAD_OP_RET(inst->op3.ipatch_field);
|
||||
case SPSLR_TARGET:
|
||||
case SPSLR_MPROT:
|
||||
case SPSLR_DPATCH:
|
||||
case SPSLR_RANDOMIZE:
|
||||
case SPSLR_EXIT:
|
||||
@ -237,7 +282,7 @@ static inline int spslr_inst_dump(const struct SPSLR_INST* inst, uint8_t* buf) {
|
||||
if (!inst || !buf)
|
||||
return -1;
|
||||
|
||||
int opcode_sz, op0_sz, op1_sz, op2_sz;
|
||||
int opcode_sz, op0_sz, op1_sz, op2_sz, op3_sz;
|
||||
|
||||
if ((opcode_sz = spslr_inst_dump_opcode(inst, buf)) < 0)
|
||||
return -1;
|
||||
@ -255,14 +300,18 @@ static inline int spslr_inst_dump(const struct SPSLR_INST* inst, uint8_t* buf) {
|
||||
return -1;
|
||||
buf += op2_sz;
|
||||
|
||||
return opcode_sz + op0_sz + op1_sz + op2_sz;
|
||||
if ((op3_sz = spslr_inst_dump_op3(inst, buf)) < 0)
|
||||
return -1;
|
||||
buf += op3_sz;
|
||||
|
||||
return opcode_sz + op0_sz + op1_sz + op2_sz + op3_sz;
|
||||
}
|
||||
|
||||
static inline int spslr_inst_load(struct SPSLR_INST* inst, const uint8_t* buf) {
|
||||
if (!inst || !buf)
|
||||
return -1;
|
||||
|
||||
int opcode_sz, op0_sz, op1_sz, op2_sz;
|
||||
int opcode_sz, op0_sz, op1_sz, op2_sz, op3_sz;
|
||||
|
||||
if ((opcode_sz = spslr_inst_load_opcode(inst, buf)) < 0)
|
||||
return -1;
|
||||
@ -280,7 +329,11 @@ static inline int spslr_inst_load(struct SPSLR_INST* inst, const uint8_t* buf) {
|
||||
return -1;
|
||||
buf += op2_sz;
|
||||
|
||||
return opcode_sz + op0_sz + op1_sz + op2_sz;
|
||||
if ((op3_sz = spslr_inst_load_op3(inst, buf)) < 0)
|
||||
return -1;
|
||||
buf += op3_sz;
|
||||
|
||||
return opcode_sz + op0_sz + op1_sz + op2_sz + op3_sz;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -18,6 +18,7 @@ struct Field {
|
||||
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
uint32_t alignment;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
@ -102,7 +103,7 @@ int spslr_target(uint32_t uid, uint32_t size, uint32_t fieldcnt) {
|
||||
return add_target(uid, size, fieldcnt);
|
||||
}
|
||||
|
||||
int spslr_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t flags) {
|
||||
int spslr_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;
|
||||
@ -113,6 +114,9 @@ int spslr_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t flags)
|
||||
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)
|
||||
@ -126,6 +130,7 @@ int spslr_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t flags)
|
||||
f->initial_idx = idx;
|
||||
f->offset = offset;
|
||||
f->size = size;
|
||||
f->alignment = alignment;
|
||||
f->flags = flags;
|
||||
|
||||
return 0;
|
||||
@ -136,10 +141,6 @@ struct ShuffleRegion {
|
||||
uint32_t fill_begin, fill_end;
|
||||
};
|
||||
|
||||
static uint32_t field_alignment(const struct Field* field) {
|
||||
return field->size; // Note -> alignments should be gathered by pinpoint plugin
|
||||
}
|
||||
|
||||
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;
|
||||
@ -184,9 +185,8 @@ static uint32_t target_get_shuffle_options(const struct Target* target, uint32_t
|
||||
}
|
||||
|
||||
// Could field be placed in origin?
|
||||
uint32_t falign = field_alignment(f);
|
||||
if (origin_region_ptr % falign != 0)
|
||||
origin_region_ptr += falign - (origin_region_ptr % falign);
|
||||
if (origin_region_ptr % f->alignment != 0)
|
||||
origin_region_ptr += f->alignment - (origin_region_ptr % f->alignment);
|
||||
|
||||
origin_region_ptr += f->size;
|
||||
|
||||
@ -217,7 +217,7 @@ static void target_swap(struct Target* target, uint32_t origin_idx, const struct
|
||||
if (target->fields[it].offset >= option_fill_end)
|
||||
break;
|
||||
|
||||
uint32_t falign = field_alignment(&target->fields[it]);
|
||||
uint32_t falign = target->fields[it].alignment;
|
||||
if (origin_region_ptr % falign != 0)
|
||||
origin_region_ptr += falign - (origin_region_ptr % falign);
|
||||
|
||||
@ -258,7 +258,7 @@ static void target_shuffle_one(struct Target* target) {
|
||||
if (target->fields[origin].flags & SPSLR_FLAG_FIELD_FIXED)
|
||||
return;
|
||||
|
||||
uint32_t origin_alignment = field_alignment(&target->fields[origin]);
|
||||
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
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int spslr_target(uint32_t uid, uint32_t size, uint32_t fieldcnt);
|
||||
int spslr_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t flags);
|
||||
int spslr_field(uint32_t target, uint32_t offset, uint32_t size, uint32_t alignment, uint32_t flags);
|
||||
int spslr_randomize(uint32_t target);
|
||||
|
||||
void spslr_targets_clear();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user