Created
May 4, 2025 14:21
-
-
Save r3bb1t/e58eed85e9cfb1b7d4bf9f8788bbfc99 to your computer and use it in GitHub Desktop.
Frida script for bypassing direct sycalls in uncrackable 4
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
| class AntiAntiDebugV2 { | |
| readonly fakeMapsFile: string; | |
| /// This will be used for redirecting syscalls which are trying to open /proc/self/maps | |
| readonly fakeMapsFileNamePtr: NativePointer; | |
| readonly fridaRegex: RegExp; | |
| readonly procSelfTaskStatusRe: RegExp; | |
| readonly fakeFilePath: string; | |
| readonly fakeFilePathPtr: NativePointer; | |
| constructor() { | |
| // Construct values | |
| //const fake_maps_file_path = Process.getTmpDir() + '/fake_maps'; | |
| const fake_maps_file_path = '/data/local/tmp/fake_maps'; | |
| this.fakeMapsFileNamePtr = Memory.allocUtf8String(fake_maps_file_path); | |
| this.fakeMapsFile = fake_maps_file_path; | |
| this.fakeFilePath = '/data/local/tmp/fake'; | |
| this.fakeFilePathPtr = Memory.allocUtf8String(this.fakeFilePath); | |
| this.fridaRegex = new RegExp('frida', 'ig'); | |
| this.procSelfTaskStatusRe = new RegExp('/proc/self/task/%d*/status'); | |
| // Prepare replacements | |
| const maps_contents = File.readAllText('/proc/self/maps'); | |
| const maps_patched = maps_contents.replaceAll(this.fridaRegex, 'glibc'); | |
| console.warn(this.fakeMapsFile); | |
| File.writeAllText(this.fakeMapsFile, maps_patched); | |
| } | |
| public start_stalker(tid: ThreadId) { | |
| console.warn(`started stalking tid: ${tid}`); | |
| Stalker.follow(tid, { | |
| transform: (iterator: StalkerX86Iterator) => { | |
| let instruction = iterator.next(); | |
| do { | |
| if (instruction!.mnemonic == 'syscall') { | |
| iterator.putCallout((ctx: CpuContext) => this.handle_syscall(ctx)); | |
| } | |
| iterator.keep(); | |
| } while ((instruction = iterator.next()) !== null); | |
| } | |
| }); | |
| } | |
| private handle_syscall(ctx: CpuContext) { | |
| // Note: | |
| // On x86 first args are passed in the following order: | |
| // RAX (holds syscall nuber), RDI, RSI, RDX, R10, R8, R9 | |
| const context: X64CpuContext = ctx as X64CpuContext; | |
| const curr_syscall = X86Syscalls[context.rax.toUInt32()]; | |
| const file_access_syscalls = ['open', 'stat', 'lstat', 'access', 'execve', 'chdir', 'chmod', 'chown', 'lchown', 'utimes', 'mknod', | |
| 'chroot', 'utimes', 'openat', 'mknodat', 'fchownat', 'futimesat', 'newfstatat', 'fchmodat', 'faccessat', 'utimensat', 'readlinkat']; | |
| if (curr_syscall != 'read') { | |
| if (file_access_syscalls.includes(curr_syscall)) | |
| this.handle_file_syscalls(context, curr_syscall); | |
| // else | |
| // console.log(curr_syscall); | |
| } | |
| } | |
| private handle_file_syscalls(context: X64CpuContext, curr_syscall: string) { | |
| // Usually file paths are in rsi | |
| let file_path = ""; | |
| if (['open', 'stat', 'lstat', 'access', 'execve', 'chdir', 'chmod', 'chown', 'lchown', 'utime', 'mknod', 'chroot', 'utimes'].includes(curr_syscall)) | |
| file_path = context.rdi.readCString()!; | |
| else | |
| file_path = context.rsi.readCString()!; | |
| //console.warn(`${curr_syscall} : ${file_path}`); | |
| if (curr_syscall == 'openat') { | |
| //if (this.procSelfTaskStatusRe.test(file_path)) { | |
| if (file_path.startsWith('/proc/self/task') && file_path.endsWith('status')) { | |
| const contents = File.readAllText(file_path); | |
| //console.log(contents); | |
| if (contents.includes('gmain')) { | |
| File.writeAllText(this.fakeMapsFile, contents.replaceAll('gmain', 'i_am_good_task')); | |
| context.rsi = this.fakeFilePathPtr; | |
| console.error(`replaced access to task which has gmain name in it. (${file_path})`) | |
| } | |
| } | |
| } | |
| else if (file_path.startsWith('/proc/self/fd')) { | |
| context.rsi = this.fakeFilePathPtr; | |
| } | |
| // console.log(`opening file with contents: \n${File.readAllText(file_path)}\n`); | |
| } | |
| } | |
| enum X86Syscalls { | |
| read, | |
| write, | |
| open, | |
| close, | |
| stat, | |
| fstat, | |
| lstat, | |
| poll, | |
| lseek, | |
| mmap, | |
| mprotect, | |
| munmap, | |
| brk, | |
| rt_sigaction, | |
| rt_sigprocmask, | |
| rt_sigreturn, | |
| ioctl, | |
| pread64, | |
| pwrite64, | |
| readv, | |
| writev, | |
| access, | |
| pipe, | |
| select, | |
| sched_yield, | |
| mremap, | |
| msync, | |
| mincore, | |
| madvise, | |
| shmget, | |
| shmat, | |
| shmctl, | |
| dup, | |
| dup2, | |
| pause, | |
| nanosleep, | |
| getitimer, | |
| alarm, | |
| setitimer, | |
| getpid, | |
| sendfile, | |
| socket, | |
| connect, | |
| accept, | |
| sendto, | |
| recvfrom, | |
| sendmsg, | |
| recvmsg, | |
| shutdown, | |
| bind, | |
| listen, | |
| getsockname, | |
| getpeername, | |
| socketpair, | |
| setsockopt, | |
| getsockopt, | |
| clone, | |
| fork, | |
| vfork, | |
| execve, | |
| exit, | |
| wait4, | |
| kill, | |
| uname, | |
| semget, | |
| semop, | |
| semctl, | |
| shmdt, | |
| msgget, | |
| msgsnd, | |
| msgrcv, | |
| msgctl, | |
| fcntl, | |
| flock, | |
| fsync, | |
| fdatasync, | |
| truncate, | |
| ftruncate, | |
| getdents, | |
| getcwd, | |
| chdir, | |
| fchdir, | |
| rename, | |
| mkdir, | |
| rmdir, | |
| creat, | |
| link, | |
| unlink, | |
| symlink, | |
| readlink, | |
| chmod, | |
| fchmod, | |
| chown, | |
| fchown, | |
| lchown, | |
| umask, | |
| gettimeofday, | |
| getrlimit, | |
| getrusage, | |
| sysinfo, | |
| times, | |
| ptrace, | |
| getuid, | |
| syslog, | |
| getgid, | |
| setuid, | |
| setgid, | |
| geteuid, | |
| getegid, | |
| setpgid, | |
| getppid, | |
| getpgrp, | |
| setsid, | |
| setreuid, | |
| setregid, | |
| getgroups, | |
| setgroups_2, | |
| setresuid, | |
| getresuid, | |
| setresgid, | |
| getresgid, | |
| getpgid, | |
| setfsuid, | |
| setfsgid, | |
| getsid, | |
| capget, | |
| capset, | |
| rt_sigpending, | |
| rt_sigtimedwait, | |
| rt_sigqueueinfo, | |
| rt_sigsuspend, | |
| sigaltstack, | |
| utime, | |
| mknod, | |
| uselib, | |
| personality, | |
| ustat, | |
| statfs, | |
| fstatfs, | |
| sysfs, | |
| getpriority, | |
| setpriority, | |
| sched_setparam, | |
| sched_getparam, | |
| sched_setscheduler, | |
| sched_getscheduler, | |
| sched_get_priority_max, | |
| sched_get_priority_min, | |
| sched_rr_get_interval, | |
| mlock, | |
| munlock, | |
| mlockall, | |
| munlockall, | |
| vhangup, | |
| modify_ldt, | |
| pivot_root, | |
| _sysctl, | |
| prctl, | |
| arch_prctl, | |
| adjtimex, | |
| setrlimit, | |
| chroot, | |
| sync, | |
| acct, | |
| settimeofday, | |
| mount, | |
| umount2, | |
| swapon, | |
| swapoff, | |
| reboot, | |
| sethostname, | |
| setdomainname, | |
| iopl, | |
| ioperm, | |
| create_module, | |
| init_module, | |
| delete_module, | |
| get_kernel_syms, | |
| query_module, | |
| quotactl, | |
| nfsservctl, | |
| getpmsg, | |
| putpmsg, | |
| afs_syscall, | |
| tuxcall, | |
| security, | |
| gettid, | |
| readahead, | |
| setxattr, | |
| lsetxattr, | |
| fsetxattr, | |
| getxattr, | |
| lgetxattr, | |
| fgetxattr, | |
| listxattr, | |
| llistxattr_2, | |
| flistxattr, | |
| removexattr, | |
| lremovexattr, | |
| fremovexattr, | |
| tkill, | |
| time, | |
| futex, | |
| sched_setaffinity, | |
| sched_getaffinity, | |
| set_thread_area, | |
| io_setup, | |
| io_destroy, | |
| io_getevents, | |
| io_submit, | |
| io_cancel, | |
| get_thread_area, | |
| lookup_dcookie, | |
| epoll_create, | |
| epoll_ctl_old, | |
| epoll_wait_old, | |
| remap_file_pages, | |
| getdents64, | |
| set_tid_address, | |
| restart_syscall, | |
| semtimedop, | |
| fadvise64, | |
| timer_create, | |
| timer_settime, | |
| timer_gettime, | |
| timer_getoverrun, | |
| timer_delete, | |
| clock_settime, | |
| clock_gettime, | |
| clock_getres, | |
| clock_nanosleep, | |
| exit_group, | |
| epoll_wait, | |
| epoll_ctl, | |
| tgkill, | |
| utimes, | |
| vserver, | |
| mbind, | |
| set_mempolicy, | |
| get_mempolicy, | |
| mq_open, | |
| mq_unlink, | |
| mq_timedsend, | |
| mq_timedreceive, | |
| mq_notify, | |
| mq_getsetattr, | |
| kexec_load, | |
| waitid, | |
| add_key, | |
| request_key, | |
| keyctl, | |
| ioprio_set, | |
| ioprio_get, | |
| inotify_init, | |
| inotify_add_watch, | |
| inotify_rm_watch, | |
| migrate_pages, | |
| openat, | |
| mkdirat, | |
| mknodat, | |
| fchownat, | |
| futimesat, | |
| newfstatat, | |
| unlinkat, | |
| renameat, | |
| linkat, | |
| symlinkat, | |
| readlinkat, | |
| fchmodat, | |
| faccessat, | |
| pselect6, | |
| ppoll, | |
| unshare, | |
| set_robust_list, | |
| get_robust_list, | |
| splice, | |
| tee, | |
| sync_file_range, | |
| vmsplice, | |
| move_pages, | |
| utimensat, | |
| epoll_pwait, | |
| signalfd, | |
| timerfd_create, | |
| eventfd, | |
| fallocate, | |
| timerfd_settime, | |
| timerfd_gettime, | |
| accept4, | |
| signalfd4, | |
| eventfd2, | |
| epoll_create1, | |
| dup3, | |
| pipe2, | |
| inotify_init1, | |
| preadv, | |
| pwritev, | |
| rt_tgsigqueueinfo, | |
| perf_event_open, | |
| recvmmsg, | |
| fanotify_init, | |
| fanotify_mark, | |
| prlimit64, | |
| name_to_handle_at, | |
| open_by_handle_at, | |
| clock_adjtime, | |
| syncfs, | |
| sendmmsg, | |
| setns, | |
| getcpu, | |
| process_vm_readv, | |
| process_vm_writev, | |
| kcmp, | |
| finit_module, | |
| sched_setattr, | |
| sched_getattr, | |
| renameat2, | |
| seccomp, | |
| getrandom, | |
| memfd_create, | |
| kexec_file_load, | |
| bpf, | |
| execveat, | |
| userfaultfd, | |
| membarrier, | |
| mlock2, | |
| copy_file_range, | |
| preadv2, | |
| pwritev2, | |
| pkey_mprotect, | |
| pkey_alloc, | |
| pkey_free, | |
| statx | |
| } | |
| const ad2 = new AntiAntiDebugV2(); | |
| Process.attachThreadObserver({ | |
| onAdded(thread) { | |
| if (thread.name == "re.pwnme") | |
| ad2.start_stalker(thread.id) | |
| } | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment