Ver código fonte

tracing syscalls

isundil 10 anos atrás
pai
commit
aaf314eff4

+ 4 - 1
.gitignore

@@ -39,6 +39,9 @@
 Makefile
 CMakeFiles
 cmake_install.cmake
-/CMakeCache.txt
+CMakeCache.txt
 /bin
 
+# test directory
+/test/test
+

+ 2 - 0
CMakeLists.txt

@@ -1,6 +1,8 @@
 cmake_minimum_required(VERSION 2.8)
 project(sandbox)
 
+include_directories(src)
+
 SET(EXECUTABLE_OUTPUT_PATH ../bin)
 add_definitions ("-Wall")
 add_definitions ("-g3")

+ 1 - 1
src/CMakeLists.txt

@@ -1 +1 @@
-add_executable(sandbox main.c param.c sandbox.c)
+add_executable(sandbox main.c param.c sandbox.c ovr_syscall/ovr_write.c ovr_syscall/ovr_open.c ovr_syscall/ovr_close.c)

+ 20 - 0
src/ovr_syscall/ovr_close.c

@@ -0,0 +1,20 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "sandbox.h"
+
+/* DEBUG HEADER */
+#include <stdio.h>
+
+int ovr_close(struct s_sandboxenv *env, unsigned long long int _fd,
+				unsigned long long int _none_0, unsigned long long int _none_1)
+{
+	int fd = (int) _fd;
+
+
+	printf("DO close ! ([%d])\n", fd);
+	fflush(stdout);
+	return 0;
+}
+

+ 23 - 0
src/ovr_syscall/ovr_open.c

@@ -0,0 +1,23 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "sandbox.h"
+
+/* DEBUG HEADER */
+#include <stdio.h>
+
+int ovr_open(struct s_sandboxenv *env, unsigned long long int _pathname,
+				unsigned long long int _flags, unsigned long long int _mode)
+{
+	const char *pathname = (const char *) _pathname;
+	int flags = (int) _flags;
+	mode_t mode = (mode_t) _mode;
+
+
+	printf("DO open ! ([%x], [%d], [%d])\n", pathname, flags, mode);
+	fflush(stdout);
+	//env->registers.orig_rax = -1;
+	return 0;
+}
+

+ 21 - 0
src/ovr_syscall/ovr_write.c

@@ -0,0 +1,21 @@
+
+#include "sandbox.h"
+
+/* DEBUG HEADER */
+#include <stdio.h>
+
+int ovr_write(struct s_sandboxenv *env, unsigned long long int _fd,
+				unsigned long long int _buf, unsigned long long int _buflen)
+{
+	int fd = (int) _fd;
+	int buflen = (int) _buflen;
+	//char *buf = strndup((char*)_buf, buflen);
+	char *buf = (char *) _buf;
+
+
+	printf("DO WRITE ! ([%d], [%x], [%d])\n", env->registers.rbx, (size_t) buf, buflen);
+	fflush(stdout);
+	//env->registers.orig_rax = -1;
+	return 0;
+}
+

+ 1 - 0
src/param.c

@@ -29,6 +29,7 @@ t_param *parse_argv(const char **av)
 	result = (t_param *) malloc(sizeof(*result));
 	if (result == NULL)
 		return NULL;
+	bzero(result, sizeof(*result));
 	for (progname = *(av++); *av && !result->cmd; ++av)
 	{
 		if (**av == '-')

+ 49 - 12
src/sandbox.c

@@ -1,8 +1,8 @@
 
 #include <sys/ptrace.h>
 #include <sys/types.h>
-#include <sys/user.h>
 #include <sys/wait.h>
+#include <strings.h>
 #include <unistd.h>
 #include "sandbox.h"
 
@@ -14,29 +14,66 @@ void doExec(int pid_parent, const t_param *params)
 {
 	char **argv = (char **)params->cmd;
 
-	ptrace(PTRACE_TRACEME, 0, 0, 0);
-	kill(getpid(), SIGINT);
+	//TODO check return value
 	execvp(argv[0], argv);
 }
 
+int manageSyscall(struct s_sandboxenv *env)
+{
+	t_syscall_fnc ovr_fnc;
+
+	/*
+		printf("CALL %d\n", (int) env->registers.orig_rax);
+		fflush(stdout);
+	*/
+	if (env->registers.orig_rax >= NR_syscalls ||
+			!(ovr_fnc = env->functions[(int) env->registers.orig_rax]))
+		return 0;
+	(ovr_fnc)(env, env->registers.rbx, env->registers.rcx, env->registers.rdx);
+	return 1;
+}
+
+static inline void init_syscalls(struct s_sandboxenv *env)
+{
+	bzero(env->functions, sizeof(*(env->functions)) * NR_syscalls);
+	env->functions[__NR_write] = ovr_write;
+	env->functions[__NR_open] = ovr_open;
+	env->functions[__NR_close] = ovr_close;
+}
+
+static inline int waitForSyscall(const int pid)
+{
+	int status;
+
+	ptrace(PTRACE_SYSCALL, pid, NULL, 0);
+	if (waitpid(pid, &status, 0) == -1)
+		return -1;
+	return 0;
+}
+
 void doTrace(int pid, const t_param *params)
 {
 	int status;
-	struct user_regs_struct registers;
+	struct s_sandboxenv sandbox_env;
 
+	ptrace(PTRACE_ATTACH, pid, 0, 0);
+	kill(pid, SIGTRAP);
 	waitpid(pid, &status, 0);
+	sandbox_env.params = params;
+	sandbox_env.child_pid = pid;
+	init_syscalls(&sandbox_env);
+
 	while (1)
 	{
-		ptrace(PTRACE_SYSCALL, pid, NULL, 0);
-		if (waitpid(pid, &status, 0) == -1)
+		if (waitForSyscall(pid))
 			break;
-		ptrace(PTRACE_GETREGS, pid, 0, &registers);
-		printf("CALL %llu\n", (int) registers.orig_rax);
-		fflush(stdout);
 
-		/* syscall return */
-		ptrace(PTRACE_SYSCALL, pid, NULL, 0);
-		if (waitpid(pid, &status, 0) == -1)
+		ptrace(PTRACE_GETREGS, pid, 0, &(sandbox_env.registers));
+		// getregsset ?
+		if (manageSyscall(&sandbox_env))
+			ptrace(PTRACE_SETREGS, pid, 0, &(sandbox_env.registers));
+
+		if (waitForSyscall(pid))
 			break;
 	}
 }

+ 45 - 0
src/sandbox.h

@@ -1,10 +1,53 @@
 #ifndef   SANDBOX_H__
 # define  SANDBOX_H__
 
+# include <sys/user.h>
+# include <sys/syscall.h>
+
+# ifndef NR_syscalls
+#  define NR_syscalls 386
+# endif
+
+/*
+# if defined __x86_64__
+#   define RAX rax
+#   define RBX rbx
+#   define RCX rcx
+#   define RDX rdx
+#   define RSP rsp
+#   define RBP rbp
+#   define RIP rip
+#   define RDI rdi
+#   define RSI rsi
+#   define FMT "%016lx"
+# else
+#   define RAX eax
+#   define RBX ebx
+#   define RCX ecx
+#   define RDX edx
+#   define RSP esp
+#   define RBP ebp
+#   define RIP eip
+#   define RDI edi
+#   define RSI esi
+#   define FMT "%08lx"
+# endif
+*/
+
 typedef struct {
 	const char **cmd;
 } t_param;
 
+struct s_sandboxenv;
+typedef int(* t_syscall_fnc)(struct s_sandboxenv *, unsigned long long int, unsigned long long int, unsigned long long int);
+
+struct s_sandboxenv {
+	const t_param *params;
+	t_syscall_fnc functions[NR_syscalls];
+	int child_pid;
+	struct user_regs_struct registers;
+};
+
 /* params.c */
 void print_help(const char *progname, int exit_status);
 t_param *parse_argv(const char **av);
@@ -12,4 +55,6 @@ t_param *parse_argv(const char **av);
 /* sandbox.c */
 int launch_program(const t_param *params);
 
+# include "sandbox_syscall.h"
+
 #endif /* SANDBOX_H__ */

+ 10 - 0
src/sandbox_syscall.h

@@ -0,0 +1,10 @@
+#ifndef  SANDBOX_SYSCALL_H__
+# define SANDBOX_SYSCALL_H__
+
+# define SANDBOX_OVERRITE_PARAMS struct s_sandboxenv *, unsigned long long int, unsigned long long int, unsigned long long int
+
+int ovr_open(SANDBOX_OVERRITE_PARAMS);
+int ovr_close(SANDBOX_OVERRITE_PARAMS);
+int ovr_write(SANDBOX_OVERRITE_PARAMS);
+
+#endif /* SANDBOX_SYSCALL_H__ */

+ 1 - 0
test/CMakeLists.txt

@@ -0,0 +1 @@
+add_executable(test test.c)

+ 8 - 0
test/test.c

@@ -0,0 +1,8 @@
+
+int main()
+{
+	const char* t = "test\n";
+	write(1, t, 5);
+	printf("%p\n", t);
+}
+