diff --git a/Makefile b/Makefile index a0ba536..7548bf0 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,7 @@ else endif #MCFLAGS += -fsanitize=thread +#MCFLAGS += -fsanitize=address -static-libasan CC ?= $(CROSS_COMPILE)gcc LD ?= $(CROSS_COMPILE)ld.bfd diff --git a/arch/arm/enter.c b/arch/arm/enter.c index db14bae..457be67 100644 --- a/arch/arm/enter.c +++ b/arch/arm/enter.c @@ -29,6 +29,7 @@ static void __attribute__((used)) container(void) /* rt_sigprocmask(), expects pointer to area for masks in r8 */ asm volatile( ".global sigprocmask_blob \n" + ".align 3 \n" "sigprocmask_blob: \n" "mov r7, #175 \n" /* __NR_rt_sigprocmask */ "mov r0, %0 \n" /* @how */ @@ -38,6 +39,7 @@ static void __attribute__((used)) container(void) "svc 0x0 \n" "udf #16 \n" /* SIGTRAP */ ".global sigprocmask_blob_size \n" + ".align 3 \n" "sigprocmask_blob_size: \n" ".int sigprocmask_blob_size - sigprocmask_blob \n" :: "i" (SIG_SETMASK) @@ -46,6 +48,7 @@ static void __attribute__((used)) container(void) /* mmaps anon area for parasite_blob */ asm volatile( ".global mmap_blob \n" + ".align 3 \n" "mmap_blob: \n" "mov r7, #192 \n" /* __NR_mmap2 */ "mov r0, #0 \n" /* @addr */ @@ -57,6 +60,7 @@ static void __attribute__((used)) container(void) "svc 0x0 \n" "udf #16 \n" /* SIGTRAP */ ".global mmap_blob_size \n" + ".align 3 \n" "mmap_blob_size: \n" ".int mmap_blob_size - mmap_blob \n" :: "i" (PROT_EXEC | PROT_READ | PROT_WRITE), @@ -66,6 +70,7 @@ static void __attribute__((used)) container(void) /* clones parasite, expects parasite address in r8 */ asm volatile( ".global clone_blob \n" + ".align 3 \n" "clone_blob: \n" "mov r7, #120 \n" /* __NR_clone */ "ldr r0, CLONE_FLAGS \n" @@ -79,6 +84,7 @@ static void __attribute__((used)) container(void) "CLONE_FLAGS: \n" ".word 0x80050f00 \n" /* (CLONE_FILES | CLONE_FS | CLONE_IO | CLONE_SIGHAND | CLONE_SYSVSEM | CLONE_THREAD | CLONE_VM) */ ".global clone_blob_size \n" + ".align 3 \n" "clone_blob_size: \n" ".int clone_blob_size - clone_blob \n" ); @@ -86,6 +92,7 @@ static void __attribute__((used)) container(void) /* munmap anon area for parasite_blob, expects addr in r8 and len in r9 */ asm volatile( ".global munmap_blob \n" + ".align 3 \n" "munmap_blob: \n" "mov r7, #91 \n" /* __NR_munmap */ "mov r0, r8 \n" /* @addr */ @@ -93,6 +100,7 @@ static void __attribute__((used)) container(void) "svc 0x0 \n" "udf #16 \n" /* SIGTRAP */ ".global munmap_blob_size \n" + ".align 3 \n" "munmap_blob_size: \n" ".int munmap_blob_size - munmap_blob \n" ); diff --git a/arch/arm64/enter.c b/arch/arm64/enter.c index d47f172..272a767 100644 --- a/arch/arm64/enter.c +++ b/arch/arm64/enter.c @@ -30,6 +30,7 @@ static void __attribute__((used)) container(void) /* rt_sigprocmask(), expects pointer to area for masks in x10 */ asm volatile( ".global sigprocmask_blob \n" + ".align 3 \n" "sigprocmask_blob: \n" "mov x8, #135 \n" /* __NR_rt_sigprocmask */ "mov x0, %0 \n" /* @how */ @@ -39,6 +40,7 @@ static void __attribute__((used)) container(void) "svc #0 \n" "brk #0 \n" /* SIGTRAP */ ".global sigprocmask_blob_size \n" + ".align 3 \n" "sigprocmask_blob_size: \n" ".int sigprocmask_blob_size - sigprocmask_blob \n" :: "i" (SIG_SETMASK) @@ -47,6 +49,7 @@ static void __attribute__((used)) container(void) /* mmaps anon area for parasite_blob */ asm volatile( ".global mmap_blob \n" + ".align 3 \n" "mmap_blob: \n" "mov x8, #222 \n" /* __NR_mmap2 */ "mov x0, #0 \n" /* @addr */ @@ -58,6 +61,7 @@ static void __attribute__((used)) container(void) "svc #0 \n" "brk #0 \n" /* SIGTRAP */ ".global mmap_blob_size \n" + ".align 3 \n" "mmap_blob_size: \n" ".int mmap_blob_size - mmap_blob \n" :: "i" (PROT_EXEC | PROT_READ | PROT_WRITE), @@ -67,6 +71,7 @@ static void __attribute__((used)) container(void) /* clones parasite, expects parasite address in x10 */ asm volatile( ".global clone_blob \n" + ".align 3 \n" "clone_blob: \n" "mov x8, #220 \n" /* __NR_clone */ "ldr x0, CLONE_FLAGS \n" /* @flags */ @@ -82,6 +87,7 @@ static void __attribute__((used)) container(void) "CLONE_FLAGS: \n" ".quad (%0 & 0xffffffff) \n" /* zero high .word */ ".global clone_blob_size \n" + ".align 3 \n" "clone_blob_size: \n" ".int clone_blob_size - clone_blob \n" :: "i" (CLONE_FILES | CLONE_FS | CLONE_IO | CLONE_SIGHAND | CLONE_SYSVSEM | CLONE_THREAD | CLONE_VM) @@ -90,6 +96,7 @@ static void __attribute__((used)) container(void) /* munmap anon area for parasite_blob, expects addr in x10 and len in x11 */ asm volatile( ".global munmap_blob \n" + ".align 3 \n" "munmap_blob: \n" "mov x8, #215 \n" /* __NR_munmap */ "mov x0, x10 \n" /* @addr */ @@ -97,6 +104,7 @@ static void __attribute__((used)) container(void) "svc #0 \n" "brk #0 \n" /* SIGTRAP */ ".global munmap_blob_size \n" + ".align 3 \n" "munmap_blob_size: \n" ".int munmap_blob_size - munmap_blob \n" ); diff --git a/arch/enter.h b/arch/enter.h index 791e6e5..ca2c944 100644 --- a/arch/enter.h +++ b/arch/enter.h @@ -19,7 +19,7 @@ #ifndef __ENTER_H__ #define __ENTER_H__ -extern char test_blob[], sigprocmask_blob[], mmap_blob[], clone_blob[], munmap_blob[]; -extern int test_blob_size, sigprocmask_blob_size, mmap_blob_size, clone_blob_size, munmap_blob_size; +extern char sigprocmask_blob[], mmap_blob[], clone_blob[], munmap_blob[]; +extern int sigprocmask_blob_size, mmap_blob_size, clone_blob_size, munmap_blob_size; #endif \ No newline at end of file diff --git a/arch/x86_64/enter.c b/arch/x86_64/enter.c index cb23c99..741fbc4 100644 --- a/arch/x86_64/enter.c +++ b/arch/x86_64/enter.c @@ -30,6 +30,7 @@ static void __attribute__((used)) container(void) /* rt_sigprocmask(), expects pointer to area for masks in %r15 */ asm volatile( ".global sigprocmask_blob \n" + ".align 8 \n" "sigprocmask_blob: \n" "movq $14, %%rax \n" /* __NR_rt_sigprocmask */ "movq %0, %%rdi \n" /* @how */ @@ -39,6 +40,7 @@ static void __attribute__((used)) container(void) "syscall \n" "int $0x03 \n" ".global sigprocmask_blob_size \n" + ".align 8 \n" "sigprocmask_blob_size: \n" ".int sigprocmask_blob_size - sigprocmask_blob \n" :: "i" (SIG_SETMASK)); @@ -46,6 +48,7 @@ static void __attribute__((used)) container(void) /* mmaps anon area for parasite_blob */ asm volatile( ".global mmap_blob \n" + ".align 8 \n" "mmap_blob: \n" "movq $9, %%rax \n" /* mmap */ "movq $0, %%rdi \n" /* @addr */ @@ -57,6 +60,7 @@ static void __attribute__((used)) container(void) "syscall \n" "int $0x03 \n" ".global mmap_blob_size \n" + ".align 8 \n" "mmap_blob_size: \n" ".int mmap_blob_size - mmap_blob \n" :: "i" (PROT_EXEC | PROT_READ | PROT_WRITE), @@ -65,6 +69,7 @@ static void __attribute__((used)) container(void) /* clones parasite, expects parasite address in %r15 */ asm volatile( ".global clone_blob \n" + ".align 8 \n" "clone_blob: \n" "movq $56, %%rax \n" /* clone */ "movq %0, %%rdi \n" /* @flags */ @@ -77,6 +82,7 @@ static void __attribute__((used)) container(void) "jmp *%%r15 \n" /* jmp parasite */ "1: int $0x03 \n" ".global clone_blob_size \n" + ".align 8 \n" "clone_blob_size: \n" ".int clone_blob_size - clone_blob \n" :: "i" (CLONE_FILES | CLONE_FS | CLONE_IO | CLONE_SIGHAND | CLONE_SYSVSEM | CLONE_THREAD | CLONE_VM)); @@ -84,6 +90,7 @@ static void __attribute__((used)) container(void) /* munmaps anon area for parasite_blob, expects mmap address in %r15 and len in %r14 */ asm volatile( ".global munmap_blob \n" + ".align 8 \n" "munmap_blob: \n" "movq $11, %%rax \n" /* munmap */ "movq %%r15, %%rdi \n" /* @addr */ @@ -91,6 +98,7 @@ static void __attribute__((used)) container(void) "syscall \n" "int $0x03 \n" ".global munmap_blob_size \n" + ".align 8 \n" "munmap_blob_size: \n" ".int munmap_blob_size - munmap_blob \n" :: diff --git a/memcr.c b/memcr.c index 8325878..87ff122 100644 --- a/memcr.c +++ b/memcr.c @@ -1837,7 +1837,10 @@ static int peek(pid_t pid, unsigned long *addr, unsigned long *dst, size_t len) { int i; - for (i = 0; i < DIV_ROUND_UP(len, sizeof(unsigned long)); i++) { + /* len must be a mutliple of CPU word size */ + assert(len % sizeof(unsigned long) == 0); + + for (i = 0; i < (len / sizeof(unsigned long)); i++) { errno = 0; dst[i] = ptrace(PTRACE_PEEKDATA, pid, addr + i, NULL); if (errno) { @@ -1854,7 +1857,10 @@ static int poke(pid_t pid, unsigned long *addr, unsigned long *src, size_t len) int ret; int i; - for (i = 0; i < DIV_ROUND_UP(len, sizeof(unsigned long)); i++) { + /* len must be a mutliple of CPU word size */ + assert(len % sizeof(unsigned long) == 0); + + for (i = 0; i < (len / sizeof(unsigned long)); i++) { ret = ptrace(PTRACE_POKEDATA, pid, addr + i, *(src + i)); if (ret) { fprintf(stderr, "[-] %s() failed addr %p, src %p, i %d: %m\n", __func__, addr, src, i); @@ -2067,18 +2073,16 @@ static int signals_unblock(pid_t pid) static int ctx_save(pid_t pid) { + int max_blob_size; struct registers regs; ctx.pid = pid; /* allocate space to save original code */ - ctx.code_size = DIV_ROUND_UP(MAX(sigprocmask_blob_size, - MAX(mmap_blob_size, - MAX(clone_blob_size, - munmap_blob_size))), - sizeof(unsigned long)); + max_blob_size = MAX(sigprocmask_blob_size, MAX(mmap_blob_size, MAX(clone_blob_size, munmap_blob_size))); + ctx.code_size = DIV_ROUND_UP(max_blob_size, sizeof(unsigned long)) * sizeof(unsigned long); - ctx.code = malloc(sizeof(unsigned long) * ctx.code_size); + ctx.code = malloc(ctx.code_size); assert(ctx.code); read_cpu_regs(ctx.pid, ®s); diff --git a/memcr.h b/memcr.h index d4a8fea..94d94cb 100644 --- a/memcr.h +++ b/memcr.h @@ -25,9 +25,10 @@ #define PAGE_SIZE 4096 #endif +/* size is CPU word aligned for ptrace() peek/poke */ struct parasite_args { struct sockaddr_un addr; -}; +} __attribute__((aligned(sizeof(unsigned long)))); typedef enum { CMD_MPROTECT = 1,