|
#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; |
|
} |