diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 98a21a3418..38c1d30f89 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -1149,6 +1149,22 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, UNICORN_EXPORT uc_err uc_hook_del(uc_engine *uc, uc_hook hh); +/* + change the user data from a hook callback. + This change the user-defined data for a given hook. + NOTE: It's undefinde behavior when called on a hook which was not initialized + by uc_hook_add or deleted by uc_hook_delete + @uc: handle returned by uc_open() + @hh: handle returned by uc_hook_add() + @user_data: user-defined data. This will be passed to callback function in its + last argument @user_data + + @return UC_ERR_OK on success, or UC_ERR_ARG when the hook was block or code + hook and emulation is runnings +*/ +UNICORN_EXPORT +uc_err uc_hook_set_user_data(uc_engine *uc, uc_hook hh, void *user_data); + /* Variables to control which state should be stored in the context. Defaults to UC_CTL_CONTEXT_CPU. The options are used in a bitfield diff --git a/uc.c b/uc.c index 1de8a5b98f..940aee21a0 100644 --- a/uc.c +++ b/uc.c @@ -2060,6 +2060,24 @@ uc_err uc_hook_del(uc_engine *uc, uc_hook hh) return UC_ERR_OK; } +UNICORN_EXPORT +uc_err uc_hook_set_user_data(uc_engine *uc, uc_hook hh, void *user_data) +{ + struct hook *hook = (struct hook *)hh; + if (hook->type == UC_HOOK_BLOCK || hook->type == UC_HOOK_CODE) { + if (uc->nested_level) { + return UC_ERR_ARG; + } + if (hook->end < hook->begin) { + uc->tb_flush(uc); + } else { + uc->uc_invalidate_tb(uc, hook->begin, hook->end - hook->begin); + } + } + hook->user_data = user_data; + return UC_ERR_OK; +} + // TCG helper // 2 arguments are enough for most opcodes. Load/Store needs 3 arguments but we // have memory hooks already. We may exceed the maximum arguments of a tcg