I've seen this done on Windows using CreateProcess, although I believe it wasn't specifically for anti-debugging purposes but instead a process that wanted to reinitialise itself from the beginning.
A far more effective actual anti-debugging technique is to have the parent become the debugger of the child, preventing any other debugger from attaching to it.
But then you can attach to the parent and cause it to stop debugging the child so you can. I think you want a process to be its own debugger; idk if ptrace(2) allows that. Then there's things like DTrace and eBPF -- I don't think you can prevent them from the target.
this is how ptrace works in essence, so if you look in the man pages for that ptrace there's an example. you just ptrace_attach from the parent to the child pid. it couldn't be more straighforward usage of ptrace. https://man7.org/linux/man-pages/man2/ptrace.2.html
long ptrace(enum __ptrace_request op, pid_t pid,
void addr, void data);
The patch code looks like a rather convoluted way of patching out the function code. Can we not just replace conditional branch with a regular one and nop out the rest? Or at least set w8 to 1 manually? I know next to nothing about ARM assembly, so I'm most likely missing something.
I am not really experienced with ARM haha :) So the way that I approached it was:
- how could I remove the call of fork (because I don't want to fork)
- how could I patch the register that should contains the result of the fork operation
I guess that it sounds like a naive approach haha
Feel free to propose an alternative I patch, I could update the post and credit you :)
```
(lldb) run
Process 14345 launched: '/anti-debug/swift/build/anti_debug' (arm64)
start pid = 14345
exit parent process for child pid = 14348
continue as child process pid = 14348
Process 14345 exited with status = 0 (0x00000000)
```
The main reason for using dlsym instead of calling fork directly is to make it harder for an ‘attacker’ to detect or set breakpoints on the fork function, thus obfuscating the anti-debugging mechanism. You have to more checks before being able to understand why you cannot attach the debuger.
You may still think that mode could be still able to catch a new child process but apparently people have tried and the answer is no
> You may still think that mode could be still able to catch a new child process but apparently people have tried and the answer is no
Not sure I got this. IIUC there is a link between the fact that we used dlsym and the fact the child process is not catched by lldb in the follow fork mode?
At first, it appears that the follow fork mode works nicely. But at some point it did not ... If I run it 10 times consequtively in LLDB. Sometimes it works, sometimes not ...
A far more effective actual anti-debugging technique is to have the parent become the debugger of the child, preventing any other debugger from attaching to it.