Skip to content

Instantly share code, notes, and snippets.

@aont
Last active June 30, 2025 08:35
Show Gist options
  • Select an option

  • Save aont/be7ac2a28babc07ea682dbe25d464280 to your computer and use it in GitHub Desktop.

Select an option

Save aont/be7ac2a28babc07ea682dbe25d464280 to your computer and use it in GitHub Desktop.

Binding Functions with Frida Gum (x86 / x86-64)

Purpose Generate at run-time a zero-argument function that always calls a given 2-argument function with two fixed constants, using Frida Gum’s GumX86Writer.

Build (Linux example)

g++ bound_function.cpp -o bound -I./frida -L./frida -lfrida-gum

Run

./bound        # prints:  Result = 142
#include <frida-gum.h>
#include <cstdio>
#include <cstdint>
using FuncWithArgs = int (*)(int, int);
using FuncNoArgs = int (*)();
static FuncNoArgs
make_bound_function (FuncWithArgs target, int arg0, int arg1)
{
/* RW ページを 1 枚確保 */
gpointer code = gum_alloc_n_pages (1, GUM_PAGE_RW);
g_assert (code != NULL);
GumX86Writer cw;
gum_x86_writer_init (&cw, code);
#if GLIB_SIZEOF_VOID_P == 8 /* ========== x86-64 ========== */
gum_x86_writer_set_target_cpu (&cw, GUM_CPU_AMD64);
# if defined (_MSC_VER) /* Windows ABI: RCX, RDX */
gum_x86_writer_put_sub_reg_imm (&cw, GUM_X86_RSP, 40);
gum_x86_writer_put_mov_reg_u64 (&cw, GUM_X86_RCX, (guint64) arg0);
gum_x86_writer_put_mov_reg_u64 (&cw, GUM_X86_RDX, (guint64) arg1);
# else /* SysV: RDI, RSI */
gum_x86_writer_put_sub_reg_imm (&cw, GUM_X86_RSP, 8);
gum_x86_writer_put_mov_reg_u64 (&cw, GUM_X86_RDI, (guint64) arg0);
gum_x86_writer_put_mov_reg_u64 (&cw, GUM_X86_RSI, (guint64) arg1);
# endif
gum_x86_writer_put_mov_reg_address (&cw,
GUM_X86_RAX, GUM_ADDRESS (target));
gum_x86_writer_put_call_reg (&cw, GUM_X86_RAX);
# if defined (_MSC_VER)
gum_x86_writer_put_add_reg_imm (&cw, GUM_X86_RSP, 40);
# else
gum_x86_writer_put_add_reg_imm (&cw, GUM_X86_RSP, 8);
# endif
#else /* ========== x86 (32-bit) ========== */
gum_x86_writer_set_target_cpu (&cw, GUM_CPU_IA32);
gum_x86_writer_put_push_u32 (&cw, arg1);
gum_x86_writer_put_push_u32 (&cw, arg0);
gum_x86_writer_put_mov_reg_address (&cw,
GUM_X86_EAX, GUM_ADDRESS (target));
gum_x86_writer_put_call_reg (&cw, GUM_X86_EAX);
gum_x86_writer_put_add_reg_imm (&cw, GUM_X86_ESP, 8);
#endif
gum_x86_writer_put_ret (&cw);
gum_x86_writer_flush (&cw);
/* RX へ変更 */
gsize page_size = gum_query_page_size ();
gum_mprotect (code, page_size, GUM_PAGE_RX);
return reinterpret_cast<FuncNoArgs> (code);
}
/* テスト用 2 引数関数 */
extern "C" int add (int a, int b)
{
return a + b;
}
int main ()
{
/* -------- frida-gum 初期化 -------- */
gum_init_embedded();
auto fn = make_bound_function (add, 42, 100);
std::printf ("Result = %d\n", fn ()); // 142
gum_deinit_embedded();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment