Skip to content

Commit

Permalink
memory: Optimize gum_memory_write for Linux/Android
Browse files Browse the repository at this point in the history
  • Loading branch information
DoranekoSystems committed Jan 26, 2025
1 parent f61b78b commit ff4664e
Showing 1 changed file with 56 additions and 3 deletions.
59 changes: 56 additions & 3 deletions gum/backend-linux/gummemory-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,26 @@

#if defined (HAVE_I386) && GLIB_SIZEOF_VOID_P == 4
# define GUM_SYS_PROCESS_VM_READV 347
# define GUM_SYS_PROCESS_VM_WRITEV 348
#elif defined (HAVE_I386) && GLIB_SIZEOF_VOID_P == 8
# define GUM_SYS_PROCESS_VM_READV 310
# define GUM_SYS_PROCESS_VM_WRITEV 311
#elif defined (HAVE_ARM)
# define GUM_SYS_PROCESS_VM_READV (__NR_SYSCALL_BASE + 376)
# define GUM_SYS_PROCESS_VM_WRITEV (__NR_SYSCALL_BASE + 377)
#elif defined (HAVE_ARM64)
# define GUM_SYS_PROCESS_VM_READV 270
# define GUM_SYS_PROCESS_VM_WRITEV 271
#elif defined (HAVE_MIPS)
# if _MIPS_SIM == _MIPS_SIM_ABI32
# define GUM_SYS_PROCESS_VM_READV (__NR_Linux + 345)
# define GUM_SYS_PROCESS_VM_WRITEV (__NR_Linux + 346)
# elif _MIPS_SIM == _MIPS_SIM_ABI64
# define GUM_SYS_PROCESS_VM_READV (__NR_Linux + 304)
# define GUM_SYS_PROCESS_VM_WRITEV (__NR_Linux + 305)
# elif _MIPS_SIM == _MIPS_SIM_NABI32
# define GUM_SYS_PROCESS_VM_READV (__NR_Linux + 309)
# define GUM_SYS_PROCESS_VM_WRITEV (__NR_Linux + 310)
# else
# error Unexpected MIPS ABI
# endif
Expand All @@ -48,6 +55,11 @@ static gssize gum_libc_process_vm_readv (pid_t pid,
const struct iovec * remote_iov, gulong riovcnt,
gulong flags);

static gssize gum_libc_process_vm_writev (pid_t pid,
const struct iovec * local_iov, gulong liovcnt,
const struct iovec * remote_iov, gulong riovcnt,
gulong flags);

gboolean
gum_memory_is_readable (gconstpointer address,
gsize len)
Expand Down Expand Up @@ -152,11 +164,40 @@ gum_memory_write (gpointer address,
gsize len)
{
gboolean success = FALSE;
static gboolean kernel_feature_likely_enabled = TRUE;
gboolean still_pending = TRUE;

if (kernel_feature_likely_enabled && gum_linux_check_kernel_version (3, 2, 0))
{
gssize n;
struct iovec local_iov = {
.iov_base = (void *) bytes,
.iov_len = len
};
struct iovec remote_iov = {
.iov_base = address,
.iov_len = len
};

n = gum_libc_process_vm_writev (getpid (), &local_iov, 1, &remote_iov, 1, 0);
if (n > 0)
{
success = (n == len);
}

if (gum_memory_is_writable (address, len))
if (n == -1 && errno == ENOSYS)
kernel_feature_likely_enabled = FALSE;
else
still_pending = FALSE;
}

if (still_pending)
{
memcpy (address, bytes, len);
success = TRUE;
if (gum_memory_is_writable (address, len))
{
memcpy (address, bytes, len);
success = TRUE;
}
}

return success;
Expand Down Expand Up @@ -320,3 +361,15 @@ gum_libc_process_vm_readv (pid_t pid,
return syscall (GUM_SYS_PROCESS_VM_READV, pid, local_iov, liovcnt, remote_iov,
riovcnt, flags);
}

static gssize
gum_libc_process_vm_writev (pid_t pid,
const struct iovec * local_iov,
gulong liovcnt,
const struct iovec * remote_iov,
gulong riovcnt,
gulong flags)
{
return syscall (GUM_SYS_PROCESS_VM_WRITEV, pid, local_iov, liovcnt, remote_iov,
riovcnt, flags);
}

0 comments on commit ff4664e

Please sign in to comment.