Linux 在汇编中执行execve系统调用后,如何将其输出返回寄存器或堆栈?
我在汇编中编写代码,试图找出如何执行execve系统调用,但我不想将输出打印到终端,而是想知道它存储在哪里,以便以后可以使用,就像管道命令一样 例如,下面是通过execve执行命令'which'的程序集,实际上是执行命令'$which ls':Linux 在汇编中执行execve系统调用后,如何将其输出返回寄存器或堆栈?,linux,assembly,system-calls,shellcode,execve,Linux,Assembly,System Calls,Shellcode,Execve,我在汇编中编写代码,试图找出如何执行execve系统调用,但我不想将输出打印到终端,而是想知道它存储在哪里,以便以后可以使用,就像管道命令一样 例如,下面是通过execve执行命令'which'的程序集,实际上是执行命令'$which ls': GLOBAL _start SECTION .TEXT _start: XOR EAX,EAX PUSH EAX PUSH 0x68636968 PUSH 0x
GLOBAL _start
SECTION .TEXT
_start:
XOR EAX,EAX
PUSH EAX
PUSH 0x68636968
PUSH 0x772f6e69
PUSH 0x622f7273
PUSH 0x752f2f2f
MOV EBX, ESP
PUSH EAX
PUSH 0x736c
MOV ESI, ESP
XOR EDX, EDX
PUSH EDX
PUSH ESI
PUSH EBX
MOV ECX, ESP
MOV AL, 0x0B; EXECVE SYSCALL NUMBER
INT 0x80
第7-10行将/usr/bin/which
的地址推送到堆栈上,第13行将参数ls
推送到堆栈上。然后,它将参数数组推送到堆栈上,并将其存储在ECX中,EBX指向/usr/bin/which
,EAX设置为execve系统调用的系统调用号0xb(11)。执行时,它返回我们要求它查找的/bin/ls
,即ls
的位置
如何将
/bin/ls
的结果存储到其他地方以供使用?比如,如果我想继续编写代码,并将返回的代码作为下一段代码的一部分使用,那么如何将返回的值保存在寄存器或堆栈中?基本上,您必须执行以下操作:
pipe()
系统调用进行fifofork()
关闭子进程。在父进程中,这将返回您需要记住的子进程ID。在子对象中,该值返回零dup2()
将管道的写入端移动到文件描述符1。然后关闭管道的原始文件描述符execve
要运行的程序。请注意,execve
将当前进程替换为一个新映像,因此我不确定您对上一个程序的预期效果如何read()
返回零)。你读的是孩子的标准输出。将该输出存储在缓冲区中wait()
收集到孩子的退出状态。如果不这样做,死子进程将作为僵尸在进程表中徘徊,占用资源除了管道之外,您还可以
open()
将输出写入的文件。这样做的好处是,您可以使用fstat()
了解进程写入了多少输出。但是,您需要实现类似于tmpfile
函数的逻辑来创建和打开临时文件。基本上,您必须执行以下操作:
pipe()
系统调用进行fifofork()
关闭子进程。在父进程中,这将返回您需要记住的子进程ID。在子对象中,该值返回零dup2()
将管道的写入端移动到文件描述符1。然后关闭管道的原始文件描述符execve
要运行的程序。请注意,execve
将当前进程替换为一个新映像,因此我不确定您对上一个程序的预期效果如何read()
返回零)。你读的是孩子的标准输出。将该输出存储在缓冲区中wait()
收集到孩子的退出状态。如果不这样做,死子进程将作为僵尸在进程表中徘徊,占用资源除了管道之外,您还可以
open()
将输出写入的文件。这样做的好处是,您可以使用fstat()
了解进程写入了多少输出。但是,您需要实现类似于tmpfile
函数的逻辑来创建和打开临时文件。除非失败,否则不会返回.execve的可能副本。除非失败,否则不会返回.execve的可能副本。