Linux下如何捕获由汇编程序通过sys_execve启动的程序的标准输出?
解决方法:手动实现标准输出重定向
你遇到的核心问题是:>messages.txt是shell的重定向语法,只有shell会解析它并完成文件描述符的重定向操作。直接把它作为参数传给myecho,程序只会将其当作普通字符串输出,不会触发重定向。
要实现需求,你需要在汇编代码中手动完成内核级的文件重定向操作,具体步骤如下:
方法1:直接在当前进程中重定向并执行(适用于myprog执行myecho后退出的场景)
这种方法不需要fork,直接在当前进程中修改stdout的指向,再执行myecho:
汇编代码示例
[.data] Par1 DB "Param1",0 Par2 DB "Param2",0 Env1 DB 0 ; 未使用 Command DB "/path/to/myecho",0 Parameters DD Par1,Par2,0 ; 移除>messages.txt参数 OutputFile DB "messages.txt",0 ; 输出文件名 [.text] ; 1. 打开/创建messages.txt文件 MOV EAX,5 ; 32位Linux sys_open系统调用号 MOV EBX,OutputFile ; 文件名指针 MOV ECX,0x241 ; 打开标志:O_WRONLY(1) | O_CREAT(0x40) | O_TRUNC(0x200) MOV EDX,0644o ; 文件权限:八进制644(所有者读写,组和其他只读) INT 0x80 CMP EAX,-1 ; 检查是否打开失败 JL exit_with_error ; 失败则退出 ; 2. 保存文件描述符到EDX MOV EDX,EAX ; 3. 将stdout(文件描述符1)重定向到刚打开的文件 MOV EAX,63 ; 32位Linux sys_dup2系统调用号 MOV EBX,EDX ; 源文件描述符(刚打开的messages.txt) MOV ECX,1 ; 目标文件描述符(stdout) INT 0x80 ; 4. 关闭原文件描述符(dup2后无需保留) MOV EAX,6 ; 32位Linux sys_close系统调用号 MOV EBX,EDX INT 0x80 ; 5. 执行myecho MOV EAX,11 ; 32位Linux sys_execve系统调用号 MOV EBX,Command MOV ECX,Parameters MOV EDX,Env1 INT 0x80 ; 错误处理:execve失败或文件打开失败时退出 exit_with_error: MOV EAX,1 ; sys_exit系统调用号 MOV EBX,1 ; 退出码1表示错误 INT 0x80
方法2:通过fork创建子进程执行(适用于myprog需要继续处理输出文件的场景)
如果myprog需要在myecho执行完成后读取并处理messages.txt,需要先fork子进程执行重定向和myecho,父进程等待子进程结束后再操作文件:
汇编代码示例
[.data] Par1 DB "Param1",0 Par2 DB "Param2",0 Env1 DB 0 ; 未使用 Command DB "/path/to/myecho",0 Parameters DD Par1,Par2,0 OutputFile DB "messages.txt",0 [.text] ; 1. fork创建子进程 MOV EAX,2 ; sys_fork系统调用号 INT 0x80 CMP EAX,0 JE child_process ; EAX=0表示当前是子进程 ; 父进程逻辑:等待子进程结束 MOV EBX,EAX ; 子进程PID存入EBX MOV EAX,7 ; sys_waitpid系统调用号 MOV ECX,0 ; 不保存子进程状态 MOV EDX,0 ; 无特殊选项 INT 0x80 ; --- 此处添加处理messages.txt的代码 --- ; 例如打开文件、读取内容等操作 ; 父进程正常退出 MOV EAX,1 MOV EBX,0 INT 0x80 ; 子进程逻辑:重定向stdout并执行myecho child_process: ; 打开messages.txt MOV EAX,5 MOV EBX,OutputFile MOV ECX,0x241 MOV EDX,0644o INT 0x80 CMP EAX,-1 JL child_exit MOV EDX,EAX ; 重定向stdout到文件 MOV EAX,63 MOV EBX,EDX MOV ECX,1 INT 0x80 ; 关闭原文件描述符 MOV EAX,6 MOV EBX,EDX INT 0x80 ; 执行myecho MOV EAX,11 MOV EBX,Command MOV ECX,Parameters MOV EDX,Env1 INT 0x80 ; 子进程退出(execve失败时执行) child_exit: MOV EAX,1 MOV EBX,1 INT 0x80
关键说明
- 重定向的本质是修改进程的文件描述符表:通过
sys_dup2将stdout(fd=1)的指向替换为目标文件的文件描述符,这样后续所有写入stdout的操作都会直接写到目标文件。 - 不需要使用
tee或管道,除非你需要同时将输出发送到文件和保留终端输出。你的需求仅需捕获到文件,直接重定向是最简洁的方案。
内容的提问来源于stack exchange,提问作者vitsoft
相关产品推荐
相关产品推荐

