我试图理解一个程序。该程序实现了一种反调试技术。
据我目前所知,父亲ptrace
是一个分叉的过程。
一个孩子会做这样的事情:
some code
Int 3
some code
Int 3
some code
Int 3
等等
我认为父亲实现了一种调试器,因为strace -i
我看到了很多:
[77b7457c] waitpid(2468, [{WIFSTOPPED(s) && WSTOPSIG(s) == SIGTRAP}], __WALL) = 2468
[77b7457c] --- SIGCHLD (Child exited) @ 0 (0) ---
[77baf52c] ptrace(PTRACE_GETREGS, 2468, 0, 0x7fb68be4) = 0
[77baf52c] ptrace(PTRACE_SETREGS, 2468, 0, 0x7fb68be4) = 0
[77baf52c] ptrace(PTRACE_CONT, 2468, 0, SIG_0) = 0
它让我想起了这个文档http://www.alexonlinux.com/how-debugger-works在这里我们发现了相同的想法:一个子进程,发送 TRAP,通过 ptrace 调用被父进程捕获,将寄存器设置为正确的值,然后继续。
我现在的问题:如何调试这个“调试器”?
- 如果我绕过 ptrace,孩子将得到它的 SIGTRAP 并停止。
- 如果我离开 ptrace,我就不能使用 gdb
- 如果我绕过 ptrace 并使用 gdb with
set follow-fork-mode child
,我将无法跟踪在父进程中捕获陷阱的方式和位置,因为 gdb 处理它。如果我发送signal SIGTRAP
父亲检测到它(如何?这是我想了解的一件事)并终止。
我知道gdb不能同时跟随父子,那么有没有办法调试这个程序?