我正在嘗試通程序式集執行 execve 系統呼叫。在開始之前,我已經從 github repo 下載了 riscv 工具鏈,并使用:./configure /opt/rv32./configure --prefix=/opt/rv32 --with-arch=rv32ia --with-abi=ilp32. 為了執行二進制檔案,我使用了 qemu-user ( qemu-riscv32)。好的,所以首先我撰寫了一個簡單的 C 程式來執行 execve 系統呼叫。代碼如下:
#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
請注意,代碼已使用-static標志編譯
然后我嘗試撰寫基本上相同的匯編程式,所以我最終得到以下代碼:
.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-unknown-linux-gnu-gcc -c syscall.s && riscv32-unknown-linux-gnu-ld syscall.o -o syscall
現在,當我嘗試執行我的 C 代碼時,它運行良好,甚至編譯沒有-static標志的代碼,但是當我執行我的匯編代碼時,它回傳 242 作為錯誤代碼。在此之前,我一直在檢查一個失敗的 execve 產生的 errno 代碼,但我什么也沒找到。另外,我一直在尋找是否有人遇到過同樣的問題,但不幸的是有人遇到過。任何想法?我有什么遺漏還是我錯了?謝謝
uj5u.com熱心網友回復:
您沒有告訴內核 argv 陣列中有多少條目。規則是 argv 需要是一個指標陣列,其最后一個條目是 NULL 指標。如果您提供 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/492919.html
上一篇:如何在32位保護模式下列印新行
