Search code examples
linuxassemblyx86io-redirection

How to capture std-output of program spawned by other program?


I have a binary executable for Linux, say "myecho", which reads its arguments from command-line and echoes them on standard output.
Then I am writing another binary executable in assembler (without "libc" or other C-libraries), say its name is "myprog". I want it to spawn "myecho" using kernel function sys_execve and I want to capture "myecho"'s standard output to a file "messages.txt" for further processing.
I don't know how to tell the spawned "myecho" to redirect its output to a file.

myprog program
[.data]
Par1        DB "Param1",0
Par2        DB "Param2",0
Par3        DB ">messages.txt",0
Env1        DB 0 ; Not used.
Command     DB "/path/to/myecho",0
Parameters  DD Par1,Par2,Par3,0
Environment DD Env1
[.text]
; Execute "myecho" from "myprog":
MOV EAX,11          ; Kernel # of "execve" in 32bit Linux.
MOV EBX,Command     ;
MOV ECX,Parameters  ;
MOV EDX,Environment ;
INT 0x80

I expected the execve'd line be something like

 /path/to/myecho Param1 Param2 >messages.txt

but it seems to not work like that.
">messages.txt" is treated like a third parameter verbatim. I tried to escape the redirection operator > with ^ or with Esc:

Par3    DB "^>messages.txt",0
Par3    DB 27,">messages.txt",0

but without success. Perhaps I'll need to spawn "myecho" with fork instead of execve and use tee to pipe its output but I don't know how to connect "myecho"'s output to "tee"'s file descriptors.

How can I run "myecho" inside "myprog", capture its output to a file and then process this output in "myprog"?


Solution

  • Yes, I was looking for dup2 to redirect standard output to a file handle, as fuz has commented. I used the procedure proposed by Jester and it works now.

    I will post here my simplified solution in asm which invokes kernel functions using a macro LinAPI.

    myprog program
    [.data]
        Par1        DB "Param1",0
        Par2        DB "Param2",0
        Env1        DB 0 ; Not used.
        Command     DB "/path/to/myecho",0
        Parameters  DD Command,Par1,Par2,0
        Environment DD Env1
        Messages    DB "messages.txt",0
        FdMessages  DD 0 ; File descriptor of "messages.txt".
    [.text]
        LinAPI open, Messages, O_RDWR+O_CREAT, 777q
        MOV [FdMessages],EAX ; File descriptor of the text file (empty so far).
        LinAPI fork ; Divide the current process into two: child and parent.
        CMP EAX,0
        JNZ Parent:
        ; I am in the child process which will be transformed to "myecho" soon.
        LinAPI dup2,[FdMessages],1 ; Replace child's stdandard output with FdMessages.
        LinAPI execve, Command, Parameters, Environment ; Child becomes "myecho".
    Parent: ; Continue with parent process "myprog".
        LinAPI waitpid, -1, 0, 0  ; Wait until the child terminates.
        LinAPI close, [FdMessages]
        ; The file "messages.txt" is written now and it can be analyzed.