Skip to content

Instantly share code, notes, and snippets.

@mniip
Last active June 9, 2016 13:08
Show Gist options
  • Save mniip/dfee175d702540f719df to your computer and use it in GitHub Desktop.
Save mniip/dfee175d702540f719df to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/user.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
asm (
"trampoline_code:\n"
"movq $0x1, %rax\n"
"movq $0x1, %rdi\n"
"movq $magic, %rsi\n"
"movq $magic_end - magic, %rdx\n"
"syscall\n"
"movq $0xb, %rax\n"
"movq $0x700000000000, %rdi\n"
"movq $0x1000, %rsi\n"
"syscall\n"
"jmp .\n"
"trampoline_end:\n"
"magic:\n"
".ascii \"magic\\n\"\n"
"magic_end:\n"
);
extern char trampoline_code;
extern char trampoline_end;
#define perror_if(cond, msg) do { if(cond) { perror(msg); exit(EXIT_FAILURE); } } while (0)
int main()
{
pid_t pid = fork();
if(pid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if(pid)
{
int status;
waitpid(pid, &status, 0); // catch SIGSTOP
struct user_regs_struct regs, regs_saved;
perror_if(-1 == ptrace(PTRACE_GETREGS, pid, 0, &regs_saved), "ptrace (getregs 1)");
memcpy(&regs, &regs_saved, sizeof regs);
regs.rip = 0x700000000000;
printf("Spoofing IP: 0x%llX (was: 0x%llX)\n", regs.rip, regs_saved.rip);
perror_if(-1 == ptrace(PTRACE_SETREGS, pid, 0, &regs), "ptrace (spoof rip)");
perror_if(-1 == ptrace(PTRACE_SYSCALL, pid, NULL, 0), "ptrace (skip until write entry)");
waitpid(pid, &status, 0); // write entry
perror_if(-1 == ptrace(PTRACE_SYSCALL, pid, NULL, 0), "ptrace (skip until write exit)");
waitpid(pid, &status, 0); // write exit
perror_if(-1 == ptrace(PTRACE_SYSCALL, pid, NULL, 0), "ptrace (skip until mmap entry)");
waitpid(pid, &status, 0); // munmap entry
perror_if(-1 == ptrace(PTRACE_SYSCALL, pid, NULL, 0), "ptrace (skip until mmap exit)");
waitpid(pid, &status, 0); // munmap exit
perror_if(-1 == ptrace(PTRACE_GETREGS, pid, 0, &regs), "ptrace (getregs 2)");
printf("Spoofing IP: 0x%llX (was: 0x%llX)\n", regs_saved.rip, regs.rip);
perror_if(-1 == ptrace(PTRACE_SETREGS, pid, 0, &regs_saved), "ptrace (restore regs)");
perror_if(-1 == ptrace(PTRACE_CONT, pid, NULL, 0), "ptrace (singlestep)");
waitpid(pid, &status, 0); // segv
}
else
{
printf("hi\n");
void *mapping = mmap((void *)0x700000000000ULL, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
perror_if(mapping == (void *)-1, "mmap");
memcpy(mapping, &trampoline_code, &trampoline_end - &trampoline_code);
ptrace(PTRACE_TRACEME, 0, 0, 0);
raise(SIGSTOP);
/* something magical happens */
printf("bye\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment