Updated patcher program
This commit is contained in:
parent
49ebe6ed8e
commit
54002646b0
@ -1,5 +1,17 @@
|
|||||||
#include <iostream>
|
#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:
|
<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
|
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)!
|
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) {
|
int main(int argc, char** argv) {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ int spslr_mprot(void* base, uint32_t pagecnt, uint8_t perm) {
|
|||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
int spslr_mprot(void* base, uint32_t pagecnt, uint8_t perm);
|
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);
|
int spslr_dpatch(void* ptr, uint32_t target);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -45,13 +45,15 @@ static int spslr_do(const struct SPSLR_INST* inst) {
|
|||||||
pending_fields_target = inst->op0.target_uid;
|
pending_fields_target = inst->op0.target_uid;
|
||||||
return spslr_target(inst->op0.target_uid, inst->op1.target_size, inst->op2.target_fieldcnt);
|
return spslr_target(inst->op0.target_uid, inst->op1.target_size, inst->op2.target_fieldcnt);
|
||||||
case SPSLR_FIELD:
|
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:
|
case SPSLR_RANDOMIZE:
|
||||||
return spslr_randomize(inst->op0.randomize_target);
|
return spslr_randomize(inst->op0.randomize_target);
|
||||||
case SPSLR_MPROT:
|
case SPSLR_MPROT:
|
||||||
return spslr_mprot(spslr_ptr_absolute(inst->op0.mprot_ptr), inst->op1.mprot_pagecnt, inst->op2.mprot_perm);
|
return spslr_mprot(spslr_ptr_absolute(inst->op0.mprot_ptr), inst->op1.mprot_pagecnt, inst->op2.mprot_perm);
|
||||||
case SPSLR_IPATCH:
|
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:
|
case SPSLR_DPATCH:
|
||||||
return spslr_dpatch(spslr_ptr_absolute(inst->op0.dpatch_ptr), inst->op1.dpatch_target);
|
return spslr_dpatch(spslr_ptr_absolute(inst->op0.dpatch_ptr), inst->op1.dpatch_target);
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
enum SPSLR_OPCODE {
|
enum SPSLR_OPCODE {
|
||||||
SPSLR_TARGET, // uid, size, field count
|
SPSLR_TARGET, // uid, size, field count
|
||||||
SPSLR_FIELD, // offset, size, flags
|
SPSLR_FIELD, // offset, size, alignment, flags
|
||||||
SPSLR_RANDOMIZE, // target uid
|
SPSLR_RANDOMIZE, // target uid
|
||||||
SPSLR_MPROT, // ptr, page count, perm
|
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_DPATCH, // ptr, target uid
|
||||||
SPSLR_EXIT
|
SPSLR_EXIT
|
||||||
};
|
};
|
||||||
@ -32,16 +32,21 @@ struct SPSLR_INST {
|
|||||||
uint32_t target_size;
|
uint32_t target_size;
|
||||||
uint32_t field_size;
|
uint32_t field_size;
|
||||||
uint32_t mprot_pagecnt;
|
uint32_t mprot_pagecnt;
|
||||||
uint32_t ipatch_target;
|
uint32_t ipatch_size;
|
||||||
uint32_t dpatch_target;
|
uint32_t dpatch_target;
|
||||||
} op1;
|
} op1;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
uint32_t target_fieldcnt;
|
uint32_t target_fieldcnt;
|
||||||
uint32_t field_flags;
|
uint32_t field_alignment;
|
||||||
uint8_t mprot_perm;
|
uint8_t mprot_perm;
|
||||||
uint32_t ipatch_field;
|
uint32_t ipatch_target;
|
||||||
} op2;
|
} 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) {
|
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:
|
case SPSLR_MPROT:
|
||||||
DUMP_OP_RET(inst->op1.mprot_pagecnt);
|
DUMP_OP_RET(inst->op1.mprot_pagecnt);
|
||||||
case SPSLR_IPATCH:
|
case SPSLR_IPATCH:
|
||||||
DUMP_OP_RET(inst->op1.ipatch_target);
|
DUMP_OP_RET(inst->op1.ipatch_size);
|
||||||
case SPSLR_DPATCH:
|
case SPSLR_DPATCH:
|
||||||
DUMP_OP_RET(inst->op1.dpatch_target);
|
DUMP_OP_RET(inst->op1.dpatch_target);
|
||||||
case SPSLR_RANDOMIZE:
|
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:
|
case SPSLR_MPROT:
|
||||||
LOAD_OP_RET(inst->op1.mprot_pagecnt);
|
LOAD_OP_RET(inst->op1.mprot_pagecnt);
|
||||||
case SPSLR_IPATCH:
|
case SPSLR_IPATCH:
|
||||||
LOAD_OP_RET(inst->op1.ipatch_target);
|
LOAD_OP_RET(inst->op1.ipatch_size);
|
||||||
case SPSLR_DPATCH:
|
case SPSLR_DPATCH:
|
||||||
LOAD_OP_RET(inst->op1.dpatch_target);
|
LOAD_OP_RET(inst->op1.dpatch_target);
|
||||||
case SPSLR_RANDOMIZE:
|
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:
|
case SPSLR_TARGET:
|
||||||
DUMP_OP_RET(inst->op2.target_fieldcnt);
|
DUMP_OP_RET(inst->op2.target_fieldcnt);
|
||||||
case SPSLR_FIELD:
|
case SPSLR_FIELD:
|
||||||
DUMP_OP_RET(inst->op2.field_flags);
|
DUMP_OP_RET(inst->op2.field_alignment);
|
||||||
case SPSLR_MPROT:
|
case SPSLR_MPROT:
|
||||||
DUMP_OP_RET(inst->op2.mprot_perm);
|
DUMP_OP_RET(inst->op2.mprot_perm);
|
||||||
case SPSLR_IPATCH:
|
case SPSLR_IPATCH:
|
||||||
DUMP_OP_RET(inst->op2.ipatch_field);
|
DUMP_OP_RET(inst->op2.ipatch_target);
|
||||||
case SPSLR_DPATCH:
|
case SPSLR_DPATCH:
|
||||||
case SPSLR_RANDOMIZE:
|
case SPSLR_RANDOMIZE:
|
||||||
case SPSLR_EXIT:
|
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:
|
case SPSLR_TARGET:
|
||||||
LOAD_OP_RET(inst->op2.target_fieldcnt);
|
LOAD_OP_RET(inst->op2.target_fieldcnt);
|
||||||
case SPSLR_FIELD:
|
case SPSLR_FIELD:
|
||||||
LOAD_OP_RET(inst->op2.field_flags);
|
LOAD_OP_RET(inst->op2.field_alignment);
|
||||||
case SPSLR_MPROT:
|
case SPSLR_MPROT:
|
||||||
LOAD_OP_RET(inst->op2.mprot_perm);
|
LOAD_OP_RET(inst->op2.mprot_perm);
|
||||||
case SPSLR_IPATCH:
|
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_DPATCH:
|
||||||
case SPSLR_RANDOMIZE:
|
case SPSLR_RANDOMIZE:
|
||||||
case SPSLR_EXIT:
|
case SPSLR_EXIT:
|
||||||
@ -237,7 +282,7 @@ static inline int spslr_inst_dump(const struct SPSLR_INST* inst, uint8_t* buf) {
|
|||||||
if (!inst || !buf)
|
if (!inst || !buf)
|
||||||
return -1;
|
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)
|
if ((opcode_sz = spslr_inst_dump_opcode(inst, buf)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -255,14 +300,18 @@ static inline int spslr_inst_dump(const struct SPSLR_INST* inst, uint8_t* buf) {
|
|||||||
return -1;
|
return -1;
|
||||||
buf += op2_sz;
|
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) {
|
static inline int spslr_inst_load(struct SPSLR_INST* inst, const uint8_t* buf) {
|
||||||
if (!inst || !buf)
|
if (!inst || !buf)
|
||||||
return -1;
|
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)
|
if ((opcode_sz = spslr_inst_load_opcode(inst, buf)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -280,7 +329,11 @@ static inline int spslr_inst_load(struct SPSLR_INST* inst, const uint8_t* buf) {
|
|||||||
return -1;
|
return -1;
|
||||||
buf += op2_sz;
|
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
|
#endif
|
||||||
|
|||||||
@ -18,6 +18,7 @@ struct Field {
|
|||||||
|
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
uint32_t alignment;
|
||||||
uint32_t flags;
|
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);
|
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);
|
struct Target* t = find_target(target);
|
||||||
if (!t)
|
if (!t)
|
||||||
return -1;
|
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)
|
if (t->present_field_count >= t->field_count)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (offset % alignment != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (t->present_field_count) {
|
if (t->present_field_count) {
|
||||||
struct Field* pred = &t->fields[t->present_field_count - 1];
|
struct Field* pred = &t->fields[t->present_field_count - 1];
|
||||||
if (offset < pred->offset + pred->size)
|
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->initial_idx = idx;
|
||||||
f->offset = offset;
|
f->offset = offset;
|
||||||
f->size = size;
|
f->size = size;
|
||||||
|
f->alignment = alignment;
|
||||||
f->flags = flags;
|
f->flags = flags;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -136,10 +141,6 @@ struct ShuffleRegion {
|
|||||||
uint32_t fill_begin, fill_end;
|
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) {
|
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_begin = target->fields[idx].offset;
|
||||||
region->fill_end = region->fill_begin + target->fields[idx].size;
|
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?
|
// Could field be placed in origin?
|
||||||
uint32_t falign = field_alignment(f);
|
if (origin_region_ptr % f->alignment != 0)
|
||||||
if (origin_region_ptr % falign != 0)
|
origin_region_ptr += f->alignment - (origin_region_ptr % f->alignment);
|
||||||
origin_region_ptr += falign - (origin_region_ptr % falign);
|
|
||||||
|
|
||||||
origin_region_ptr += f->size;
|
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)
|
if (target->fields[it].offset >= option_fill_end)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
uint32_t falign = field_alignment(&target->fields[it]);
|
uint32_t falign = target->fields[it].alignment;
|
||||||
if (origin_region_ptr % falign != 0)
|
if (origin_region_ptr % falign != 0)
|
||||||
origin_region_ptr += falign - (origin_region_ptr % falign);
|
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)
|
if (target->fields[origin].flags & SPSLR_FLAG_FIELD_FIXED)
|
||||||
return;
|
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 max_options = target->size / origin_alignment;
|
||||||
uint32_t* swap_options = (uint32_t*)malloc(sizeof(uint32_t) * max_options); // match fill_begin
|
uint32_t* swap_options = (uint32_t*)malloc(sizeof(uint32_t) * max_options); // match fill_begin
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
int spslr_target(uint32_t uid, uint32_t size, uint32_t fieldcnt);
|
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);
|
int spslr_randomize(uint32_t target);
|
||||||
|
|
||||||
void spslr_targets_clear();
|
void spslr_targets_clear();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user