Skip to content

Commit

Permalink
process: add get_main_module()
Browse files Browse the repository at this point in the history
This returns a copy of the details of the module which represents the
main executable of the process.

It is exposed to JS via the `Process.mainModule` property.

For darwin this is implemented by getting the first loaded module for
which the Mach-O header's `filetype` is set to `MH_EXECUTE`. For all
other archs it is currently just the first loaded module (equivalent to
Process.enumerateModules()[0]).
  • Loading branch information
mrmacete committed Nov 23, 2023
1 parent ed4f171 commit 46a4218
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 1 deletion.
16 changes: 16 additions & 0 deletions bindings/gumjs/gumquickprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct _GumQuickFindRangeByAddressContext
GumQuickCore * core;
};

GUMJS_DECLARE_GETTER (gumjs_process_get_main_module)
GUMJS_DECLARE_FUNCTION (gumjs_process_get_current_dir)
GUMJS_DECLARE_FUNCTION (gumjs_process_get_home_dir)
GUMJS_DECLARE_FUNCTION (gumjs_process_get_tmp_dir)
Expand Down Expand Up @@ -114,6 +115,7 @@ static const JSCFunctionListEntry gumjs_process_entries[] =
JS_PROP_STRING_DEF ("arch", GUM_SCRIPT_ARCH, JS_PROP_C_W_E),
JS_PROP_STRING_DEF ("platform", GUM_SCRIPT_PLATFORM, JS_PROP_C_W_E),
JS_PROP_INT32_DEF ("pointerSize", GLIB_SIZEOF_VOID_P, JS_PROP_C_W_E),
JS_CGETSET_DEF ("mainModule", gumjs_process_get_main_module, NULL),
JS_CFUNC_DEF ("getCurrentDir", 0, gumjs_process_get_current_dir),
JS_CFUNC_DEF ("getHomeDir", 0, gumjs_process_get_home_dir),
JS_CFUNC_DEF ("getTmpDir", 0, gumjs_process_get_tmp_dir),
Expand Down Expand Up @@ -162,12 +164,14 @@ _gum_quick_process_init (GumQuickProcess * self,
void
_gum_quick_process_flush (GumQuickProcess * self)
{
g_clear_pointer (&self->main_module, gum_module_details_free);
g_clear_pointer (&self->exception_handler, gum_quick_exception_handler_free);
}

void
_gum_quick_process_dispose (GumQuickProcess * self)
{
g_clear_pointer (&self->main_module, gum_module_details_free);
g_clear_pointer (&self->exception_handler, gum_quick_exception_handler_free);
}

Expand All @@ -182,6 +186,18 @@ gumjs_get_parent_module (GumQuickCore * core)
return _gum_quick_core_load_module_data (core, "process");
}

GUMJS_DEFINE_GETTER (gumjs_process_get_main_module)
{
GumQuickProcess * self;

self = gumjs_get_parent_module (core);

if (self->main_module == NULL)
self->main_module = gum_process_get_main_module ();

return _gum_quick_module_new (ctx, self->main_module, self->module);
}

GUMJS_DEFINE_FUNCTION (gumjs_process_get_current_dir)
{
JSValue result;
Expand Down
3 changes: 3 additions & 0 deletions bindings/gumjs/gumquickprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "gumquickcore.h"
#include "gumquickmodule.h"

#include <gum/gumprocess.h>

G_BEGIN_DECLS

typedef struct _GumQuickProcess GumQuickProcess;
Expand All @@ -21,6 +23,7 @@ struct _GumQuickProcess
GumQuickCore * core;

GumQuickExceptionHandler * exception_handler;
GumModuleDetails * main_module;
};

G_GNUC_INTERNAL void _gum_quick_process_init (GumQuickProcess * self,
Expand Down
27 changes: 26 additions & 1 deletion bindings/gumjs/gumv8process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ struct GumV8FindModuleByNameContext
GumV8Process * parent;
};

GUMJS_DECLARE_GETTER (gumjs_process_get_main_module)
GUMJS_DECLARE_FUNCTION (gumjs_process_get_current_dir)
GUMJS_DECLARE_FUNCTION (gumjs_process_get_home_dir)
GUMJS_DECLARE_FUNCTION (gumjs_process_get_tmp_dir)
Expand Down Expand Up @@ -93,6 +94,13 @@ static gboolean gum_v8_exception_handler_on_exception (

const gchar * gum_v8_script_exception_type_to_string (GumExceptionType type);

static const GumV8Property gumjs_process_values[] =
{
{ "mainModule", gumjs_process_get_main_module, NULL },

{ NULL, NULL }
};

static const GumV8Function gumjs_process_functions[] =
{
{ "getCurrentDir", gumjs_process_get_current_dir },
Expand Down Expand Up @@ -136,7 +144,11 @@ _gum_v8_process_init (GumV8Process * self,
process->Set (_gum_v8_string_new_ascii (isolate, "codeSigningPolicy"),
String::NewFromUtf8 (isolate, gum_code_signing_policy_to_string (
gum_process_get_code_signing_policy ())).ToLocalChecked (), ReadOnly);
_gum_v8_module_add (External::New (isolate, self), process,

auto process_module = External::New (isolate, self);

_gum_v8_module_add (process_module, process, gumjs_process_values, isolate);
_gum_v8_module_add (process_module, process,
gumjs_process_functions, isolate);
}

Expand All @@ -148,12 +160,14 @@ _gum_v8_process_realize (GumV8Process * self)
void
_gum_v8_process_flush (GumV8Process * self)
{
g_clear_pointer (&self->main_module, gum_module_details_free);
g_clear_pointer (&self->exception_handler, gum_v8_exception_handler_free);
}

void
_gum_v8_process_dispose (GumV8Process * self)
{
g_clear_pointer (&self->main_module, gum_module_details_free);
g_clear_pointer (&self->exception_handler, gum_v8_exception_handler_free);
}

Expand All @@ -162,6 +176,17 @@ _gum_v8_process_finalize (GumV8Process * self)
{
}

GUMJS_DEFINE_GETTER (gumjs_process_get_main_module)
{
auto self = module;

if (self->main_module == NULL)
self->main_module = gum_process_get_main_module ();

info.GetReturnValue ().Set (_gum_v8_module_value_new (self->main_module,
self->module));
}

GUMJS_DEFINE_FUNCTION (gumjs_process_get_current_dir)
{
gchar * dir_opsys = g_get_current_dir ();
Expand Down
3 changes: 3 additions & 0 deletions bindings/gumjs/gumv8process.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "gumv8core.h"
#include "gumv8module.h"

#include <gum/gumprocess.h>

struct GumV8ExceptionHandler;

struct GumV8Process
Expand All @@ -18,6 +20,7 @@ struct GumV8Process
GumV8Core * core;

GumV8ExceptionHandler * exception_handler;
GumModuleDetails * main_module;
};

G_GNUC_INTERNAL void _gum_v8_process_init (GumV8Process * self,
Expand Down
18 changes: 18 additions & 0 deletions gum/backend-darwin/gumprocess-darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,24 @@ _gum_process_enumerate_ranges (GumPageProtection prot,
gum_darwin_enumerate_ranges (mach_task_self (), prot, func, user_data);
}

gboolean
_gum_process_match_main_module (const GumModuleDetails * details,
gpointer user_data)
{
GumModuleDetails ** out = user_data;
gum_mach_header_t * header;

header = details->range->base_address;
if (header->filetype == MH_EXECUTE)
{
*out = gum_module_details_copy (details);

return FALSE;
}

return TRUE;
}

void
gum_process_enumerate_malloc_ranges (GumFoundMallocRangeFunc func,
gpointer user_data)
Expand Down
11 changes: 11 additions & 0 deletions gum/backend-freebsd/gumprocess-freebsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,17 @@ gum_emit_module_from_phdr (struct dl_phdr_info * info,
return carry_on ? 0 : 1;
}

gboolean
_gum_process_match_main_module (const GumModuleDetails * details,
gpointer user_data)
{
GumModuleDetails ** out = user_data;

*out = gum_module_details_copy (details);

return FALSE;
}

void
_gum_process_enumerate_ranges (GumPageProtection prot,
GumFoundRangeFunc func,
Expand Down
11 changes: 11 additions & 0 deletions gum/backend-linux/gumprocess-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,17 @@ gum_linux_enumerate_modules_using_proc_maps (GumFoundModuleFunc func,
gum_proc_maps_iter_destroy (&iter);
}

gboolean
_gum_process_match_main_module (const GumModuleDetails * details,
gpointer user_data)
{
GumModuleDetails ** out = user_data;

*out = gum_module_details_copy (details);

return FALSE;
}

GHashTable *
gum_linux_collect_named_ranges (void)
{
Expand Down
11 changes: 11 additions & 0 deletions gum/backend-qnx/gumprocess-qnx.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,17 @@ _gum_process_enumerate_modules (GumFoundModuleFunc func,
dlclose (handle);
}

gboolean
_gum_process_match_main_module (const GumModuleDetails * details,
gpointer user_data)
{
GumModuleDetails ** out = user_data;

*out = gum_module_details_copy (details);

return FALSE;
}

void
gum_qnx_enumerate_ranges (pid_t pid,
GumPageProtection prot,
Expand Down
11 changes: 11 additions & 0 deletions gum/backend-windows/gumprocess-windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,17 @@ _gum_process_enumerate_ranges (GumPageProtection prot,
}
}

gboolean
_gum_process_match_main_module (const GumModuleDetails * details,
gpointer user_data)
{
GumModuleDetails ** out = user_data;

*out = gum_module_details_copy (details);

return FALSE;
}

void
gum_process_enumerate_malloc_ranges (GumFoundMallocRangeFunc func,
gpointer user_data)
Expand Down
2 changes: 2 additions & 0 deletions gum/gumprocess-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ G_GNUC_INTERNAL void _gum_process_enumerate_modules (GumFoundModuleFunc func,
gpointer user_data);
G_GNUC_INTERNAL void _gum_process_enumerate_ranges (GumPageProtection prot,
GumFoundRangeFunc func, gpointer user_data);
G_GNUC_INTERNAL gboolean _gum_process_match_main_module (
const GumModuleDetails * details, gpointer user_data);

G_END_DECLS

Expand Down
16 changes: 16 additions & 0 deletions gum/gumprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,22 @@ gum_process_enumerate_modules (GumFoundModuleFunc func,
_gum_process_enumerate_modules (gum_emit_module_if_not_cloaked, &ctx);
}

/**
* gum_process_get_main_module:
*
* Returns a copy of the details of the module representing the main executable
* of the process. Result must be freed with gum_module_details_free ();
*/
GumModuleDetails *
gum_process_get_main_module (void)
{
GumModuleDetails * result;

gum_process_enumerate_modules (_gum_process_match_main_module, &result);

return result;
}

static gboolean
gum_emit_module_if_not_cloaked (const GumModuleDetails * details,
gpointer user_data)
Expand Down
1 change: 1 addition & 0 deletions gum/gumprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ GUM_API gboolean gum_process_resolve_module_pointer (gconstpointer ptr,
gchar ** path, GumMemoryRange * range);
GUM_API void gum_process_enumerate_modules (GumFoundModuleFunc func,
gpointer user_data);
GUM_API GumModuleDetails * gum_process_get_main_module (void);
GUM_API void gum_process_enumerate_ranges (GumPageProtection prot,
GumFoundRangeFunc func, gpointer user_data);
GUM_API void gum_process_enumerate_malloc_ranges (
Expand Down

0 comments on commit 46a4218

Please sign in to comment.