首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么dup2的工作方式与直接称为dup2不同?

为什么dup2的工作方式与直接称为dup2不同?
EN

Stack Overflow用户
提问于 2022-05-01 18:28:03
回答 1查看 51关注 0票数 0

我试着把tracee的标准文件重定向到一个文件上。

为此,我:

  1. 附在特雷西
  2. mmap有些记忆
  3. 将文件名复制到tracee的内存中
  4. 让tracee打开文件

为了达到这些结果,我必须深入存储库。

到目前为止,我的结果看起来很好,我在top命令中进行跟踪,lsof可以检测到我的工作(参见最后一行):

代码语言:javascript
复制
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF       NODE NAME
top     421762 root  cwd    DIR  179,2     4096      17528 /root
top     421762 root  rtd    DIR  179,2     4096          2 /
top     421762 root  txt    REG  179,2   124856      12493 /usr/bin/top
top     421762 root    0u   CHR  136,1      0t0          4 /dev/pts/1
top     421762 root    1u   CHR  136,1      0t0          4 /dev/pts/1
top     421762 root    2w   CHR    1,3      0t0          5 /dev/null
top     421762 root    3u   CHR  136,1      0t0          4 /dev/pts/1
top     421762 root    4r   REG   0,17        0 4026533347 /proc/stat
top     421762 root    5r   REG   0,17        0 4026533348 /proc/uptime
top     421762 root    6r   REG   0,17        0 4026533346 /proc/meminfo
top     421762 root    7r   REG   0,17        0 4026533345 /proc/loadavg
top     421762 root    8u  FIFO   0,28      0t0        827 /tmp/mystdout

这是我的命令的输出(仅仅是为了完整性):

代码语言:javascript
复制
[+] Allocated scratch page: 7fbd357000
[+] Opened the new fd in the child: 8 (/tmp/mystdout)
[+] Saved fd 1 to -1 in the child
[+] Duplicated fd 8 to 1
[+] Freed scratch page: 7fbd357000

我现在要做的是最后一步,那就是dup2,tracee的标准输出到打开的file_fd (8)。

可行性

我编写了一个非常小的程序来测试dup2如何在目标平台(Aarch64)上工作:

代码语言:javascript
复制
int i = 0;
while(1) {
    printf("helloworld %d\n", i++);
    sleep(1);
    
    if (i==5) {
        printf("Opening tmp file\n");
        int file_fd = open("/tmp/mystdout", O_RDWR | O_CREAT, 0666, 0, 0);
        printf("File opened=%d\n", file_fd);
        
        int err = dup2(file_fd, 1);
        printf("dup2 result=%d\n", err);
        
        close(file_fd);
    }
}

这个测试程序验证了我可以在file_fd调用之后关闭dup2,而且程序仍然会在默认情况下继续记录到这个文件。甚至我的"dup2 result=1“也会打印到文件中(而不是在stdout上)。

考虑dup2 2的返回值1匹配它的预期行为,通过它的文档:

成功后,这些系统调用将返回新的文件描述符。

尝试使用ptrace进行dup2

如果直接调用已验证的dup2,那么我现在用file_fd (8)和orig_fd (1)的参数调用tracee中的tracee中的tracee:

代码语言:javascript
复制
int err = do_syscall(child, dup2, file_fd, orig_fd, 0, 0, 0, 0);
debug("Duplicated fd %d to %d, return=%d", file_fd, orig_fd, err);

这样,程序的输出将更改为:

代码语言:javascript
复制
[+] Allocated scratch page: 7fbd357000
[+] Opened the new fd in the child: 8 (/tmp/mystdout)
[+] Saved fd 1 to -1 in the child
[+] Duplicated fd 8 to 1, return=8 !!!
[+] Freed scratch page: 7fbd357000

如您所见,成功地执行了dup2 (正返回值),但返回了8而不是1。

同样,我使用以下方法调用ptraced dup2:

代码语言:javascript
复制
int err = do_syscall(child, dup2, 8, 1, 0, 0, 0, 0);

我不知道如何在这里详细说明这个方法,因为它有点太大了,但作为参考,我在这里调用openat,它实际上在tracee的过程中打开了所需的文件:

代码语言:javascript
复制
int file_fd = do_syscall(child, openat, AT_FDCWD, scratch_page, O_RDWR | O_CREAT, 0666, 0, 0);

(注意: scratch_page是一个映射在tracee空间中的内存,在使用上面的指令之前,"/tmp/mystdout“被复制到其中)

所以问题是:

如何调试注入的dup2?例如,使用strace

我希望理解为什么它的行为与直接从小型测试应用程序调用时不同。

EN

回答 1

Stack Overflow用户

发布于 2022-05-02 14:45:11

结果发现,在aarch64上,由于某种原因,dup2无法注入。

不管我试过什么,结果总是很奇怪。

然而,在我将dup2更改为dup3之后,一切都神奇地开始工作了。

我仍然想知道为什么dup2 syscall不能工作,但是现在经过几天的挖掘和学习,我对这个结果很满意。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72079386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档