From 16c7074019f93ed17ad44a0cd3c308200a48bb12 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 26 Feb 2024 13:53:07 +0000 Subject: [PATCH] Add support for Windows --- gum/backend-windows/gumprocess-windows.c | 33 +++++++++++++++++++++++- tests/core/process.c | 9 ++++--- tests/gumjs/script.c | 9 ++++--- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/gum/backend-windows/gumprocess-windows.c b/gum/backend-windows/gumprocess-windows.c index 432db24de..a4197ef4d 100644 --- a/gum/backend-windows/gumprocess-windows.c +++ b/gum/backend-windows/gumprocess-windows.c @@ -27,6 +27,9 @@ typedef void (WINAPI * GumGetCurrentThreadStackLimitsFunc) ( PULONG_PTR low_limit, PULONG_PTR high_limit); typedef struct _GumEnumerateSymbolsContext GumEnumerateSymbolsContext; typedef struct _GumFindExportContext GumFindExportContext; +typedef BOOL (WINAPI * GetThreadTimesFunc) (HANDLE ThreadHandle, + LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, + LPFILETIME lpUserTime); struct _GumEnumerateSymbolsContext { @@ -640,7 +643,35 @@ gum_thread_resume (GumThreadId thread_id, guint64 gum_thead_get_user_time (void) { - return 0; + static gboolean initialized = false; + static GetThreadTimesFunc get_thread_times = NULL; + + HMODULE mod; + FILETIME userTime; + guint64 result; + + if (!initialized) + { + initialized = TRUE; + + mod = GetModuleHandle (_T ("kernel32.dll")); + if (mod == NULL) + return 0; + + get_thread_times =(GetThreadTimesFunc) GetProcAddress (mod, + "GetThreadTimes"); + } + + if (get_thread_times == NULL) + return 0; + + if (!get_thread_times (GetCurrentThread (), NULL, NULL, NULL, &userTime)) + return 0; + + result = ((guint64) userTime.dwHighDateTime) << 32 + userTime.dwLowDateTime; + + /* Timings on Windows are to 100-nanosecond granularity. Convert to u-secs */ + return result / 10; } gboolean diff --git a/tests/core/process.c b/tests/core/process.c index b1f248003..07fa48e96 100644 --- a/tests/core/process.c +++ b/tests/core/process.c @@ -309,7 +309,8 @@ TESTCASE (process_threads_get_user_time) do_work (); user_time_b = gum_thead_get_user_time (); -#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) +#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) \ + || defined (HAVE_WINDOWS) g_assert_cmpuint (user_time_a, !=, 0); g_assert_cmpuint (user_time_b, >, user_time_a); #else @@ -331,7 +332,8 @@ TESTCASE (process_threads_get_user_time_by_id_self) do_work (); user_time_b = gum_thead_get_user_time_by_id (tid); -#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) +#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) \ + || defined (HAVE_WINDOWS) g_assert_cmpuint (user_time_a, !=, 0); g_assert_cmpuint (user_time_b, >, user_time_a); #else @@ -360,7 +362,8 @@ TESTCASE (process_threads_get_user_time_by_id_other) g_usleep (250000); user_time_b = gum_thead_get_user_time_by_id (d.id); -#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) +#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) \ + || defined (HAVE_WINDOWS) g_assert_cmpuint (user_time_a, !=, 0); g_assert_cmpuint (user_time_b, >, user_time_a); #else diff --git a/tests/gumjs/script.c b/tests/gumjs/script.c index 64846273d..360fc4869 100644 --- a/tests/gumjs/script.c +++ b/tests/gumjs/script.c @@ -5183,7 +5183,8 @@ TESTCASE (process_threads_get_user_time) ); EXPECT_NO_MESSAGES (); -#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) +#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) \ + || defined (HAVE_WINDOWS) g_assert_true (user_time_a != 0); g_assert_true (user_time_b > user_time_a); #else @@ -5251,7 +5252,8 @@ TESTCASE (process_threads_get_user_time_other_thread) g_async_queue_unref (ctx.sleeper_messages); g_async_queue_unref (ctx.controller_messages); -#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) +#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) \ + || defined (HAVE_WINDOWS) g_assert_true (user_time_a != 0); g_assert_true (user_time_b > user_time_a); #else @@ -5361,7 +5363,8 @@ TESTCASE (process_threads_find_busy_thread) g_async_queue_unref (ctx[i].controller_messages); } -#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) +#if defined (HAVE_LINUX) || defined (HAVE_DARWIN) || defined (HAVE_FREEBSD) \ + || defined (HAVE_WINDOWS) EXPECT_SEND_MESSAGE_WITH ("%" G_GSIZE_MODIFIER "u", ctx[rand].id); #endif }