Skip to content

Instantly share code, notes, and snippets.

@avagin
Created December 20, 2019 02:27
Show Gist options
  • Save avagin/146f0190a766bd7d4543c2ae132218d0 to your computer and use it in GitHub Desktop.
Save avagin/146f0190a766bd7d4543c2ae132218d0 to your computer and use it in GitHub Desktop.
ptrace/syscall/arm64
#define _GNU_SOURCE
#include <sys/ptrace.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/uio.h>
#define NT_PRSTATUS 1
#define SYSTRAP
int main(int argc, char **argv)
{
struct user_regs_struct regs;
long i, n = atoi(argv[1]), sigtrap = atoi(argv[2]);
int status;
struct iovec iov = {};
pid_t pid = fork();
if (pid < 0)
return 1;
if (pid == 0) {
long sysno = __NR_kill;
long signo = SIGSTOP;
long p = syscall(__NR_getpid);
setsid();
asm volatile(
"mov x8, %0 \n"
"mov x1, %1 \n"
"mov x0, %2 \n"
"svc #0 \n"
"brk #3 \n"
:
: "r" (sysno), "r" (signo), "r" (p)
: "x0" , "x8", "x1", "memory");
return 1;
}
if (ptrace(PTRACE_ATTACH, pid, 0, 0))
return 1;
while (1) {
if (waitpid(pid, &status, 0) != pid)
return 1;
printf("%x\n", status);
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
break;
if (ptrace(PTRACE_CONT, pid, 0, 0))
return 1;
}
if (ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACESYSGOOD))
return 1;
iov.iov_base = &regs;
iov.iov_len = sizeof(regs);
if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov))
return 1;
regs.pc -= 4;
regs.regs[8] = __NR_getpid;
printf("pc %llx\n", regs.pc);
for (i = 0; i < n; i++) {
if (ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov))
return 1;
if (sigtrap) {
if (ptrace(PTRACE_CONT, pid, 0, 0))
return 1;
if (waitpid(pid, &status, 0) != pid)
return 1;
if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP) {
printf("%x\n", status);
return 1;
}
} else {
if (ptrace(PTRACE_SYSCALL, pid, 0, 0))
return 1;
if (wait4(pid, &status, __WALL, NULL) != pid)
return 1;
if (status != 0x857f) {
printf("%x\n", status);
return 1;
}
if (ptrace(PTRACE_SYSCALL, pid, 0, 0))
return 1;
if (wait4(pid, &status, __WALL, NULL) != pid)
return 1;
if (status != 0x857f) {
printf("%x\n", status);
return 1;
}
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment