Skip to content

Instantly share code, notes, and snippets.

@r3bb1t
Created May 4, 2025 14:21
Show Gist options
  • Select an option

  • Save r3bb1t/e58eed85e9cfb1b7d4bf9f8788bbfc99 to your computer and use it in GitHub Desktop.

Select an option

Save r3bb1t/e58eed85e9cfb1b7d4bf9f8788bbfc99 to your computer and use it in GitHub Desktop.
Frida script for bypassing direct sycalls in uncrackable 4
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