无法在RISC V组装中执行执行SYSCALL

发布于 2025-02-08 17:05:53 字数 2469 浏览 2 评论 0原文

我正在尝试通过汇编执行执行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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北城孤痞 2025-02-15 17:05:53

您不是在告诉内核中有多少个条目。规则是,ARGV需要是一系列指针,其最后一个条目是无效的指针。如果您提供Envp,则对于ENVP参数也是如此。

我建议您在.rodata中使用前定性数组进行此操作,就像这样:

    .section .rodata
shell:
    .string "/bin/sh"
    .balign 4
argv:
    .4byte shell
    .4byte 0

然后您的代码可以是类似的东西

    .section .text
    .globl _start
    .type _start, @function
_start:
    # execve syscall
    la a0, shell # Pointer to '/bin/sh'
    la a1, addr  # Pointer to the array that contains '/bin/sh'
    li a2, 0     # No environment variables
    li a7, 0xDD  # 221 = execve
    ecall
    # _exit syscall
    # if execve returns, it failed, so pass 1 to _exit
    li a0, 1
    li a7, 0x5D  # 93 = _exit
    ecall

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:

    .section .rodata
shell:
    .string "/bin/sh"
    .balign 4
argv:
    .4byte shell
    .4byte 0

and then your code can be something like

    .section .text
    .globl _start
    .type _start, @function
_start:
    # execve syscall
    la a0, shell # Pointer to '/bin/sh'
    la a1, addr  # Pointer to the array that contains '/bin/sh'
    li a2, 0     # No environment variables
    li a7, 0xDD  # 221 = execve
    ecall
    # _exit syscall
    # if execve returns, it failed, so pass 1 to _exit
    li a0, 1
    li a7, 0x5D  # 93 = _exit
    ecall
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文