在调试 32 位 Linux 可执行文件时,我在绕过对 ptrace 的调用时遇到了一些麻烦。
我有这个二进制文件:ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=b1579d4c55e90110491da76331c9a158b77a5729, stripped
我一直在尝试调试它。所以由于它是一个剥离的二进制文件,我使用 gdb 找到了入口点。
gef➤ info file
Entry point: 0x804849c
.
.
.
other stuff
到达入口点后,我打印出以下说明:
gef➤ x/15i 0x804849c
0x804849c: xor ebp,ebp
0x804849e: pop esi
0x804849f: mov ecx,esp
0x80484a1: and esp,0xfffffff0
0x80484a4: push eax
0x80484a5: push esp
0x80484a6: push edx
0x80484a7: push 0x8048580
0x80484ac: push 0x8048590
0x80484b1: push ecx
0x80484b2: push esi
0x80484b3: push 0x8048480
0x80484b8: call 0x8048350 <__libc_start_main@plt>
0x80484bd: hlt
0x80484be: nop
我知道0x8048480
是主函数的地址。现在我在 main (0x8048480) 处放置了一个断点,然后运行程序,但我无法进入断点,程序以代码 01 退出。因此我决定运行strace ./binary
命令,ptrace 调用禁止我进一步调试:
ptrace(PTRACE_TRACEME) = -1 EPERM (Operation not permitted)
为了绕过这个,我尝试使用 LD_PRELOAD 环境变量。
因此我创建了一个简单的 .c 文件:
long ptrace(int request, int pid, void *addr, void *data) {
return 0;
}
并使用以下命令将其编译为共享库:
gcc -fPIC -shared -m32 ptrace.c -o ptrace.so
这里是命令文件 ptrace.so 的输出
ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=a9de523da44299f76ad94373a07c9c5f6f3c76db, not stripped
接下来,我首先使用命令在 shell 中设置环境变量 LD_PRELOAD export LD_PRELOAD=./ptrace.so
,然后在 gdb 中设置set environment LD_PRELOAD=./ptrace.so
但这是输出:
ERROR: ld.so: object './ptrace.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.
我怎样才能绕过 ptrace 调用?
谢谢你。