无法在RISC V组装中执行执行SYSCALL
我正在尝试通过汇编执行执行syscall。在开始之前,我已经从github存储库下载了RISCV工具链,并使用:./ configure/opt/rv32./configure -prefix =/prefix =/opt/rv32 -with-arch = rv32ia--使用-abi = ilp32
。 为了执行二进制文件,我正在使用qemu-user(qemu-riscv32
)。 好的,所以我首先写了一个简单的C程序,该程序执行了执行syscall。代码如下:
#include <unistd.h>
char *args[] = {"/bin/sh", 0x0};
int main()
{
execve(args[0], args, 0x0);
}
然后,我分解了生成的代码,我获得的是:
00010530 <main>:
10530: ff010113 addi sp,sp,-16
10534: 00112623 sw ra,12(sp)
10538: 00812423 sw s0,8(sp)
1053c: 01010413 addi s0,sp,16
10540: a9418793 addi a5,gp,-1388 # 85df0 <args>
10544: 0007a703 lw a4,0(a5)
10548: 00000613 li a2,0
1054c: a9418593 addi a1,gp,-1388 # 85df0 <args>
10550: 00070513 mv a0,a4
10554: 304160ef jal ra,26858 <__execve>
10558: 00000793 li a5,0
1055c: 00078513 mv a0,a5
10560: 00c12083 lw ra,12(sp)
10564: 00812403 lw s0,8(sp)
10568: 01010113 addi sp,sp,16
1056c: 00008067 ret
00026858 <__execve>:
26858: 0dd00893 li a7,221
2685c: 00000073 ecall
26860: fffff8b7 lui a7,0xfffff
26864: 00a8e463 bltu a7,a0,2686c <__execve+0x14>
26868: 00008067 ret
2686c: 71d0406f j 2b788 <__syscall_error>
26870: 00008067 ret
请注意,该代码是使用statation
flag编译的
,然后我尝试编写我的汇编程序,该程序基本上可以做相同的程序,因此我最终获得了以下代码:
.globl _start
.section .text
_start:
# execve syscall
la a0, shell # Pointer to '/bin/sh'
la a1, addr # Pointer to the arraythat contains '/bin/sh'
sw a0, 0(a1)
mv a2, x0 # No environment variables are needed
li a7, 0xDD # 221
ecall
# exit syscall
li a7, 0x5D # 93
ecall
.section .rodata
shell: .string "/bin/sh"
.section .data
addr: .space 4
然后,我将代码编译了以下语句:riscv32-Inknown-linux-gnu-gcc -c syscall.s&amp;&amp;&amp; RISCV32-INKNOWN-LINUX-GNU-LLD SYSCALL.O -O SYSCALL
现在,当我尝试执行C代码时,它可以完美地工作,甚至在没有static
标志的情况下编译代码,但是当我执行汇编代码时,它将返回242作为错误代码。在此之前,我一直在检查失败的执行程序产生的ERRNO代码,但我什么也没发现。 此外,我一直在搜索是否有人遇到了同样的问题,但不幸的是有人遇到了。 有什么想法吗?我想念什么还是错了? 谢谢
I am trying to perform the execve syscall via assembly. Before I start, I have downloaded the riscv toolchain from the github repo, and configured it using: ./configure /opt/rv32./configure --prefix=/opt/rv32 --with-arch=rv32ia --with-abi=ilp32
.
In order to execute the binaries, I'm using qemu-user (qemu-riscv32
).
Ok, so first I wrote a simple C program that performs an execve syscall. The code is the following:
#include <unistd.h>
char *args[] = {"/bin/sh", 0x0};
int main()
{
execve(args[0], args, 0x0);
}
Then I dissassembled the produced code, and what I obtained is:
00010530 <main>:
10530: ff010113 addi sp,sp,-16
10534: 00112623 sw ra,12(sp)
10538: 00812423 sw s0,8(sp)
1053c: 01010413 addi s0,sp,16
10540: a9418793 addi a5,gp,-1388 # 85df0 <args>
10544: 0007a703 lw a4,0(a5)
10548: 00000613 li a2,0
1054c: a9418593 addi a1,gp,-1388 # 85df0 <args>
10550: 00070513 mv a0,a4
10554: 304160ef jal ra,26858 <__execve>
10558: 00000793 li a5,0
1055c: 00078513 mv a0,a5
10560: 00c12083 lw ra,12(sp)
10564: 00812403 lw s0,8(sp)
10568: 01010113 addi sp,sp,16
1056c: 00008067 ret
00026858 <__execve>:
26858: 0dd00893 li a7,221
2685c: 00000073 ecall
26860: fffff8b7 lui a7,0xfffff
26864: 00a8e463 bltu a7,a0,2686c <__execve+0x14>
26868: 00008067 ret
2686c: 71d0406f j 2b788 <__syscall_error>
26870: 00008067 ret
Notice that the code has been compiled using -static
flag
Then I tried to write my assembly program that basically does the same, so I ended up with the following code:
.globl _start
.section .text
_start:
# execve syscall
la a0, shell # Pointer to '/bin/sh'
la a1, addr # Pointer to the arraythat contains '/bin/sh'
sw a0, 0(a1)
mv a2, x0 # No environment variables are needed
li a7, 0xDD # 221
ecall
# exit syscall
li a7, 0x5D # 93
ecall
.section .rodata
shell: .string "/bin/sh"
.section .data
addr: .space 4
Then, I compiled the code with the following statement: riscv32-unknown-linux-gnu-gcc -c syscall.s && riscv32-unknown-linux-gnu-ld syscall.o -o syscall
And now, when I try to execute my C code, it works perfectly, even compiling the code without -static
flag, but when I execute my assembly code it returns 242 as error code. Before that, I have been checking errno codes produced by a failed execve, but i found nothing.
In addition, I have been searching if someone has experienced the same problem but unfortunately anyone has.
Any idea? Is there something am I missing or am I wrong?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不是在告诉内核中有多少个条目。规则是,ARGV需要是一系列指针,其最后一个条目是无效的指针。如果您提供Envp,则对于ENVP参数也是如此。
我建议您在
.rodata
中使用前定性数组进行此操作,就像这样:然后您的代码可以是类似的东西
You're not telling the kernel how many entries there are in the argv array. The rule is that argv needs to be an array of pointers whose last entry is a NULL pointer. This would also be true for the envp argument if you were supplying an envp.
I'd suggest you do this with a preinitialized array also in
.rodata
, like so:and then your code can be something like