Fredrik Fornwall
8 years ago
13 changed files with 4 additions and 539 deletions
@ -1,21 +0,0 @@ |
|||
diff -u -r ../PRoot-5.1.0/src/GNUmakefile ./src/GNUmakefile
|
|||
--- ../PRoot-5.1.0/src/GNUmakefile 2014-12-15 09:18:11.000000000 -0500
|
|||
+++ ./src/GNUmakefile 2015-09-04 17:36:29.967980524 -0400
|
|||
@@ -8,8 +8,6 @@
|
|||
GIT = git |
|||
RM = rm |
|||
INSTALL = install |
|||
-CC = $(CROSS_COMPILE)gcc
|
|||
-LD = $(CC)
|
|||
STRIP = $(CROSS_COMPILE)strip |
|||
OBJCOPY = $(CROSS_COMPILE)objcopy |
|||
OBJDUMP = $(CROSS_COMPILE)objdump |
|||
@@ -222,7 +220,7 @@
|
|||
###################################################################### |
|||
# PHONY targets |
|||
|
|||
-PREFIX = /usr/local
|
|||
+PREFIX = @TERMUX_PREFIX@
|
|||
DESTDIR = $(PREFIX)/bin |
|||
|
|||
.PHONY: clean distclean install install-care uninstall |
@ -1,14 +0,0 @@ |
|||
diff -r -u PRoot-next/src/arch.h src/src/arch.h
|
|||
--- PRoot-next/src/arch.h 2015-07-23 21:50:10.000000000 +0200
|
|||
+++ src/src/arch.h 2016-08-17 16:15:24.197684187 +0200
|
|||
@@ -133,6 +133,10 @@
|
|||
#define EXEC_PIC_ADDRESS 0x3000000000 |
|||
#define INTERP_PIC_ADDRESS 0x3f00000000 |
|||
|
|||
+ /* Syscall -2 appears to cause some odd side effects, use -1 */
|
|||
+ #undef SYSCALL_AVOIDER
|
|||
+ #define SYSCALL_AVOIDER ((word_t) -1)
|
|||
+
|
|||
#elif defined(ARCH_X86) |
|||
|
|||
#define SYSNUMS_HEADER1 "syscall/sysnums-i386.h" |
@ -1,27 +0,0 @@ |
|||
diff -u -r ../PRoot-5.1.0/src/cli/cli.c ./src/cli/cli.c
|
|||
--- ../PRoot-5.1.0/src/cli/cli.c 2014-12-15 09:18:11.000000000 -0500
|
|||
+++ ./src/cli/cli.c 2016-01-08 15:16:33.393030857 -0500
|
|||
@@ -30,7 +30,10 @@
|
|||
#include <sys/types.h> /* getpid(2), */ |
|||
#include <unistd.h> /* getpid(2), */ |
|||
#include <errno.h> /* errno(3), */ |
|||
+#include <libgen.h> /* basename(3), */
|
|||
+#ifndef __ANDROID__
|
|||
#include <execinfo.h> /* backtrace_symbols(3), */ |
|||
+#endif
|
|||
#include <limits.h> /* INT_MAX, */ |
|||
|
|||
#include "cli/cli.h" |
|||
@@ -558,7 +560,12 @@
|
|||
void *const pointers[] = { this_function, call_site }; |
|||
char **symbols = NULL; |
|||
|
|||
+#ifdef __ANDROID__
|
|||
+ fprintf(stderr, "backtrace_symbols() not available on Android\n");
|
|||
+ exit(1);
|
|||
+#else
|
|||
symbols = backtrace_symbols(pointers, 2); |
|||
+#endif
|
|||
if (symbols == NULL) |
|||
goto end; |
|||
|
@ -1,42 +0,0 @@ |
|||
--- PRoot-5.1.0/src/execve/enter.c 2014-12-15 15:18:11.000000000 +0100
|
|||
+++ src/src/execve/enter.c 2016-03-20 12:05:08.013426156 +0100
|
|||
@@ -454,10 +454,10 @@
|
|||
} |
|||
|
|||
extern unsigned char _binary_loader_exe_start; |
|||
-extern unsigned char _binary_loader_exe_size;
|
|||
+extern unsigned char _binary_loader_exe_end;
|
|||
|
|||
extern unsigned char WEAK _binary_loader_m32_exe_start; |
|||
-extern unsigned char WEAK _binary_loader_m32_exe_size;
|
|||
+extern unsigned char WEAK _binary_loader_m32_exe_end;
|
|||
|
|||
/** |
|||
* Extract the built-in loader. This function returns NULL if an |
|||
@@ -483,11 +483,11 @@
|
|||
|
|||
if (wants_32bit_version) { |
|||
start = (void *) &_binary_loader_m32_exe_start; |
|||
- size = (size_t) &_binary_loader_m32_exe_size;
|
|||
+ size = (size_t) (&_binary_loader_m32_exe_end - &_binary_loader_m32_exe_start);
|
|||
} |
|||
else { |
|||
start = (void *) &_binary_loader_exe_start; |
|||
- size = (size_t) &_binary_loader_exe_size;
|
|||
+ size = (size_t) (&_binary_loader_exe_end - &_binary_loader_exe_start);
|
|||
} |
|||
|
|||
status2 = write(fd, start, size); |
|||
@@ -645,8 +645,10 @@
|
|||
|
|||
/* An ELF interpreter is supposed to be |
|||
* standalone. */ |
|||
- if (tracee->load_info->interp->interp != NULL)
|
|||
- return -EINVAL;
|
|||
+ if (tracee->load_info->interp->interp != NULL) {
|
|||
+ TALLOC_FREE(tracee->load_info->interp->interp);
|
|||
+ // TODO: Print warning?
|
|||
+ }
|
|||
} |
|||
|
|||
compute_load_addresses(tracee); |
@ -1,29 +0,0 @@ |
|||
diff -u -r ../PRoot-5.1.0/src/path/temp.c ./src/path/temp.c
|
|||
--- ../PRoot-5.1.0/src/path/temp.c 2014-12-15 09:18:11.000000000 -0500
|
|||
+++ ./src/path/temp.c 2016-01-08 19:40:46.901462550 -0500
|
|||
@@ -120,9 +120,14 @@
|
|||
{ |
|||
int result; |
|||
int status; |
|||
- char *cwd;
|
|||
|
|||
+#ifdef __ANDROID__
|
|||
+ char cwd[PATH_MAX];
|
|||
+ getcwd(cwd, PATH_MAX);
|
|||
+#else
|
|||
+ char *cwd;
|
|||
cwd = get_current_dir_name(); |
|||
+#endif
|
|||
|
|||
status = chmod(path, 0700); |
|||
if (status < 0) { |
|||
@@ -163,7 +168,9 @@
|
|||
result = -1; |
|||
note(NULL, ERROR, SYSTEM, "can't chdir to '%s'", cwd); |
|||
} |
|||
+#ifndef __ANDROID__
|
|||
free(cwd); |
|||
+#endif
|
|||
} |
|||
|
|||
return result; |
@ -1,26 +0,0 @@ |
|||
diff -u -r ../PRoot-5.1.0/src/ptrace/ptrace.c ./src/ptrace/ptrace.c
|
|||
--- ../PRoot-5.1.0/src/ptrace/ptrace.c 2014-12-15 09:18:11.000000000 -0500
|
|||
+++ ./src/ptrace/ptrace.c 2016-01-08 15:12:27.089144325 -0500
|
|||
@@ -27,6 +27,7 @@
|
|||
#include <signal.h> /* siginfo_t, */ |
|||
#include <sys/uio.h> /* struct iovec, */ |
|||
#include <sys/param.h> /* MIN(), MAX(), */ |
|||
+#include <sys/wait.h> /* __WALL */
|
|||
#include <string.h> /* memcpy(3), */ |
|||
|
|||
#include "ptrace/ptrace.h" |
|||
@@ -58,7 +59,13 @@
|
|||
#define user_fpregs_struct user_fpsimd_struct |
|||
#endif |
|||
|
|||
-static const char *stringify_ptrace(enum __ptrace_request request)
|
|||
+static const char *stringify_ptrace(
|
|||
+#ifdef __ANDROID__
|
|||
+ int
|
|||
+#else
|
|||
+ enum __ptrace_request
|
|||
+#endif
|
|||
+ request)
|
|||
{ |
|||
#define CASE_STR(a) case a: return #a; break; |
|||
switch ((int) request) { |
@ -1,12 +0,0 @@ |
|||
diff -u -r ../PRoot-5.1.0/src/ptrace/wait.h ./src/ptrace/wait.h
|
|||
--- ../PRoot-5.1.0/src/ptrace/wait.h 2014-12-15 09:18:11.000000000 -0500
|
|||
+++ ./src/ptrace/wait.h 2016-01-08 09:07:20.342650218 -0500
|
|||
@@ -25,6 +25,8 @@
|
|||
|
|||
#include "tracee/tracee.h" |
|||
|
|||
+#include <sys/wait.h> /* for __WALL */
|
|||
+
|
|||
extern int translate_wait_enter(Tracee *ptracer); |
|||
extern int translate_wait_exit(Tracee *ptracer); |
|||
extern bool handle_ptracee_event(Tracee *ptracee, int wait_status); |
@ -1,32 +0,0 @@ |
|||
On 32-bit prlimit() does not exist. prlimit64 however exists on both. |
|||
|
|||
diff -u -r ../PRoot-next/src/syscall/rlimit.c ./src/syscall/rlimit.c
|
|||
--- ../PRoot-next/src/syscall/rlimit.c 2015-07-23 15:50:10.000000000 -0400
|
|||
+++ ./src/syscall/rlimit.c 2016-03-21 20:29:49.544175830 -0400
|
|||
@@ -58,7 +58,7 @@
|
|||
*/ |
|||
int translate_setrlimit_exit(const Tracee *tracee, bool is_prlimit) |
|||
{ |
|||
- struct rlimit proot_stack;
|
|||
+ struct rlimit64 proot_stack;
|
|||
word_t resource; |
|||
word_t address; |
|||
word_t tracee_stack_limit; |
|||
@@ -94,7 +94,7 @@
|
|||
return -errno; |
|||
|
|||
/* Get current PRoot's stack limit. */ |
|||
- status = prlimit(0, RLIMIT_STACK, NULL, &proot_stack);
|
|||
+ status = prlimit64(0, RLIMIT_STACK, NULL, &proot_stack);
|
|||
if (status < 0) { |
|||
VERBOSE(tracee, 1, "can't get stack limit."); |
|||
return 0; /* Not fatal. */ |
|||
@@ -107,7 +107,7 @@
|
|||
proot_stack.rlim_cur = tracee_stack_limit; |
|||
|
|||
/* Increase current PRoot's stack limit. */ |
|||
- status = prlimit(0, RLIMIT_STACK, &proot_stack, NULL);
|
|||
+ status = prlimit64(0, RLIMIT_STACK, &proot_stack, NULL);
|
|||
if (status < 0) |
|||
VERBOSE(tracee, 1, "can't set stack limit."); |
|||
return 0; /* Not fatal. */ |
@ -1,32 +0,0 @@ |
|||
--- PRoot-5.1.0/src/tracee/mem.c 2014-12-15 15:18:11.000000000 +0100
|
|||
+++ src/src/tracee/mem.c 2016-03-20 10:37:46.288702967 +0100
|
|||
@@ -131,6 +131,9 @@
|
|||
/* Copy the bytes in the last word carefully since we have to |
|||
* overwrite only the relevant ones. */ |
|||
|
|||
+ /* Clear errno so we won't detect previous syscall failure as ptrace one */
|
|||
+ errno = 0;
|
|||
+
|
|||
word = ptrace(PTRACE_PEEKDATA, tracee->pid, dest + i, NULL); |
|||
if (errno != 0) { |
|||
note(tracee, WARNING, SYSTEM, "ptrace(PEEKDATA)"); |
|||
@@ -236,6 +239,9 @@
|
|||
nb_trailing_bytes = size % sizeof(word_t); |
|||
nb_full_words = (size - nb_trailing_bytes) / sizeof(word_t); |
|||
|
|||
+ /* Clear errno so we won't detect previous syscall failure as ptrace one */
|
|||
+ errno = 0;
|
|||
+
|
|||
/* Copy one word by one word, except for the last one. */ |
|||
for (i = 0; i < nb_full_words; i++) { |
|||
word = ptrace(PTRACE_PEEKDATA, tracee->pid, src + i, NULL); |
|||
@@ -366,6 +372,9 @@
|
|||
nb_trailing_bytes = max_size % sizeof(word_t); |
|||
nb_full_words = (max_size - nb_trailing_bytes) / sizeof(word_t); |
|||
|
|||
+ /* Clear errno so we won't detect previous syscall failure as ptrace one */
|
|||
+ errno = 0;
|
|||
+
|
|||
/* Copy one word by one word, except for the last one. */ |
|||
for (i = 0; i < nb_full_words; i++) { |
|||
word = ptrace(PTRACE_PEEKDATA, tracee->pid, src + i, NULL); |
@ -1,13 +0,0 @@ |
|||
diff -u -r ../PRoot-5.1.0/src/tracee/tracee.c ./src/tracee/tracee.c
|
|||
--- ../PRoot-5.1.0/src/tracee/tracee.c 2014-12-15 09:18:11.000000000 -0500
|
|||
+++ ./src/tracee/tracee.c 2016-01-08 19:32:43.493157624 -0500
|
|||
@@ -538,6 +538,9 @@
|
|||
/* Sanity check. */ |
|||
assert(!child->as_ptracee.tracing_started); |
|||
|
|||
+#ifndef __W_STOPCODE
|
|||
+#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
|
|||
+#endif
|
|||
keep_stopped = handle_ptracee_event(child, __W_STOPCODE(SIGSTOP)); |
|||
|
|||
/* Note that this event was already handled by |
@ -1,17 +0,0 @@ |
|||
diff -u -r ../PRoot-5.1.0/src/tracee/tracee.h ./src/tracee/tracee.h
|
|||
--- ../PRoot-5.1.0/src/tracee/tracee.h 2014-12-15 09:18:11.000000000 -0500
|
|||
+++ ./src/tracee/tracee.h 2016-01-08 09:04:52.144913929 -0500
|
|||
@@ -140,7 +140,12 @@
|
|||
&& get_sysnum((tracee), ORIGINAL) == sysnum) |
|||
|
|||
/* How this tracee is restarted. */ |
|||
- enum __ptrace_request restart_how;
|
|||
+#ifdef __ANDROID__
|
|||
+ int
|
|||
+#else
|
|||
+ enum __ptrace_request
|
|||
+#endif
|
|||
+ restart_how;
|
|||
|
|||
/* Value of the tracee's general purpose registers. */ |
|||
struct user_regs_struct _regs[NB_REG_VERSION]; |
@ -1,272 +0,0 @@ |
|||
diff -r -u src/src/syscall/chain.c src_set_syscall_workaround/src/syscall/chain.c
|
|||
--- src/src/syscall/chain.c 2015-07-23 21:50:10.000000000 +0200
|
|||
+++ src_set_syscall_workaround/src/syscall/chain.c 2016-08-12 19:33:13.920471000 +0200
|
|||
@@ -39,17 +39,10 @@
|
|||
|
|||
STAILQ_HEAD(chained_syscalls, chained_syscall); |
|||
|
|||
-/**
|
|||
- * Append a new syscall (@sysnum, @sysarg_*) to the list of
|
|||
- * "unrequested" syscalls for the given @tracee. These new syscalls
|
|||
- * will be triggered in order once the current syscall is done. The
|
|||
- * caller is free to force the last result of this syscall chain in
|
|||
- * @tracee->chain.final_result. This function returns -errno if an
|
|||
- * error occurred, otherwise 0.
|
|||
- */
|
|||
-int register_chained_syscall(Tracee *tracee, Sysnum sysnum,
|
|||
+static int register_chained_syscall_internal(Tracee *tracee, Sysnum sysnum,
|
|||
word_t sysarg_1, word_t sysarg_2, word_t sysarg_3, |
|||
- word_t sysarg_4, word_t sysarg_5, word_t sysarg_6)
|
|||
+ word_t sysarg_4, word_t sysarg_5, word_t sysarg_6,
|
|||
+ bool at_front)
|
|||
{ |
|||
struct chained_syscall *syscall; |
|||
|
|||
@@ -73,12 +66,35 @@
|
|||
syscall->sysargs[4] = sysarg_5; |
|||
syscall->sysargs[5] = sysarg_6; |
|||
|
|||
- STAILQ_INSERT_TAIL(tracee->chain.syscalls, syscall, link);
|
|||
+ if (at_front) {
|
|||
+ STAILQ_INSERT_HEAD(tracee->chain.syscalls, syscall, link);
|
|||
+ } else {
|
|||
+ STAILQ_INSERT_TAIL(tracee->chain.syscalls, syscall, link);
|
|||
+ }
|
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/** |
|||
+ * Append a new syscall (@sysnum, @sysarg_*) to the list of
|
|||
+ * "unrequested" syscalls for the given @tracee. These new syscalls
|
|||
+ * will be triggered in order once the current syscall is done. The
|
|||
+ * caller is free to force the last result of this syscall chain in
|
|||
+ * @tracee->chain.final_result. This function returns -errno if an
|
|||
+ * error occurred, otherwise 0.
|
|||
+ */
|
|||
+int register_chained_syscall(Tracee *tracee, Sysnum sysnum,
|
|||
+ word_t sysarg_1, word_t sysarg_2, word_t sysarg_3,
|
|||
+ word_t sysarg_4, word_t sysarg_5, word_t sysarg_6) {
|
|||
+ return register_chained_syscall_internal(
|
|||
+ tracee, sysnum,
|
|||
+ sysarg_1, sysarg_2, sysarg_3,
|
|||
+ sysarg_4, sysarg_5, sysarg_6,
|
|||
+ false
|
|||
+ );
|
|||
+}
|
|||
+
|
|||
+/**
|
|||
* Use/remove the first element of @tracee->chain.syscalls to forge a |
|||
* new syscall. This function should be called only at the end of in |
|||
* the sysexit stage. |
|||
@@ -126,6 +142,9 @@
|
|||
/* Move the instruction pointer back to the original trap. */ |
|||
instr_pointer = peek_reg(tracee, CURRENT, INSTR_POINTER); |
|||
poke_reg(tracee, INSTR_POINTER, instr_pointer - SYSTRAP_SIZE); |
|||
+
|
|||
+ /* Break after exit from syscall, there may be another one in chain */
|
|||
+ tracee->restart_how = PTRACE_SYSCALL;
|
|||
} |
|||
|
|||
/** |
|||
@@ -154,3 +173,18 @@
|
|||
peek_reg(tracee, ORIGINAL, SYSARG_5), |
|||
peek_reg(tracee, ORIGINAL, SYSARG_6)); |
|||
} |
|||
+
|
|||
+int restart_current_syscall_as_chained(Tracee *tracee)
|
|||
+{
|
|||
+ assert(tracee->chain.sysnum_workaround_state == SYSNUM_WORKAROUND_INACTIVE);
|
|||
+ tracee->chain.sysnum_workaround_state = SYSNUM_WORKAROUND_PROCESS_FAULTY_CALL;
|
|||
+ return register_chained_syscall_internal(tracee,
|
|||
+ get_sysnum(tracee, CURRENT),
|
|||
+ peek_reg(tracee, CURRENT, SYSARG_1),
|
|||
+ peek_reg(tracee, CURRENT, SYSARG_2),
|
|||
+ peek_reg(tracee, CURRENT, SYSARG_3),
|
|||
+ peek_reg(tracee, CURRENT, SYSARG_4),
|
|||
+ peek_reg(tracee, CURRENT, SYSARG_5),
|
|||
+ peek_reg(tracee, CURRENT, SYSARG_6),
|
|||
+ true);
|
|||
+}
|
|||
diff -r -u src/src/syscall/chain.h src_set_syscall_workaround/src/syscall/chain.h
|
|||
--- src/src/syscall/chain.h 2015-07-23 21:50:10.000000000 +0200
|
|||
+++ src_set_syscall_workaround/src/syscall/chain.h 2016-08-09 17:12:36.448471000 +0200
|
|||
@@ -37,5 +37,7 @@
|
|||
|
|||
extern void chain_next_syscall(Tracee *tracee); |
|||
|
|||
+extern int restart_current_syscall_as_chained(Tracee *tracee);
|
|||
+
|
|||
|
|||
#endif /* CHAIN_H */ |
|||
diff -r -u src/src/syscall/syscall.c src_set_syscall_workaround/src/syscall/syscall.c
|
|||
--- src/src/syscall/syscall.c 2015-07-23 21:50:10.000000000 +0200
|
|||
+++ src_set_syscall_workaround/src/syscall/syscall.c 2016-08-12 19:32:35.199527000 +0200
|
|||
@@ -31,6 +31,7 @@
|
|||
#include "tracee/tracee.h" |
|||
#include "tracee/reg.h" |
|||
#include "tracee/mem.h" |
|||
+#include "cli/note.h"
|
|||
|
|||
/** |
|||
* Copy in @path a C string (PATH_MAX bytes max.) from the @tracee's |
|||
@@ -126,7 +127,9 @@
|
|||
save_current_regs(tracee, MODIFIED); |
|||
} |
|||
else { |
|||
- status = notify_extensions(tracee, SYSCALL_CHAINED_ENTER, 0, 0);
|
|||
+ if (tracee->chain.sysnum_workaround_state != SYSNUM_WORKAROUND_PROCESS_REPLACED_CALL) {
|
|||
+ status = notify_extensions(tracee, SYSCALL_CHAINED_ENTER, 0, 0);
|
|||
+ }
|
|||
tracee->restart_how = PTRACE_SYSCALL; |
|||
} |
|||
|
|||
@@ -159,8 +162,13 @@
|
|||
/* Translate the syscall only if it was actually |
|||
* requested by the tracee, it is not a syscall |
|||
* chained by PRoot. */ |
|||
- if (tracee->chain.syscalls == NULL)
|
|||
+ if (tracee->chain.syscalls == NULL || tracee->chain.sysnum_workaround_state == SYSNUM_WORKAROUND_PROCESS_REPLACED_CALL) {
|
|||
+ tracee->chain.sysnum_workaround_state = SYSNUM_WORKAROUND_INACTIVE;
|
|||
translate_syscall_exit(tracee); |
|||
+ }
|
|||
+ else if (tracee->chain.sysnum_workaround_state == SYSNUM_WORKAROUND_PROCESS_FAULTY_CALL) {
|
|||
+ tracee->chain.sysnum_workaround_state = SYSNUM_WORKAROUND_PROCESS_REPLACED_CALL;
|
|||
+ }
|
|||
else |
|||
(void) notify_extensions(tracee, SYSCALL_CHAINED_EXIT, 0, 0); |
|||
|
|||
@@ -172,7 +180,42 @@
|
|||
chain_next_syscall(tracee); |
|||
} |
|||
|
|||
- (void) push_regs(tracee);
|
|||
+ bool override_sysnum = is_enter_stage && tracee->chain.syscalls == NULL;
|
|||
+ int push_regs_status = push_specific_regs(tracee, override_sysnum);
|
|||
+
|
|||
+ /* Handle inability to change syscall number */
|
|||
+ if (push_regs_status < 0 && override_sysnum) {
|
|||
+ word_t orig_sysnum = peek_reg(tracee, ORIGINAL, SYSARG_NUM);
|
|||
+ word_t current_sysnum = peek_reg(tracee, CURRENT, SYSARG_NUM);
|
|||
+ if (orig_sysnum != current_sysnum) {
|
|||
+ /* Restart current syscall as chained */
|
|||
+ if (current_sysnum != SYSCALL_AVOIDER) {
|
|||
+ restart_current_syscall_as_chained(tracee);
|
|||
+ }
|
|||
+
|
|||
+ /* Set syscall arguments to make it fail
|
|||
+ * TODO: More reliable way to make invalid arguments */
|
|||
+ if (get_sysnum(tracee, ORIGINAL) == PR_brk) {
|
|||
+ /* For brk() we pass 0 as first arg; this is used to query value without changing it */
|
|||
+ poke_reg(tracee, SYSARG_1, 0);
|
|||
+ } else {
|
|||
+ /* For other syscalls we set all args to -1
|
|||
+ * Hoping there is among them invalid request/address/fd/value that will make syscall fail */
|
|||
+ poke_reg(tracee, SYSARG_1, -1);
|
|||
+ poke_reg(tracee, SYSARG_2, -1);
|
|||
+ poke_reg(tracee, SYSARG_3, -1);
|
|||
+ poke_reg(tracee, SYSARG_4, -1);
|
|||
+ poke_reg(tracee, SYSARG_5, -1);
|
|||
+ poke_reg(tracee, SYSARG_6, -1);
|
|||
+ }
|
|||
+
|
|||
+ /* Push regs again without changing syscall */
|
|||
+ push_regs_status = push_specific_regs(tracee, false);
|
|||
+ if (push_regs_status != 0) {
|
|||
+ note(tracee, WARNING, SYSTEM, "can't set tracee registers in workaround");
|
|||
+ }
|
|||
+ }
|
|||
+ }
|
|||
|
|||
if (is_enter_stage) |
|||
print_current_regs(tracee, 5, "sysenter end" ); |
|||
diff -r -u src/src/tracee/reg.c src_set_syscall_workaround/src/tracee/reg.c
|
|||
--- src/src/tracee/reg.c 2015-07-23 21:50:10.000000000 +0200
|
|||
+++ src_set_syscall_workaround/src/tracee/reg.c 2016-08-12 14:48:31.410423000 +0200
|
|||
@@ -262,12 +262,7 @@
|
|||
return 0; |
|||
} |
|||
|
|||
-/**
|
|||
- * Copy the cached values of all @tracee's general purpose registers
|
|||
- * back to the process, if necessary. This function returns -errno if
|
|||
- * an error occured, 0 otherwise.
|
|||
- */
|
|||
-int push_regs(Tracee *tracee)
|
|||
+int push_specific_regs(Tracee *tracee, bool including_sysnum)
|
|||
{ |
|||
int status; |
|||
|
|||
@@ -306,12 +301,14 @@
|
|||
/* Update syscall number if needed. On arm64, a new |
|||
* subcommand has been added to PTRACE_{S,G}ETREGSET |
|||
* to allow write/read of current sycall number. */ |
|||
- if (current_sysnum != REG(tracee, ORIGINAL, SYSARG_NUM)) {
|
|||
+ if (including_sysnum && current_sysnum != REG(tracee, ORIGINAL, SYSARG_NUM)) {
|
|||
regs.iov_base = ¤t_sysnum; |
|||
regs.iov_len = sizeof(current_sysnum); |
|||
status = ptrace(PTRACE_SETREGSET, tracee->pid, NT_ARM_SYSTEM_CALL, ®s); |
|||
- if (status < 0)
|
|||
- note(tracee, WARNING, SYSTEM, "can't set the syscall number");
|
|||
+ if (status < 0) {
|
|||
+ //note(tracee, WARNING, SYSTEM, "can't set the syscall number");
|
|||
+ return status;
|
|||
+ }
|
|||
} |
|||
|
|||
/* Update other registers. */ |
|||
@@ -325,10 +322,12 @@
|
|||
* change effectively the syscall number during a |
|||
* ptrace-stop. */ |
|||
word_t current_sysnum = REG(tracee, CURRENT, SYSARG_NUM); |
|||
- if (current_sysnum != REG(tracee, ORIGINAL, SYSARG_NUM)) {
|
|||
+ if (including_sysnum && current_sysnum != REG(tracee, ORIGINAL, SYSARG_NUM)) {
|
|||
status = ptrace(PTRACE_SET_SYSCALL, tracee->pid, 0, current_sysnum); |
|||
- if (status < 0)
|
|||
- note(tracee, WARNING, SYSTEM, "can't set the syscall number");
|
|||
+ if (status < 0) {
|
|||
+ //note(tracee, WARNING, SYSTEM, "can't set the syscall number");
|
|||
+ return status;
|
|||
+ }
|
|||
} |
|||
# endif |
|||
|
|||
@@ -340,3 +339,12 @@
|
|||
|
|||
return 0; |
|||
} |
|||
+
|
|||
+/**
|
|||
+ * Copy the cached values of all @tracee's general purpose registers
|
|||
+ * back to the process, if necessary. This function returns -errno if
|
|||
+ * an error occured, 0 otherwise.
|
|||
+ */
|
|||
+int push_regs(Tracee *tracee) {
|
|||
+ return push_specific_regs(tracee, true);
|
|||
+}
|
|||
diff -r -u src/src/tracee/reg.h src_set_syscall_workaround/src/tracee/reg.h
|
|||
--- src/src/tracee/reg.h 2015-07-23 21:50:10.000000000 +0200
|
|||
+++ src_set_syscall_workaround/src/tracee/reg.h 2016-08-09 21:38:03.863456000 +0200
|
|||
@@ -43,6 +43,7 @@
|
|||
} Reg; |
|||
|
|||
extern int fetch_regs(Tracee *tracee); |
|||
+extern int push_specific_regs(Tracee *tracee, bool including_sysnum);
|
|||
extern int push_regs(Tracee *tracee); |
|||
|
|||
extern word_t peek_reg(const Tracee *tracee, RegVersion version, Reg reg); |
|||
diff -r -u src/src/tracee/tracee.h src_set_syscall_workaround/src/tracee/tracee.h
|
|||
--- src/src/tracee/tracee.h 2016-08-12 19:44:07.301407472 +0200
|
|||
+++ src_set_syscall_workaround/src/tracee/tracee.h 2016-08-12 19:52:43.554712737 +0200
|
|||
@@ -193,6 +193,11 @@
|
|||
struct chained_syscalls *syscalls; |
|||
bool force_final_result; |
|||
word_t final_result; |
|||
+ enum {
|
|||
+ SYSNUM_WORKAROUND_INACTIVE,
|
|||
+ SYSNUM_WORKAROUND_PROCESS_FAULTY_CALL,
|
|||
+ SYSNUM_WORKAROUND_PROCESS_REPLACED_CALL
|
|||
+ } sysnum_workaround_state;
|
|||
} chain; |
|||
|
|||
/* Load info generated during execve sysenter and used during |
Loading…
Reference in new issue