【问题标题】:ptrace to change an array in another programptrace 更改另一个程序中的数组
【发布时间】:2014-04-01 05:49:02
【问题描述】:

我正在尝试使用 ptrace 在运行时更改另一个程序变量,在我的例子中是一个虚拟 shell。

int main(void)
{
    char    buf[MAXLINE];
    fgets(buf, MAXLINE, stdin);
    if (buf[strlen(buf) - 1] == '\n')
        buf[strlen(buf) - 1] = 0;

    execlp("sh", "sh", "-c", buf, (char *)0);
    printf("couldn't execute: %s", buf);
    exit(127);
}

在我的注入器应用程序中,我使用 PTRACE_ATTACH 并监听 sys_read 系统调用;然后 PTRACE_GETREGS 尝试获取应该包含“buf”数组地址的寄存器。

    ptrace(PTRACE_SYSCALL, pid, 0, 0);
    wait(&status);
    ptrace(PTRACE_GETREGS, pid, 0, &regs);

    syscall_n = regs.orig_rax;
    if (syscall_n == SYS_read){
        switch(syscall_status){
        case STARTED:
            printf("Waiting user input... ");
            syscall_status = WAITING;
            break;

        case WAITING:
            printf("\t[  OK  ]\n");
            syscall_status = RETURNED;
            break;

        default:
            break;
        }
    }

虽然我可以在调用 fgets 时捕获正确的打开系统调用,但我不知道应该使用哪个寄存器来获取字符串数组的地址。或者有没有更好的获取方式。

所以我以后可以使用 PEEKDATA 和 POKEDATA 来注入修改后的字符串。

顺便说一句,我已阅读“使用 ptrace 第 I 部分”文章,但我不明白如何使其适应我的目的。

【问题讨论】:

    标签: arrays linux 64-bit ptrace


    【解决方案1】:

    首先,fgets() 不是系统调用,因此您不会使用 ptrace 捕获它。您将要捕获的是 sys_read() 或类似的系统调用。更重要的是,由于 stdio 中的 I/O 缓存,实际的 sys_read() 实际调用的缓冲区和长度参数可能与传递给原始 fgets() 的参数不同。

    其次,为了可靠地建立,要检查哪些寄存器,您需要知道您正在使用的确切 ABI。例如,在 ARM/EABI 上,sys_read() 调用将期望寄存器“r1”中的缓冲区指针(寄存器“r0”保存第一个参数,例如文件描述符和寄存器“r2”保存长度)。在 x86 上,它将是 ebx/ecx/edx 组合;在 amd64 上 - rdi/rsi/rdx。

    如果你真的想跟踪更高级别函数的效果(而不是系统调用),你需要深入挖掘编译器产生的调试信息,因为它或多或少是做这些事情的唯一方法(您可以尝试使用来自 elfutils 的 libelf 库,就像 ltrace 实用程序一样)。您实际上必须以编程方式在适当的位置设置断点,然后依靠调试信息来推断堆栈上的变量布局(以获取堆栈分配的缓冲区)。

    考虑使用ltrace 实用程序的源代码作为工作示例:

    http://anonscm.debian.org/gitweb/?p=collab-maint/ltrace.git;a=tree;h=refs/heads/master;hb=refs/heads/master

    顺便说一下,如果您使用的是足够新的内核,您可能会受益于使用两个新的系统调用:process_vm_readvprocess_vm_writev,它们可以“批量”操作远程进程内存,只给定目标PID 和地址(这比 ptrace PEEK 和 POKE 方便得多)。

    http://man7.org/linux/man-pages/man2/process_vm_readv.2.html

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多