strace.so pintool 显示的 IP

逆向工程 仪器仪表
2021-06-13 18:08:42

我有一个静态编译的测试二进制文件编译为:-

$ cat > test.c
 #include<stdio.h>
int main() {
printf("adsf");
mprotect(0x8048000, 0x100, 0x7);
}
$ gcc -o test test.c -static

我使用 strace.so pintool 并获得以下输出:-

0xb77c0419: 122(0xbfa1a72a, 0xb77c0000, 0x0, 0x0, 0x8049630, 0xbfa1a6ec)returns: 0x0
0xb77c0419: 45(0x0, 0x840, 0x27, 0xd40, 0x28, 0xbfa1a868)returns: 0x9fda000
0xb77c0419: 45(0x9fdad40, 0x840, 0x9fda000, 0x9fdad40, 0x28, 0xbfa1a868)returns: 0x9fdad40
0x80493b9: 243(0xbfa1a8c0, 0x0, 0x4, 0x4, 0x28, 0x40)returns: 0x0
0xb77c0419: 45(0x9ffbd40, 0x21000, 0x21000, 0x9ffbd40, 0x0, 0xbfa1a728)returns: 0x9ffbd40
0xb77c0419: 45(0x9ffc000, 0x2c0, 0x21000, 0x9ffc000, 0x0, 0xbfa1a728)returns: 0x9ffc000
0xb77c0419: 197(0x1, 0xbfa1a210, 0xbfa1a210, 0x2000, 0x2000, 0xbfa1a1b8)returns: 0x0
0xb77c0419: 192(0x0, 0x1000, 0x3, 0x22, 0xffffffff, 0xbfa1a1cc)returns: 0xb60b6000
0xb77c0419: 125(0x8048000, 0x100, 0x7, 0x0, 0x8049630, 0xbfa1a8d8)returns: 0x0
0xb77c0419: 4(0x1, 0xb60b6000, 0x4, 0x80ef6a0, 0x4, 0xbfa1a778)returns: 0x4
0xb77c0419: 252(0x0, 0x0, 0x80f0d04, 0x0, 0x80ef06c, 0xbfa1a8ac)#eof

我们可以看到左侧显示的地址(IP)具有重复值。此外,它们似乎不是文本段中的地址。我希望能够查看进行系统调用的地址。

为什么会发生这种情况?可以在此处找到 strace pintool 的代码

[编辑] 检查 gdb 我知道发生这种情况是因为调用是通过一个常见的“int 0x80”指令进行的。结果,多个系统调用似乎是从同一个地址发出的。因此,似乎我必须从堆栈顶部读取 4 个字节才能找出试图进行系统调用的指令。有没有更好的方法来做到这一点?

1个回答

在现代 Linux 系统上,系统调用存根 ( vdso) 用于调用实际的系统调用。这样做是为了使应用程序二进制文件不需要了解有关主机 CPU 的任何信息,以及哪种机制对 CPU 来说是最好的或最快的。

这可以从 GDB 内部或通过ldd.

ldd /bin/bash
    linux-vdso.so.1 =>  (0x00007fff07fc3000)
    libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f65e336e000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f65e316a000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f65e2da3000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f65e35b6000)

您可以通过打印 的返回值轻松转储正在使用 Pin 执行的指令INS_Disassemble您应该看到它实际上是一个syscall指令或类似指令。

关于确定 VDSO 调用源的最佳机制,检查例程入口处的堆栈顶部将为您提供其返回地址。这将是指令几个字节call此外,您必须将 中的显式地址列入白名单vdso,因为并非所有int 0x80指令都会在调用后立即执行。