#define FN_MAXNUM 32 class FunctionIndex { U64 addr; U64 prologue; } fn_index[FN_MAXNUM]; MemSet(fn_index, 0, sizeof(FunctionIndex)); I64 fn_restore(U32 from) { if (!from) { return -1; } I64 i; for (i = 0; i < FN_MAXNUM; i++) { if (fn_index[i].addr == from) { MemCpy(fn_index[i].addr, &fn_index[i].prologue, 8); fn_index[i].addr = fn_index[i].prologue = 0; return 0; } } return -1; } I64 fn_patch(U32 from, U32 to, Bool patch = TRUE) { if (!from || !to) { return -1; } if (!patch) { return fn_restore(from); } I64 i = 0; while (i < FN_MAXNUM && fn_index[i].addr) { if (fn_index[i].addr == from) { // Function already patched return -1; } ++i; } if (i >= FN_MAXNUM) { // Maximum entires reached return -1; } fn_index[i].addr = from; MemCpy(&fn_index[i].prologue, from, 8); *(from(U8*)) = 0xE9; *((from + 1)(I32*)) = to - from - 5; return 0; }