Linux 将参数传递给execve syscall的最简单方法

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

据推测,将参数传递给execve系统调用非常简单

在一个教程中,讲师说它只在一行中,并将此作为练习

下面的代码执行“ls”命令。我正在尝试执行类似“ls-la”的操作。 搜索了又搜索,我仍然不知道在哪里添加“-la”

我知道它在ecx寄存器指向的结构中,并且必须以null结尾。目前,ecx包含到/bin/ls的地址。这些参数应该是另一个地址吗?argv是一个数组,第一个元素是“/bin/ls”

这不起作用:

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
%