Updated patchcompile to work with new selfpatch interface
This commit is contained in:
parent
b40222f0ae
commit
3dac12431a
@ -1,144 +1,319 @@
|
||||
#include "emit.h"
|
||||
#include "accumulation.h"
|
||||
|
||||
#include <spslr_program.h>
|
||||
#include <spslr_list.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
struct TARGET_REC {
|
||||
uint32_t size;
|
||||
uint32_t fieldcnt;
|
||||
uint32_t fieldoff;
|
||||
};
|
||||
|
||||
struct TARGET_FIELD_REC {
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
uint32_t alignment;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct IPIN_REC {
|
||||
std::string addr_sym;
|
||||
uint32_t size;
|
||||
uint32_t program;
|
||||
};
|
||||
|
||||
struct IPIN_OP_REC {
|
||||
uint32_t code;
|
||||
uint32_t op0;
|
||||
uint32_t op1;
|
||||
};
|
||||
|
||||
struct DPIN_REC {
|
||||
std::string addr_sym;
|
||||
uint32_t target;
|
||||
};
|
||||
|
||||
struct PROGRAM_KEY {
|
||||
uint32_t target;
|
||||
uint32_t field;
|
||||
|
||||
bool operator==(const PROGRAM_KEY& other) const {
|
||||
return target == other.target && field == other.field;
|
||||
}
|
||||
};
|
||||
|
||||
struct PROGRAM_KEY_HASH {
|
||||
std::size_t operator()(const PROGRAM_KEY& k) const {
|
||||
return (static_cast<std::size_t>(k.target) << 32) ^ k.field;
|
||||
}
|
||||
};
|
||||
|
||||
static bool emit_header(std::ostream& out);
|
||||
static bool emit_target_header(std::ostream& out, std::size_t uid, std::size_t size, std::size_t fieldcnt);
|
||||
static bool emit_target_field(std::ostream& out, std::size_t offset, std::size_t size, std::size_t alignment, std::size_t flags);
|
||||
static bool emit_target_randomize(std::ostream& out, std::size_t uid);
|
||||
static bool emit_target(std::ostream& out, std::size_t uid, const TARGET& target);
|
||||
static bool emit_ipin(std::ostream& out, const CU& cu, const IPIN& ipin);
|
||||
static bool emit_dpin_component(std::ostream& out, std::size_t target, const std::string& sym, std::size_t offset);
|
||||
static bool emit_dpin(std::ostream& out, const CU& cu, const DPIN& dpin);
|
||||
static bool emit_exit(std::ostream& out);
|
||||
static bool emit_u32_object(std::ostream& out, const char* name, uint32_t value);
|
||||
static bool emit_targets(std::ostream& out, const std::vector<TARGET_REC>& targets);
|
||||
static bool emit_target_fields(std::ostream& out, const std::vector<TARGET_FIELD_REC>& fields);
|
||||
static bool emit_ipins(std::ostream& out, const std::vector<IPIN_REC>& ipins);
|
||||
static bool emit_ipin_ops(std::ostream& out, const std::vector<IPIN_OP_REC>& ops);
|
||||
static bool emit_dpins(std::ostream& out, const std::vector<DPIN_REC>& dpins);
|
||||
|
||||
static uint32_t intern_simple_ipin_program(
|
||||
std::vector<IPIN_OP_REC>& ops,
|
||||
std::unordered_map<PROGRAM_KEY, uint32_t, PROGRAM_KEY_HASH>& memo,
|
||||
uint32_t target,
|
||||
uint32_t field)
|
||||
{
|
||||
PROGRAM_KEY key{target, field};
|
||||
|
||||
auto it = memo.find(key);
|
||||
if (it != memo.end())
|
||||
return it->second;
|
||||
|
||||
const uint32_t start = static_cast<uint32_t>(ops.size());
|
||||
|
||||
ops.push_back(IPIN_OP_REC{
|
||||
.code = SPSLR_IPIN_OP_ADD_OFFSET,
|
||||
.op0 = target,
|
||||
.op1 = field,
|
||||
});
|
||||
|
||||
ops.push_back(IPIN_OP_REC{
|
||||
.code = SPSLR_IPIN_OP_PATCH,
|
||||
.op0 = 0,
|
||||
.op1 = 0,
|
||||
});
|
||||
|
||||
memo.emplace(key, start);
|
||||
return start;
|
||||
}
|
||||
|
||||
static bool emit_header(std::ostream& out) {
|
||||
out << ".section .spslr,\"a\",@progbits\n";
|
||||
out << ".balign 8\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_u32_object(std::ostream& out, const char* name, uint32_t value) {
|
||||
out << ".globl " << name << "\n";
|
||||
out << ".type " << name << ", @object\n";
|
||||
out << ".balign 4\n";
|
||||
out << name << ":\n";
|
||||
out << "\t.long " << value << "\n";
|
||||
out << ".size " << name << ", 4\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_targets(std::ostream& out, const std::vector<TARGET_REC>& targets) {
|
||||
out << ".globl spslr_targets\n";
|
||||
out << ".type spslr_targets, @object\n";
|
||||
out << ".balign 4\n";
|
||||
out << "spslr_targets:\n";
|
||||
|
||||
for (const TARGET_REC& t : targets) {
|
||||
out << "\t.long " << t.size << "\n";
|
||||
out << "\t.long " << t.fieldcnt << "\n";
|
||||
out << "\t.long " << t.fieldoff << "\n";
|
||||
}
|
||||
|
||||
out << ".size spslr_targets, .-spslr_targets\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_target_fields(std::ostream& out, const std::vector<TARGET_FIELD_REC>& fields) {
|
||||
out << ".globl spslr_target_fields\n";
|
||||
out << ".type spslr_target_fields, @object\n";
|
||||
out << ".balign 4\n";
|
||||
out << "spslr_target_fields:\n";
|
||||
|
||||
for (const TARGET_FIELD_REC& f : fields) {
|
||||
out << "\t.long " << f.offset << "\n";
|
||||
out << "\t.long " << f.size << "\n";
|
||||
out << "\t.long " << f.alignment << "\n";
|
||||
out << "\t.long " << f.flags << "\n";
|
||||
}
|
||||
|
||||
out << ".size spslr_target_fields, .-spslr_target_fields\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_ipins(std::ostream& out, const std::vector<IPIN_REC>& ipins) {
|
||||
out << ".globl spslr_ipins\n";
|
||||
out << ".type spslr_ipins, @object\n";
|
||||
out << ".balign 8\n";
|
||||
out << "spslr_ipins:\n";
|
||||
|
||||
for (const IPIN_REC& ip : ipins) {
|
||||
out << "\t.quad " << ip.addr_sym << "\n";
|
||||
out << "\t.long " << ip.size << "\n";
|
||||
out << "\t.long " << ip.program << "\n";
|
||||
}
|
||||
|
||||
out << ".size spslr_ipins, .-spslr_ipins\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_ipin_ops(std::ostream& out, const std::vector<IPIN_OP_REC>& ops) {
|
||||
out << ".globl spslr_ipin_ops\n";
|
||||
out << ".type spslr_ipin_ops, @object\n";
|
||||
out << ".balign 4\n";
|
||||
out << "spslr_ipin_ops:\n";
|
||||
|
||||
for (const IPIN_OP_REC& op : ops) {
|
||||
out << "\t.long " << op.code << "\n";
|
||||
out << "\t.long " << op.op0 << "\n";
|
||||
out << "\t.long " << op.op1 << "\n";
|
||||
}
|
||||
|
||||
out << ".size spslr_ipin_ops, .-spslr_ipin_ops\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_dpins(std::ostream& out, const std::vector<DPIN_REC>& dpins) {
|
||||
out << ".globl spslr_dpins\n";
|
||||
out << ".type spslr_dpins, @object\n";
|
||||
out << ".balign 8\n";
|
||||
out << "spslr_dpins:\n";
|
||||
|
||||
for (const DPIN_REC& dp : dpins) {
|
||||
out << "\t.quad " << dp.addr_sym << "\n";
|
||||
out << "\t.long " << dp.target << "\n";
|
||||
}
|
||||
|
||||
out << ".size spslr_dpins, .-spslr_dpins\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool emit_patcher_program_asm(std::ostream& out) {
|
||||
if (!emit_header(out))
|
||||
return false;
|
||||
|
||||
// Dump all targets
|
||||
for (const auto& [uid, target] : targets) {
|
||||
if (!emit_target(out, uid, target))
|
||||
return false;
|
||||
}
|
||||
// Important: target UID == index in spslr_targets[] for the new interface.
|
||||
std::vector<TARGET_REC> target_recs(targets.size());
|
||||
std::vector<TARGET_FIELD_REC> field_recs;
|
||||
field_recs.reserve(64);
|
||||
|
||||
// Dump all pins
|
||||
for (const auto& [uid, cu] : units) {
|
||||
for (const auto& [sym, pin] : cu.ipins) {
|
||||
if (!emit_ipin(out, cu, pin))
|
||||
return false;
|
||||
for (uint32_t uid = 0; uid < static_cast<uint32_t>(targets.size()); ++uid) {
|
||||
if (!targets.contains(uid))
|
||||
return false;
|
||||
|
||||
const TARGET& target = targets.at(uid);
|
||||
|
||||
TARGET_REC trec{};
|
||||
trec.size = static_cast<uint32_t>(target.size);
|
||||
trec.fieldoff = static_cast<uint32_t>(field_recs.size());
|
||||
trec.fieldcnt = static_cast<uint32_t>(target.fields.size());
|
||||
|
||||
for (const auto& [off, field] : target.fields) {
|
||||
(void)off;
|
||||
field_recs.push_back(TARGET_FIELD_REC{
|
||||
.offset = static_cast<uint32_t>(field.offset),
|
||||
.size = static_cast<uint32_t>(field.size),
|
||||
.alignment = static_cast<uint32_t>(field.alignment),
|
||||
.flags = static_cast<uint32_t>(field.flags),
|
||||
});
|
||||
}
|
||||
|
||||
for (const auto& [sym, pin] : cu.dpins) {
|
||||
if (!emit_dpin(out, cu, pin))
|
||||
target_recs[uid] = trec;
|
||||
}
|
||||
|
||||
std::vector<IPIN_REC> ipin_recs;
|
||||
std::vector<IPIN_OP_REC> ipin_ops;
|
||||
std::unordered_map<PROGRAM_KEY, uint32_t, PROGRAM_KEY_HASH> program_memo;
|
||||
|
||||
std::vector<DPIN_REC> dpin_recs;
|
||||
|
||||
for (const auto& [cu_uid, cu] : units) {
|
||||
(void)cu_uid;
|
||||
|
||||
for (const auto& [sym, ipin] : cu.ipins) {
|
||||
const uint32_t global_target = static_cast<uint32_t>(cu.local_targets.at(ipin.local_target));
|
||||
|
||||
if (!targets.contains(global_target))
|
||||
return false;
|
||||
|
||||
const TARGET& target = targets.at(global_target);
|
||||
|
||||
if (!target.fields.contains(ipin.field_offset))
|
||||
return false;
|
||||
|
||||
const FIELD& field = target.fields.at(ipin.field_offset);
|
||||
|
||||
const uint32_t program = intern_simple_ipin_program(
|
||||
ipin_ops,
|
||||
program_memo,
|
||||
global_target,
|
||||
static_cast<uint32_t>(field.idx)
|
||||
);
|
||||
|
||||
ipin_recs.push_back(IPIN_REC{
|
||||
.addr_sym = ipin.symbol,
|
||||
.size = static_cast<uint32_t>(ipin.imm_size),
|
||||
.program = program,
|
||||
});
|
||||
}
|
||||
|
||||
for (const auto& [sym, dpin] : cu.dpins) {
|
||||
std::vector<DPIN::COMPONENT> sorted_components(dpin.components.begin(), dpin.components.end());
|
||||
|
||||
std::sort(
|
||||
sorted_components.begin(),
|
||||
sorted_components.end(),
|
||||
[](const DPIN::COMPONENT& a, const DPIN::COMPONENT& b) {
|
||||
return a.level > b.level;
|
||||
}
|
||||
);
|
||||
|
||||
for (const DPIN::COMPONENT& component : sorted_components) {
|
||||
const uint32_t global_target =
|
||||
static_cast<uint32_t>(cu.local_targets.at(component.target));
|
||||
|
||||
std::string addr = dpin.symbol;
|
||||
if (component.offset != 0)
|
||||
addr += " + " + std::to_string(component.offset);
|
||||
|
||||
dpin_recs.push_back(DPIN_REC{
|
||||
.addr_sym = std::move(addr),
|
||||
.target = global_target,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit patcher program
|
||||
if (!emit_exit(out))
|
||||
if (!emit_u32_object(out, "spslr_target_cnt", static_cast<uint32_t>(target_recs.size())))
|
||||
return false;
|
||||
if (!emit_targets(out, target_recs))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool emit_header(std::ostream& out) {
|
||||
out << ".section .spslr,\"a\",@progbits\n";
|
||||
out << ".balign 1\n";
|
||||
out << ".globl __spslr_program\n";
|
||||
out << ".type __spslr_program, @object\n";
|
||||
out << "__spslr_program:\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
bool emit_target_header(std::ostream& out, std::size_t uid, std::size_t size, std::size_t fieldcnt) {
|
||||
out << "\t.byte " << OPCODE_SPSLR_TARGET << "\n";
|
||||
out << "\t.long " << uid << "\n";
|
||||
out << "\t.long " << size << "\n";
|
||||
out << "\t.long " << fieldcnt << "\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
bool emit_target_field(std::ostream& out, std::size_t offset, std::size_t size, std::size_t alignment, std::size_t flags) {
|
||||
out << "\t.byte " << OPCODE_SPSLR_FIELD << "\n";
|
||||
out << "\t.long " << offset << "\n";
|
||||
out << "\t.long " << size << "\n";
|
||||
out << "\t.long " << alignment << "\n";
|
||||
out << "\t.long " << flags << "\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
bool emit_target_randomize(std::ostream& out, std::size_t uid) {
|
||||
out << "\t.byte " << OPCODE_SPSLR_RANDOMIZE << "\n";
|
||||
out << "\t.long " << uid << "\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
bool emit_target(std::ostream& out, std::size_t uid, const TARGET& target) {
|
||||
if (!emit_target_header(out, uid, target.size, target.fields.size()))
|
||||
if (!emit_u32_object(out, "spslr_target_field_cnt", static_cast<uint32_t>(field_recs.size())))
|
||||
return false;
|
||||
if (!emit_target_fields(out, field_recs))
|
||||
return false;
|
||||
|
||||
for (const auto& [off, field] : target.fields) {
|
||||
// Note -> Might want to do explicit flag mapping from pinpoint to selfpatch
|
||||
if (!emit_target_field(out, field.offset, field.size, field.alignment, field.flags))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!emit_target_randomize(out, uid))
|
||||
if (!emit_u32_object(out, "spslr_ipin_cnt", static_cast<uint32_t>(ipin_recs.size())))
|
||||
return false;
|
||||
if (!emit_ipins(out, ipin_recs))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool emit_ipin(std::ostream& out, const CU& cu, const IPIN& ipin) {
|
||||
std::size_t global_target = cu.local_targets.at(ipin.local_target);
|
||||
|
||||
if (!targets.contains(global_target))
|
||||
if (!emit_u32_object(out, "spslr_ipin_op_cnt", static_cast<uint32_t>(ipin_ops.size())))
|
||||
return false;
|
||||
if (!emit_ipin_ops(out, ipin_ops))
|
||||
return false;
|
||||
|
||||
const TARGET& target = targets.at(global_target);
|
||||
|
||||
if (!target.fields.contains(ipin.field_offset))
|
||||
if (!emit_u32_object(out, "spslr_dpin_cnt", static_cast<uint32_t>(dpin_recs.size())))
|
||||
return false;
|
||||
if (!emit_dpins(out, dpin_recs))
|
||||
return false;
|
||||
|
||||
const FIELD& field = target.fields.at(ipin.field_offset);
|
||||
|
||||
out << "\t.byte " << OPCODE_SPSLR_IPATCH << "\n";
|
||||
out << "\t.quad " << ipin.symbol << "\n";
|
||||
out << "\t.long " << ipin.imm_size << "\n";
|
||||
out << "\t.long " << global_target << "\n";
|
||||
out << "\t.long " << field.idx << "\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
bool emit_dpin_component(std::ostream& out, std::size_t target, const std::string& sym, std::size_t offset) {
|
||||
out << "\t.byte " << OPCODE_SPSLR_DPATCH << "\n";
|
||||
out << "\t.quad " << sym;
|
||||
if (offset != 0)
|
||||
out << " + " << offset;
|
||||
out << "\n";
|
||||
out << "\t.long " << target << "\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
bool emit_dpin(std::ostream& out, const CU& cu, const DPIN& dpin) {
|
||||
std::list<DPIN::COMPONENT> sorted_components = dpin.components;
|
||||
sorted_components.sort([](const DPIN::COMPONENT& a, const DPIN::COMPONENT& b) {
|
||||
return a.level > b.level; // Descending order to handle deeper nested first
|
||||
});
|
||||
|
||||
for (const DPIN::COMPONENT& component : sorted_components) {
|
||||
std::size_t global_target = cu.local_targets.at(component.target);
|
||||
if (!emit_dpin_component(out, global_target, dpin.symbol, component.offset))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool emit_exit(std::ostream& out) {
|
||||
out << "\t.byte " << OPCODE_SPSLR_EXIT << "\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,8 @@ static void reorder_object(void* dst, const void* src, uint32_t target);
|
||||
static int64_t spslr_calculate_ipin_value(uint32_t start);
|
||||
|
||||
void spslr_selfpatch(void) {
|
||||
seed_rand_time();
|
||||
|
||||
spslr_selfpatch_load_targets();
|
||||
spslr_selfpatch_randomize_targets();
|
||||
spslr_selfpatch_patch_dpins();
|
||||
@ -113,7 +115,7 @@ void spslr_selfpatch_patch_ipins(void) {
|
||||
spslr_env_poke_text_8((void*)ip->addr, (uint8_t)value);
|
||||
break;
|
||||
case 2:
|
||||
spslr_env_poke_text_64((void*)ip->addr, (uint16_t)value);
|
||||
spslr_env_poke_text_16((void*)ip->addr, (uint16_t)value);
|
||||
break;
|
||||
case 4:
|
||||
spslr_env_poke_text_32((void*)ip->addr, (uint32_t)value);
|
||||
@ -139,58 +141,64 @@ int64_t spslr_calculate_ipin_value(uint32_t start) {
|
||||
spslr_env_panic("ipin op out of bounds");
|
||||
#endif
|
||||
|
||||
int end_flag = 0;
|
||||
|
||||
const struct spslr_ipin_op* op = &spslr_ipin_ops[pc++];
|
||||
switch (op->code) {
|
||||
case SPSLR_IPIN_OP_PATCH:
|
||||
end_flag = 1;
|
||||
break;
|
||||
case SPSLR_IPIN_OP_ADD_INITIAL_OFFSET:
|
||||
{
|
||||
uint32_t initial_offset;
|
||||
if (spslr_get_target_field_ordered(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, NULL, NULL, &initial_offset))
|
||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, NULL, &initial_offset))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
|
||||
res += initial_offset;
|
||||
}
|
||||
continue;
|
||||
break;
|
||||
case SPSLR_IPIN_OP_ADD_OFFSET:
|
||||
{
|
||||
uint32_t offset;
|
||||
if (spslr_get_target_field_ordered(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, &offset, NULL, NULL))
|
||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, &offset, NULL))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
|
||||
res += offset;
|
||||
}
|
||||
continue;
|
||||
break;
|
||||
case SPSLR_IPIN_OP_SUB_INITIAL_OFFSET:
|
||||
{
|
||||
uint32_t initial_offset;
|
||||
if (spslr_get_target_field_ordered(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, NULL, NULL, &initial_offset))
|
||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, NULL, &initial_offset))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
|
||||
res -= initial_offset;
|
||||
}
|
||||
continue;
|
||||
break;
|
||||
case SPSLR_IPIN_OP_SUB_OFFSET:
|
||||
{
|
||||
uint32_t offset;
|
||||
if (spslr_get_target_field_ordered(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, &offset, NULL, NULL))
|
||||
if (spslr_get_randomized_field_offset(op->op0.add_initial_offset_target,
|
||||
op->op1.add_initial_offset_field, &offset, NULL))
|
||||
spslr_env_panic("failed to get initial field offset");
|
||||
|
||||
res -= offset;
|
||||
}
|
||||
continue;
|
||||
break;
|
||||
case SPSLR_IPIN_OP_ADD_CONST:
|
||||
res += op->op0.add_const_value;
|
||||
continue;
|
||||
break;
|
||||
#ifdef SPSLR_SANITY_CHECK
|
||||
default:
|
||||
spslr_env_panic("invalid ipin op");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (end_flag)
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
static void seed_rand_time() {
|
||||
void seed_rand_time() {
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
@ -333,8 +333,6 @@ int spslr_randomize(uint32_t target) {
|
||||
if (t->field_count != t->present_field_count)
|
||||
return -1;
|
||||
|
||||
seed_rand_time(); // Note -> this is obviously not sufficient
|
||||
|
||||
uint32_t shuffle_count = t->field_count * 2;
|
||||
for (uint32_t i = 0; i < shuffle_count; i++)
|
||||
target_shuffle_one(t);
|
||||
@ -355,9 +353,9 @@ int spslr_randomize(uint32_t target) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spslr_get_randomized_field_offset(uint32_t target, uint32_t field, uint32_t* offset) {
|
||||
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 || !offset)
|
||||
if (!t)
|
||||
return -1;
|
||||
|
||||
if (field >= t->field_count)
|
||||
@ -366,7 +364,12 @@ int spslr_get_randomized_field_offset(uint32_t target, uint32_t field, uint32_t*
|
||||
if (!t->final_fields)
|
||||
return -1;
|
||||
|
||||
*offset = t->final_fields[field].offset;
|
||||
if (offset)
|
||||
*offset = t->final_fields[field].offset;
|
||||
|
||||
if (initial_offset)
|
||||
*initial_offset = t->final_fields[field].initial_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -3,11 +3,13 @@
|
||||
|
||||
#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);
|
||||
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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user