【问题标题】:How to get a char* with ptrace如何使用 ptrace 获取 char*
【发布时间】:2012-05-10 06:38:26
【问题描述】:

我目前正在开发一种工具,我必须在其中跟踪程序以了解他的系统调用。目前,我能够获取系统调用的数字参数,但无法正确获取字符串的地址。

这是我继续的方式:

  long addr = ptrace(PTRACE_PEEKDATA, pid, regs.ebx, NULL);
  printf("%s", (char *) &addr);

使用那段代码,我可以得到字符串的开头(前 3 或 4 个字符),但结尾已损坏,我不知道为什么。

你有什么解决办法吗? 谢谢。

【问题讨论】:

  • @Jeffey Muller:您试图捕获特定系统调用的参数,对吧?我构建了一个类似的应用程序,它类似于 strace,但适用于更少的系统调用。

标签: c char system-calls ptrace


【解决方案1】:

您确定不想要这个吗?

printf("%lX", addr);

【讨论】:

  • 我想打印字符串。例如,如果 tracee 二进制文件执行 write(1, "hello world", 14) ,我想获取字符串 "hello world" 而不是地址。
  • @JeffreyMuller 好吧,但是你写的代码没有多大意义,要么你得到一个字符串的地址,在这种情况下,你应该追踪那个地址,或者你得到了一部分字符串,在这种情况下,您需要使用 ptrace 单步执行该字符串,直到您完全阅读它为止。
  • 在 regs.ebx 中,我想我有字符串的地址。所以我使用 PTRACE_PEEKDATA 来获取 ebx 指向的数据,但是 ptrace 给我的地址不行。这是一个分段错误。这是一个例子:pastebin.com/p3rdCXDV
  • @JeffreyMuller ptrace 返回数据,而不是地址,请阅读手册页,特别是 PTRACE_PEEKDATA 部分。
【解决方案2】:
char *read_string (int child, unsigned long addr) {
    char *val = malloc(4096);
    if (!val)
        return NULL;

    int allocated = 4096, read = 0;
    unsigned long tmp =0;
    while(1) {
        if (read + sizeof (tmp) > allocated) {
            allocated *= 2;
            char *temp_val = realloc (val, allocated);
            if (!temp_val) {
                free(val);
                return NULL;
            }
            val = temp_val;
        }
        tmp = ptrace(PTRACE_PEEKDATA, child, addr + read);
        if(errno != 0) {
            val[read] = 0;
            break;
        }
        memcpy(val + read, &tmp, sizeof tmp);
        if (memchr(&tmp, 0, sizeof tmp) != NULL) break;
        read += sizeof tmp;
    }
    return val;
} // Don't forget to free the returned val.

尝试使用以下函数,它是我在应用程序中编写的内容的一部分:

reg_val[1] = ptrace (PTRACE_PEEKUSER, child, 4 * EBX, NULL);
char *filepath = read_string(child, reg_val[1]);

Child 是我正在跟踪的子进程的 pid。如果这不起作用,请告诉我?

【讨论】:

    【解决方案3】:

    使用您发布的代码,您仅通过调用 ptrace 读取 4 个字节的数据(即 4 个字符)。您需要从调试进程中读取整个缓冲区,然后才能在父进程中打印出字符串。即在你读完addr之后,你需要循环

       ptrace(PTRACE_PEEKTEXT, child, addr, NULL)
       addr+=4;
    

    直到您阅读完整的字符串。

    然后你可以使用 printf() 打印出来

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      • 2019-10-02
      • 2013-11-30
      • 1970-01-01
      相关资源
      最近更新 更多