Linux 将参数传递给execve syscall的最简单方法
据推测,将参数传递给execve系统调用非常简单 在一个教程中,讲师说它只在一行中,并将此作为练习 下面的代码执行“ls”命令。我正在尝试执行类似“ls-la”的操作。 搜索了又搜索,我仍然不知道在哪里添加“-la” 我知道它在ecx寄存器指向的结构中,并且必须以null结尾。目前,ecx包含到/bin/ls的地址。这些参数应该是另一个地址吗?argv是一个数组,第一个元素是“/bin/ls” 这不起作用:Linux 将参数传递给execve syscall的最简单方法,linux,assembly,x86,nasm,system-calls,Linux,Assembly,X86,Nasm,System Calls,据推测,将参数传递给execve系统调用非常简单 在一个教程中,讲师说它只在一行中,并将此作为练习 下面的代码执行“ls”命令。我正在尝试执行类似“ls-la”的操作。 搜索了又搜索,我仍然不知道在哪里添加“-la” 我知道它在ecx寄存器指向的结构中,并且必须以null结尾。目前,ecx包含到/bin/ls的地址。这些参数应该是另一个地址吗?argv是一个数组,第一个元素是“/bin/ls” 这不起作用: xor eax, eax push eax push 0x2a632020 push 0
xor eax, eax
push eax
push 0x2a632020
push 0x736c2f6e
push 0x69622f2f ; /bin/ls c*
mov ecx, esp
您必须将
-la
参数保存在ecx
寄存器中,并将其复制到esp
寄存器中(我的意思是在堆栈中)
以下是修改后的代码:
global _start
section .text
_start:
xor eax, eax
push eax
push byte 0x61
push word 0x6c2d
mov ecx, esp ; -la
push eax
push 0x736c2f6e
push 0x69622f2f ; //bin/ls
mov ebx, esp
push edx
push ecx
push ebx
mov ecx, esp
mov al, 11
int 0x80
代码工作正常:)
您必须将
-la
参数保存在ecx
寄存器中,并将其复制到esp
寄存器中(我的意思是在堆栈中)
以下是修改后的代码:
global _start
section .text
_start:
xor eax, eax
push eax
push byte 0x61
push word 0x6c2d
mov ecx, esp ; -la
push eax
push 0x736c2f6e
push 0x69622f2f ; //bin/ls
mov ebx, esp
push edx
push ecx
push ebx
mov ecx, esp
mov al, 11
int 0x80
代码工作正常:)
是的,它应该是一个单独的字符串,分别以null结尾,并且它自己的地址插入到
argv
数组中,该数组到目前为止只有{”//bin/ls“,null}
ecx
指向argv
,正如我已经说过的,它当前是{”//bin/ls“,null}
。您插入-la
使其看起来像{+//bin/ls“,“-la”,NULL}
是的,它是argv
的第一个元素,它本身是指向“//bin/ls”
的指针。哪个部分导致了您的问题?首先将字符串本身放在堆栈上(以null结尾),然后将该地址添加到数组中。@Jason什么syscall
用于x86_64,int 0x80
用于x86。如果他写的是64位代码,那么syscall
是正确的,但是对于32位代码int 0x80
是正确的。是的,它应该是一个单独的字符串,单独以null结尾,并且它自己的地址插入到argv
数组中,该数组到目前为止只有{”//bin/ls“,null}
ecx
指向argv
,它当前是{+//bin/ls”,NULL}
,正如我已经说过的那样。您插入-la
使其看起来像{+//bin/ls“,“-la”,NULL}
是的,它是argv
的第一个元素,它本身是指向“//bin/ls”
的指针。哪个部分导致了您的问题?首先将字符串本身放在堆栈上(以null结尾),然后将该地址添加到数组中。@Jason什么syscall
用于x86_64,int 0x80
用于x86。如果他写的是64位代码,那么syscall
是正确的,但是对于32位代码int0x80
是正确的。除了这不是ls-la
。您拥有的是ls-l
。您需要删除push 0x61
和push 0x6c2d
,并用单个push 0x006c612d
@DavidC.Rankin替换它们。如果您熟悉外壳代码
,可以避免空字节
,您可以使用strace
进行测试,结果是ls-la
这就是为什么你要确保它是最后一个字节:)
试试看。@DavidC.Rankin ahhh,好吧,它是ls-l
,很抱歉:DAlso,ls
接受冗余的单字母选项,这样你就可以推送-lla
。或者在需要获得奇数长度字符串的情况下,push'--la'
/shr-dword[esp],8
或其他。或者存储AL中的0
,以插入终止符。但是,push imm8/push word imm16也可以工作。但是请记住,推送字节0x61
仍然推送dword;NASM应该真正拒绝那里的字节
关键字,因为它不是有效的推送操作数大小push strict byte'a'
会告诉它您确实需要push imm8
编码,但是通过push'a'
或push dword'a'
,您还是可以得到它。但这不是ls-la
。您拥有的是ls-l
。您需要删除push 0x61
和push 0x6c2d
,并用单个push 0x006c612d
@DavidC.Rankin替换它们。如果您熟悉外壳代码
,可以避免空字节
,您可以使用strace
进行测试,结果是ls-la
这就是为什么你要确保它是最后一个字节:)
试试看。@DavidC.Rankin ahhh,好吧,它是ls-l
,很抱歉:DAlso,ls
接受冗余的单字母选项,这样你就可以推送-lla
。或者在需要获得奇数长度字符串的情况下,push'--la'
/shr-dword[esp],8
或其他。或者存储AL中的0
,以插入终止符。但是,push imm8/push word imm16也可以工作。但是请记住,推送字节0x61
仍然推送dword;NASM应该真正拒绝那里的字节
关键字,因为它不是有效的推送操作数大小push strict byte'a'
会告诉它您确实需要push imm8
编码,但是通过push'a'
或push dword'a>您还是可以得到它。
global _start
section .text
_start:
xor eax, eax
push eax
push byte 0x61
push word 0x6c2d
mov ecx, esp ; -la
push eax
push 0x736c2f6e
push 0x69622f2f ; //bin/ls
mov ebx, esp
push edx
push ecx
push ebx
mov ecx, esp
mov al, 11
int 0x80
% ./list
total 4
-rwxrwxr-x 1 febri febri 512 Oct 5 07:45 list
%