Skip to content

Commit

Permalink
gumjs: Expose more Memory APIs to CModule
Browse files Browse the repository at this point in the history
  • Loading branch information
hillelpinto authored and oleavr committed May 31, 2024
1 parent 51741dd commit e5d0b3e
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
40 changes: 40 additions & 0 deletions bindings/gumjs/runtime/cmodule/gum/gummemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "gumdefs.h"

typedef guint GumPtrauthSupport;
typedef guint GumPageProtection;
typedef struct _GumMatchPattern GumMatchPattern;

enum _GumPtrauthSupport
{
Expand All @@ -12,10 +14,48 @@ enum _GumPtrauthSupport
GUM_PTRAUTH_SUPPORTED
};

enum _GumPageProtection
{
GUM_PAGE_NO_ACCESS = 0,
GUM_PAGE_READ = (1 << 0),
GUM_PAGE_WRITE = (1 << 1),
GUM_PAGE_EXECUTE = (1 << 2),
};

typedef void (* GumMemoryPatchApplyFunc) (gpointer mem, gpointer user_data);
typedef gboolean (* GumMemoryScanMatchFunc) (GumAddress address, gsize size,
gpointer user_data);

gpointer gum_sign_code_pointer (gpointer value);
gpointer gum_strip_code_pointer (gpointer value);
GumAddress gum_sign_code_address (GumAddress value);
GumAddress gum_strip_code_address (GumAddress value);
GumPtrauthSupport gum_query_ptrauth_support (void);
gboolean gum_memory_query_protection (gconstpointer address,
GumPageProtection * prot);
guint8 * gum_memory_read (gconstpointer address, gsize len,
gsize * n_bytes_read);
gboolean gum_memory_write (gpointer address, const guint8 * bytes, gsize len);
gboolean gum_memory_patch_code (gpointer address, gsize size,
GumMemoryPatchApplyFunc apply, gpointer apply_data);
gboolean gum_memory_mark_code (gpointer address, gsize size);

void gum_memory_scan (const GumMemoryRange * range,
const GumMatchPattern * pattern, GumMemoryScanMatchFunc func,
gpointer user_data);

GumMatchPattern * gum_match_pattern_new_from_string (
const gchar * pattern_str);
GumMatchPattern * gum_match_pattern_ref (GumMatchPattern * pattern);
void gum_match_pattern_unref (GumMatchPattern * pattern);
guint gum_match_pattern_get_size (const GumMatchPattern * pattern);

void gum_ensure_code_readable (gconstpointer address, gsize size);

void gum_mprotect (gpointer address, gsize size, GumPageProtection prot);
gboolean gum_try_mprotect (gpointer address, gsize size,
GumPageProtection prot);

void gum_clear_cache (gpointer address, gsize size);

#endif
68 changes: 68 additions & 0 deletions tests/gumjs/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Copyright (C) 2020 Marcus Mengs <[email protected]>
* Copyright (C) 2021 Abdelrahman Eid <[email protected]>
* Copyright (C) 2023 Grant Douglas <[email protected]>
* Copyright (C) 2024 Hillel Pinto <[email protected]>
*
* Licence: wxWindows Library Licence, Version 3.1
*/
Expand Down Expand Up @@ -364,6 +365,7 @@ TESTLIST_BEGIN (script)
TESTENTRY (cmodule_can_be_used_with_stalker_call_probe)
TESTENTRY (cmodule_can_be_used_with_module_map)
TESTENTRY (cmodule_should_provide_some_builtin_string_functions)
TESTENTRY (cmodule_should_provide_memory_access_apis)
TESTENTRY (cmodule_should_support_memory_builtins)
TESTENTRY (cmodule_should_support_arithmetic_builtins)
TESTENTRY (cmodule_should_support_floating_point)
Expand Down Expand Up @@ -9922,6 +9924,72 @@ TESTCASE (cmodule_should_provide_some_builtin_string_functions)
g_assert_cmpint (score_impl ("w00tage"), ==, 9);
}

TESTCASE (cmodule_should_provide_memory_access_apis)
{
gboolean (* scan) (const guint8 * p, guint8 ** match);
guint8 * match;
const guint8 haystack[] = { 0x11, 0x22, 0x33, 0x13, 0x37, 0x44, 0x42, 0x55 };

COMPILE_AND_LOAD_SCRIPT (
"const m = new CModule(`"
"#include <gum/gummemory.h>\\n"
"\\n"
"static gboolean store_match (GumAddress address, gsize size,\\n"
" gpointer user_data);\\n"
"\\n"
"gboolean\\n"
"scan (const guint8 * p,\\n"
" guint8 ** match)\\n"
"{\\n"
" guint8 * data;\\n"
" gsize n_bytes_read;\\n"
" GumMemoryRange range;\\n"
" GumMatchPattern * pattern;\\n"
"\\n"
" *match = NULL;\\n"
"\\n"
" data = gum_memory_read (p, 8, &n_bytes_read);\\n"
" if (data == NULL || n_bytes_read != 8)\\n"
" return FALSE;\\n"
"\\n"
" range.base_address = GUM_ADDRESS (data);\\n"
" range.size = 8;\\n"
" pattern = gum_match_pattern_new_from_string (\"13 37 ?? 42\");\\n"
" gum_memory_scan (&range, pattern, store_match, match);\\n"
"\\n"
" gum_match_pattern_unref (pattern);\\n"
" g_free (data);\\n"
"\\n"
" return TRUE;\\n"
"}\\n"
"\\n"
"static gboolean\\n"
"store_match (GumAddress address,\\n"
" gsize size,\\n"
" gpointer user_data)\\n"
"{\\n"
" guint8 ** match = user_data;\\n"
" *match = g_memdup (GSIZE_TO_POINTER (address), size);\\n"
" return FALSE;\\n"
"}\\n"
"`);"
"send(m.scan);");

scan = EXPECT_SEND_MESSAGE_WITH_POINTER ();
g_assert_nonnull (scan);

g_assert_false (scan (GSIZE_TO_POINTER (42), &match));
g_assert_null (match);

g_assert_true (scan (haystack, &match));
g_assert_nonnull (match);
g_assert_cmphex (match[0], ==, 0x13);
g_assert_cmphex (match[1], ==, 0x37);
g_assert_cmphex (match[2], ==, 0x44);
g_assert_cmphex (match[3], ==, 0x42);
g_free (match);
}

TESTCASE (cmodule_should_support_memory_builtins)
{
int (* f) (void);
Expand Down

0 comments on commit e5d0b3e

Please sign in to comment.