1

我有一个文件范围内核扩展,它在启动应用程序时通知守护程序。守护进程需要在 main() 中的第一条指令开始时暂停已启动的应用程序。

当使用 PT_ATTACH 调用 ptrace 时,守护程序似乎连接得太早并且位于动态链接器 (dyld) 中。

这是附加时线程0的调用堆栈的示例:-

Thread 0:
0   dyld                            0x00007fff6e4cd35e mach_reply_port + 10
1   dyld                            0x00007fff6e4cd4d4 _mig_init + 13
2   dyld                            0x00007fff6e4cd17f mach_init + 46
3   dyld                            0x00007fff6e4aa239 dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 411
4   dyld                            0x00007fff6e4aa05e _dyld_start + 54

因此,有什么方法可以确保在加载库完成后守护进程可以附加到 main 函数的开头,或者重复单步到该点,在这种情况下,我怎么能找到 main 的地址,考虑到启动的应用程序可能没有可用的符号?

谢谢。

4

2 回答 2

0

只是一个猜测,但由于 libc 必须在exitafter调用main,您可能可以main通过步行来识别调用,_start直到找到对该.text部分的调用,然后是对该部分的调用.plt。您还知道退出状态main是 to 的参数exit,因此您正在寻找 a mov %eax, %edi,并且可能main出现在 之后_start.plt之前.text,并且您知道两者都不会走得太远,因此您可以使其非常通用。

鉴于运行时/libc/编译器是健全的(Mac OS X 基于 FreeBSD,对吗?),您可能只需匹配几个字节就可以逃脱,像这样(您可能至少应该增加一些安全性):

size_t *find_main_vmoffset(char *text_start, size_t text_size)
{
    char *p = text_start;

    const char sig[] = {
        /* 0xe8, ??, ??, */ 0, 0,       /* callq  main */
        0x89, 0xc7,             /* mov    %eax, %edi */ 
        0xe8, /* ??, ??, 0xff, 0xff, */     /* callq  exit */
    };

    while (p = memmem(p, text_size - (p - text_start), sig, sizeof(sig))) {
        /* Check it's one call followed by another */
        if (p[-3] != 0xe8)
            continue;
        /* Check the second call is backwards (into .plt) */
        if (p[7] != 0xff || p[8] != 0xff)
            continue;

        /* Eureka! */
        return (p - text_start) + 2 + *(int32_t *)(p - 2);
    }
    return 0;
}

你只需要添加它的虚拟地址.text,你基本上就完成了:)。

于 2016-09-21T01:18:39.957 回答
-1

Main 不是实际的入口点,而是映射到程序集可执行文件的 _start 符号的名称。根据您的可执行文件类型(elf-32 或其他),它将从不同的地址开始(这可能是随机的)。您可以使用 GDB 通过单步执行程序一次(使用 gdb,然后 si)来查找入口点的地址(或执行的第一条指令),然后打印 PC 寄存器的值(使用 show registers 或其他东西)。

您还可以切换到 gdb 中的程序集布局并查看整个堆栈跟踪并查看它从哪里开始。可执行代码通常以 0x0800xxxx 开头

于 2013-05-13T14:56:00.423 回答