Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 65 additions & 3 deletions umvu/include/ptrace_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,43 @@
snprintf(errmsg, 80, "%s line %d, ptrace", __FILE__, __LINE__); \
perror(errmsg); \
}

#if defined(__aarch64__)
#define P_GETREGS(tracee_tid, regs) \
do { \
struct iovec iov = { .iov_base = regs, .iov_len = sizeof(arch_regs_struct), }; \
long err; \
if (!(err = r_ptrace(PTRACE_GETREGSET, tracee_tid, NT_PRSTATUS, &iov))) { \
iov.iov_base += sizeof (struct user_regs_struct); \
iov.iov_len = sizeof(int); \
err = r_ptrace(PTRACE_GETREGSET, tracee_tid, NT_ARM_SYSTEM_CALL, &iov); } \
if (err == -1) { \
char errmsg[80]; \
snprintf(errmsg, 80, "%s line %d, ptrace", __FILE__, __LINE__); \
perror(errmsg); \
pthread_exit(NULL); \
} \
} while(0)
#define P_SETREGS(tracee_tid, regs) \
do { \
struct iovec iov = { .iov_base = regs, .iov_len = sizeof(arch_regs_struct), }; \
long err; \
if (!(err = r_ptrace(PTRACE_SETREGSET, tracee_tid, NT_PRSTATUS, &iov))) { \
iov.iov_base += sizeof (struct user_regs_struct); \
iov.iov_len = sizeof(int); \
err = r_ptrace(PTRACE_SETREGSET, tracee_tid, NT_ARM_SYSTEM_CALL, &iov); } \
if (err == -1) { \
char errmsg[80]; \
snprintf(errmsg, 80, "%s line %d, ptrace", __FILE__, __LINE__); \
perror(errmsg); \
pthread_exit(NULL); \
} \
} while(0)
#else
#define P_GETREGS(tracee_tid, regs) \
PTRACE(PTRACE_GETREGSET, tracee_tid, NT_PRSTATUS, &((struct iovec) {regs, sizeof(arch_regs_struct)}))
#define P_SETREGS(tracee_tid, regs) \
PTRACE(PTRACE_SETREGSET, tracee_tid, NT_PRSTATUS, &((struct iovec) {regs, sizeof(arch_regs_struct)}))

#endif
#define P_SYSCALL(tracee_tid, signal) PTRACE(PTRACE_SYSCALL, tracee_tid, 0L, signal)
#define P_CONT(tracee_tid, signal) PTRACE(PTRACE_CONT, tracee_tid, 0L, signal)
#define P_LISTEN(tracee_tid, signal) PTRACE(PTRACE_LISTEN, tracee_tid, 0L, signal)
Expand All @@ -43,13 +74,44 @@
#define P_SETOPT(tracee_tid, opt) PTRACE(PTRACE_SETOPTIONS, tracee_tid, 0L, opt)
#define P_GETEVENTMSG(tracee_tid, event) \
PTRACE(PTRACE_GETEVENTMSG, tracee_tid, 0L, event)

#if defined(__aarch64__)
#define P_GETREGS_NODIE(tracee_tid, regs) \
do { \
struct iovec iov = { .iov_base = regs, .iov_len = sizeof(arch_regs_struct), }; \
long err; \
if (!(err = r_ptrace(PTRACE_GETREGSET, tracee_tid, NT_PRSTATUS, &iov))) { \
iov.iov_base += sizeof (struct user_regs_struct); \
iov.iov_len = sizeof(int); \
err = r_ptrace(PTRACE_GETREGSET, tracee_tid, NT_ARM_SYSTEM_CALL, &iov); } \
if (err == -1) { \
char errmsg[80]; \
snprintf(errmsg, 80, "%s line %d, ptrace", __FILE__, __LINE__); \
perror(errmsg); \
} \
} while(0)
#define P_SETREGS_NODIE(tracee_tid, regs) \
do { \
struct iovec iov = { .iov_base = regs, .iov_len = sizeof(arch_regs_struct), }; \
long err; \
if (!(err = r_ptrace(PTRACE_SETREGSET, tracee_tid, NT_PRSTATUS, &iov))) { \
iov.iov_base += sizeof (struct user_regs_struct); \
iov.iov_len = sizeof(int); \
err = r_ptrace(PTRACE_SETREGSET, tracee_tid, NT_ARM_SYSTEM_CALL, &iov); } \
if (err == -1) { \
char errmsg[80]; \
snprintf(errmsg, 80, "%s line %d, ptrace", __FILE__, __LINE__); \
perror(errmsg); \
pthread_exit(NULL); \
} \
} while(0)
#else
#define P_GETREGS_NODIE(tracee_tid, regs) \
PTRACE_NODIE(PTRACE_GETREGSET, tracee_tid, NT_PRSTATUS, \
&((struct iovec) {regs, sizeof(arch_regs_struct)}))
#define P_SETREGS_NODIE(tracee_tid, regs) \
PTRACE_NODIE(PTRACE_SETREGSET, tracee_tid, NT_PRSTATUS, \
&((struct iovec) {regs, sizeof(arch_regs_struct)}))
#endif
#define P_SYSCALL_NODIE(tracee_tid, signal) \
PTRACE_NODIE(PTRACE_SYSCALL, tracee_tid, 0L, signal)
#define P_CONT_NODIE(tracee_tid, signal) \
Expand Down
23 changes: 22 additions & 1 deletion umvu/include/umvu_peekpoke.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,34 @@ typedef struct user_regs_struct arch_regs_struct;

#elif defined(__riscv_xlen) && __riscv_xlen == 64

#include<asm/ptrace.h>
#include <asm/ptrace.h>

#define SYSCALL_ARG_NR 6
typedef unsigned long int syscall_arg_t;
#define SYSCALL_INSTRUCTION_LEN 4
typedef struct user_regs_struct arch_regs_struct;

#elif defined(__aarch64__)

#include <asm/ptrace.h>
#define SYSCALL_ARG_NR 6
typedef unsigned long int syscall_arg_t;
#define SYSCALL_INSTRUCTION_LEN 4
struct arch_regs_struct_full {
union {
struct user_regs_struct user_regs;
struct {
unsigned long regs[31];
unsigned long sp;
unsigned long pc;
unsigned long pstate;
};
};
int syscallno;
};
typedef struct arch_regs_struct_full arch_regs_struct;
//typedef struct user_regs_struct arch_regs_struct;

#else

#error Unsupported architecture
Expand Down
67 changes: 67 additions & 0 deletions umvu/src/umvu_peekpoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,73 @@ int umvu_poke_syscall(arch_regs_struct *regs,
return 0;
}

#elif defined(__aarch64__)

void umvu_peek_syscall(arch_regs_struct *regs,
struct syscall_descriptor_t *syscall_desc,
peekpokeop_t op)
{
if (regs && syscall_desc) {
if (op == PEEK_ARGS) {
syscall_desc->orig_syscall_number =
syscall_desc->syscall_number = regs->syscallno;
syscall_desc->syscall_args[0] = regs->regs[0];
syscall_desc->syscall_args[1] = regs->regs[1];
syscall_desc->syscall_args[2] = regs->regs[2];
syscall_desc->syscall_args[3] = regs->regs[3];
syscall_desc->syscall_args[4] = regs->regs[4];
syscall_desc->syscall_args[5] = regs->regs[5];
syscall_desc->prog_counter = regs->pc;
syscall_desc->stack_pointer = regs->sp;
} else {
syscall_desc->orig_ret_value = regs->regs[0];
}
}
}

int umvu_poke_syscall(arch_regs_struct *regs,
struct syscall_descriptor_t *syscall_desc,
peekpokeop_t op)
{
if (regs && syscall_desc) {
switch (op) {
case POKE_ARGS:
/* regs->sp is missing as stack pointer should not be modified */
if (regs->syscallno == (unsigned) syscall_desc->syscall_number &&
regs->regs[0] == syscall_desc->syscall_args[0] &&
regs->regs[1] == syscall_desc->syscall_args[1] &&
regs->regs[2] == syscall_desc->syscall_args[2] &&
regs->regs[3] == syscall_desc->syscall_args[3] &&
regs->regs[4] == syscall_desc->syscall_args[4] &&
regs->regs[5] == syscall_desc->syscall_args[5] &&
regs->pc == syscall_desc->prog_counter)
return 0;

regs->syscallno = regs->regs[8] = syscall_desc->syscall_number;
regs->regs[0] = syscall_desc->syscall_args[0];
regs->regs[1] = syscall_desc->syscall_args[1];
regs->regs[2] = syscall_desc->syscall_args[2];
regs->regs[3] = syscall_desc->syscall_args[3];
regs->regs[4] = syscall_desc->syscall_args[4];
regs->regs[5] = syscall_desc->syscall_args[5];
regs->pc = syscall_desc->prog_counter;
break;
case POKE_RETVALUE:
if (regs->regs[0] == syscall_desc->ret_value)
return 0;
regs->regs[0] = syscall_desc->ret_value;
break;
case SKIP_SETRETVALUE:
regs->regs[8] = -1;
regs->regs[0] = syscall_desc->ret_value;
break;
}
return 1;
} else {
return 0;
}
}

#else

#error Unsupported architecture
Expand Down