Last active
November 22, 2022 12:08
-
-
Save ammarfaizi2/673d08a0c1a0f45a352e927fe9607528 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* A syscall decoder to solve a challenge from Alviro. | |
* | |
* Link: https://t.me/GNUWeebTDD/7955 | |
*/ | |
#include <sys/syscall.h> | |
#include <sys/ptrace.h> | |
#include <sys/types.h> | |
#include <sys/user.h> | |
#include <sys/wait.h> | |
#include <stdbool.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdint.h> | |
#include <errno.h> | |
#include <stdio.h> | |
static void dump_code(char *dst, const void *src_, const void *rip, size_t len) | |
{ | |
const unsigned char *src = src_; | |
while (len) { | |
const char *fmt; | |
if (src == rip) | |
fmt = "<%02x> "; | |
else | |
fmt = "%02x "; | |
dst += sprintf(dst, fmt, *src); | |
src++; | |
len--; | |
} | |
} | |
static void exec_child_ptrace(char * const path) | |
{ | |
char * const argv[] = { path, NULL }; | |
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0) { | |
perror("ptrace"); | |
exit(1); | |
} | |
execve(path, argv, NULL); | |
perror("execve"); | |
} | |
static pid_t start_child_ptrace(char * const path) | |
{ | |
pid_t ret; | |
ret = fork(); | |
if (ret < 0) { | |
perror("fork"); | |
return -1; | |
} | |
if (!ret) { | |
exec_child_ptrace(path); | |
exit(1); | |
} | |
return ret; | |
} | |
static size_t copy_from_process(pid_t pid, void *_hdst, const void *_psrc, | |
size_t len) | |
{ | |
const char *psrc = _psrc; | |
char *hdst = _hdst; | |
long ret; | |
while (len) { | |
size_t copy_size; | |
errno = 0; | |
ret = ptrace(PTRACE_PEEKDATA, pid, (void *)psrc, NULL); | |
if (errno) | |
return len; | |
if (len < sizeof(ret)) | |
copy_size = len; | |
else | |
copy_size = sizeof(ret); | |
memcpy(hdst, &ret, copy_size); | |
hdst += copy_size; | |
psrc += copy_size; | |
len -= copy_size; | |
} | |
return len; | |
} | |
#if 0 | |
static size_t copy_to_process(pid_t pid, void *pdst_, const void *hsrc_, | |
size_t len) | |
{ | |
const char *hsrc = hsrc_; | |
char *pdst = pdst_; | |
char *src; | |
long ret; | |
while (len) { | |
size_t copy_size; | |
if (len < sizeof(ret)) { | |
copy_size = len; | |
errno = 0; | |
ret = ptrace(PTRACE_PEEKDATA, pid, pdst, NULL); | |
if (errno) | |
return len; | |
src = (char *)&ret; | |
memcpy(src, hsrc, copy_size); | |
} else { | |
copy_size = sizeof(ret); | |
src = (char *)hsrc; | |
} | |
errno = 0; | |
ptrace(PTRACE_POKEDATA, pid, pdst, src); | |
if (errno) | |
return len; | |
hsrc += copy_size; | |
pdst += copy_size; | |
len -= copy_size; | |
} | |
return len; | |
} | |
#endif | |
static const char *get_syscall_name(unsigned long long nr_sys) | |
{ | |
switch (nr_sys) { | |
case __NR_mmap: | |
return "mmap"; | |
case __NR_write: | |
return "write"; | |
case __NR_read: | |
return "read"; | |
case __NR_memfd_create: | |
return "memfd_create"; | |
default: | |
return NULL; | |
} | |
} | |
static void print_syscall_arg(struct user_regs_struct *regs) | |
{ | |
unsigned long long nr_sys = regs->orig_rax; | |
const char *name; | |
fprintf(stderr, "[%#llx] ", regs->rip); | |
name = get_syscall_name(nr_sys); | |
if (name) { | |
fprintf(stderr, "%s(%#llx, %#llx, %#llx, %#llx, %#llx, %#llx)\n", | |
name, | |
regs->rdi, | |
regs->rsi, | |
regs->rdx, | |
regs->r10, | |
regs->r8, | |
regs->r9); | |
} else { | |
fprintf(stderr, "syscall%llu(%#llx, %#llx, %#llx, %#llx, %#llx, %#llx)\n", | |
nr_sys, | |
regs->rdi, | |
regs->rsi, | |
regs->rdx, | |
regs->r10, | |
regs->r8, | |
regs->r9); | |
} | |
} | |
static void dump_asm_code(pid_t pid, const void *addr) | |
{ | |
char code[1024]; | |
char dump[sizeof(code) * 4]; | |
char cmd[sizeof(dump) + 128]; | |
const char *decoder = "/home/ammarfaizi2/work/linux.work/scripts/decodecode"; | |
size_t rem_len, len, i; | |
rem_len = copy_from_process(pid, code, (void *)addr, sizeof(code)); | |
if (rem_len == sizeof(code)) { | |
perror("copy_from_process"); | |
return; | |
} | |
len = sizeof(code) - rem_len; | |
for (i = 0; i < (len - 8); i++) { | |
if (!memcmp(&code[i], "\0\0\0\0\0\0\0\0", 8)) { | |
len = i; | |
break; | |
} | |
} | |
for (i = 2; i < (len - 2); i++) { | |
if (!memcmp(&code[i], "\x0f\x05", 2)) { | |
len = i + 2; | |
break; | |
} | |
} | |
dump_code(dump, code, code + 2, len); | |
snprintf(cmd, sizeof(cmd), "echo \"Code: %s\" | %s", dump, decoder); | |
system(cmd); | |
} | |
static void decode_syscall_and_asm(struct user_regs_struct *regs, pid_t pid) | |
{ | |
struct user_regs_struct cregs; | |
if (copy_from_process(pid, &cregs, (void *)regs->r10, sizeof(cregs))) { | |
perror("copy_from_process"); | |
return; | |
} | |
print_syscall_arg(&cregs); | |
dump_asm_code(pid, (const void *)(cregs.rip - 2ull)); | |
} | |
static void inspect_checkpoint(struct user_regs_struct *regs, pid_t pid) | |
{ | |
if (regs->rax != (__typeof__(regs->rax))-ENOSYS) | |
return; | |
if (regs->orig_rax != __NR_ptrace) | |
return; | |
if (regs->rdi != PTRACE_SETREGS) | |
return; | |
decode_syscall_and_asm(regs, pid); | |
} | |
static int do_trace(pid_t pid) | |
{ | |
struct user_regs_struct regs; | |
int ret; | |
ret = waitpid(pid, NULL, 0); | |
if (ret < 0) | |
return -1; | |
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL); | |
if (ret < 0) | |
return -1; | |
ret = waitpid(pid, NULL, 0); | |
if (ret < 0) | |
return -1; | |
ret = ptrace(PTRACE_GETREGS, pid, NULL, ®s); | |
if (ret < 0) | |
return -1; | |
inspect_checkpoint(®s, pid); | |
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL); | |
if (ret < 0) | |
return -1; | |
return 0; | |
} | |
static void trace_child(pid_t pid) | |
{ | |
while (1) { | |
if (do_trace(pid)) | |
return; | |
} | |
} | |
int main(void) | |
{ | |
pid_t pid; | |
pid = start_child_ptrace("/home/ammarfaizi2/Downloads/Telegram Desktop/chall_expert"); | |
if (pid < 0) | |
return 1; | |
trace_child(pid); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment