selfpatch-slr/selfpatch/include/spslr_program.h

285 lines
6.1 KiB
C

#ifndef SPSLR_PROGRAM_H
#define SPSLR_PROGRAM_H
#include <stdint.h>
#include <string.h>
enum SPSLR_OPCODE {
SPSLR_TARGET, // uid, size, field count
SPSLR_FIELD, // offset, size, flags
SPSLR_RANDOMIZE, // target uid
SPSLR_MPROT, // ptr, page count, perm
SPSLR_IPATCH, // ptr, target uid, field idx (not offset!)
SPSLR_DPATCH, // ptr, target uid
SPSLR_EXIT
};
struct SPSLR_INST {
enum SPSLR_OPCODE opcode;
union {
uint32_t target_uid;
uint32_t field_offset;
uint32_t randomize_target;
uint64_t mprot_ptr;
uint64_t ipatch_ptr;
uint64_t dpatch_ptr;
} op0;
union {
uint32_t target_size;
uint32_t field_size;
uint32_t mprot_pagecnt;
uint32_t ipatch_target;
uint32_t dpatch_target;
} op1;
union {
uint32_t target_fieldcnt;
uint32_t field_flags;
uint8_t mprot_perm;
uint32_t ipatch_field;
} op2;
};
static inline int spslr_inst_dump_opcode(const struct SPSLR_INST* inst, uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (inst->opcode) {
case SPSLR_TARGET:
*buf = 1; return 1;
case SPSLR_FIELD:
*buf = 2; return 1;
case SPSLR_RANDOMIZE:
*buf = 3; return 1;
case SPSLR_MPROT:
*buf = 4; return 1;
case SPSLR_IPATCH:
*buf = 5; return 1;
case SPSLR_DPATCH:
*buf = 6; return 1;
case SPSLR_EXIT:
*buf = 7; return 1;
default:
return -1;
}
}
static inline int spslr_inst_load_opcode(struct SPSLR_INST* inst, const uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (*buf) {
case 1:
inst->opcode = SPSLR_TARGET; return 1;
case 2:
inst->opcode = SPSLR_FIELD; return 1;
case 3:
inst->opcode = SPSLR_RANDOMIZE; return 1;
case 4:
inst->opcode = SPSLR_MPROT; return 1;
case 5:
inst->opcode = SPSLR_IPATCH; return 1;
case 6:
inst->opcode = SPSLR_DPATCH; return 1;
case 7:
inst->opcode = SPSLR_EXIT; return 1;
default:
return -1;
}
}
#define DUMP_OP_RET(field) { memcpy(buf, &field, sizeof(field)); return sizeof(field); }
#define LOAD_OP_RET(field) { memcpy(&field, buf, sizeof(field)); return sizeof(field); }
static inline int spslr_inst_dump_op0(const struct SPSLR_INST* inst, uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (inst->opcode) {
case SPSLR_TARGET:
DUMP_OP_RET(inst->op0.target_uid);
case SPSLR_FIELD:
DUMP_OP_RET(inst->op0.field_offset);
case SPSLR_RANDOMIZE:
DUMP_OP_RET(inst->op0.randomize_target);
case SPSLR_MPROT:
DUMP_OP_RET(inst->op0.mprot_ptr);
case SPSLR_IPATCH:
DUMP_OP_RET(inst->op0.ipatch_ptr);
case SPSLR_DPATCH:
DUMP_OP_RET(inst->op0.dpatch_ptr);
case SPSLR_EXIT:
return 0;
default:
return -1;
}
}
static inline int spslr_inst_load_op0(struct SPSLR_INST* inst, const uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (inst->opcode) {
case SPSLR_TARGET:
LOAD_OP_RET(inst->op0.target_uid);
case SPSLR_FIELD:
LOAD_OP_RET(inst->op0.field_offset);
case SPSLR_RANDOMIZE:
LOAD_OP_RET(inst->op0.randomize_target);
case SPSLR_MPROT:
LOAD_OP_RET(inst->op0.mprot_ptr);
case SPSLR_IPATCH:
LOAD_OP_RET(inst->op0.ipatch_ptr);
case SPSLR_DPATCH:
LOAD_OP_RET(inst->op0.dpatch_ptr);
case SPSLR_EXIT:
return 0;
default:
return -1;
}
}
static inline int spslr_inst_dump_op1(const struct SPSLR_INST* inst, uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (inst->opcode) {
case SPSLR_TARGET:
DUMP_OP_RET(inst->op1.target_size);
case SPSLR_FIELD:
DUMP_OP_RET(inst->op1.field_size);
case SPSLR_MPROT:
DUMP_OP_RET(inst->op1.mprot_pagecnt);
case SPSLR_IPATCH:
DUMP_OP_RET(inst->op1.ipatch_target);
case SPSLR_DPATCH:
DUMP_OP_RET(inst->op1.dpatch_target);
case SPSLR_RANDOMIZE:
case SPSLR_EXIT:
return 0;
default:
return -1;
}
}
static inline int spslr_inst_load_op1(struct SPSLR_INST* inst, const uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (inst->opcode) {
case SPSLR_TARGET:
LOAD_OP_RET(inst->op1.target_size);
case SPSLR_FIELD:
LOAD_OP_RET(inst->op1.field_size);
case SPSLR_MPROT:
LOAD_OP_RET(inst->op1.mprot_pagecnt);
case SPSLR_IPATCH:
LOAD_OP_RET(inst->op1.ipatch_target);
case SPSLR_DPATCH:
LOAD_OP_RET(inst->op1.dpatch_target);
case SPSLR_RANDOMIZE:
case SPSLR_EXIT:
return 0;
default:
return -1;
}
}
static inline int spslr_inst_dump_op2(const struct SPSLR_INST* inst, uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (inst->opcode) {
case SPSLR_TARGET:
DUMP_OP_RET(inst->op2.target_fieldcnt);
case SPSLR_FIELD:
DUMP_OP_RET(inst->op2.field_flags);
case SPSLR_MPROT:
DUMP_OP_RET(inst->op2.mprot_perm);
case SPSLR_IPATCH:
DUMP_OP_RET(inst->op2.ipatch_field);
case SPSLR_DPATCH:
case SPSLR_RANDOMIZE:
case SPSLR_EXIT:
return 0;
default:
return -1;
}
}
static inline int spslr_inst_load_op2(struct SPSLR_INST* inst, const uint8_t* buf) {
if (!inst || !buf)
return -1;
switch (inst->opcode) {
case SPSLR_TARGET:
LOAD_OP_RET(inst->op2.target_fieldcnt);
case SPSLR_FIELD:
LOAD_OP_RET(inst->op2.field_flags);
case SPSLR_MPROT:
LOAD_OP_RET(inst->op2.mprot_perm);
case SPSLR_IPATCH:
LOAD_OP_RET(inst->op2.ipatch_field);
case SPSLR_DPATCH:
case SPSLR_RANDOMIZE:
case SPSLR_EXIT:
return 0;
default:
return -1;
}
}
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;
if ((opcode_sz = spslr_inst_dump_opcode(inst, buf)) < 0)
return -1;
buf += opcode_sz;
if ((op0_sz = spslr_inst_dump_op0(inst, buf)) < 0)
return -1;
buf += op0_sz;
if ((op1_sz = spslr_inst_dump_op1(inst, buf)) < 0)
return -1;
buf += op1_sz;
if ((op2_sz = spslr_inst_dump_op2(inst, buf)) < 0)
return -1;
buf += op2_sz;
return opcode_sz + op0_sz + op1_sz + op2_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;
if ((opcode_sz = spslr_inst_load_opcode(inst, buf)) < 0)
return -1;
buf += opcode_sz;
if ((op0_sz = spslr_inst_load_op0(inst, buf)) < 0)
return -1;
buf += op0_sz;
if ((op1_sz = spslr_inst_load_op1(inst, buf)) < 0)
return -1;
buf += op1_sz;
if ((op2_sz = spslr_inst_load_op2(inst, buf)) < 0)
return -1;
buf += op2_sz;
return opcode_sz + op0_sz + op1_sz + op2_sz;
}
#endif