簡體   English   中英

來自Assembly的sys_execve系統調用

[英]sys_execve system call from Assembly

asm_execve.s:

.section .data
file_to_run:
.ascii       "/bin/sh"

.section .text
.globl main

main:
    pushl %ebp
    movl %esp, %ebp
    subl $0x8, %esp         # array of two pointers. array[0] = file_to_run  array[1] = 0

    movl file_to_run, %edi
    movl %edi, -0x4(%ebp)   
    movl $0, -0x8(%ebp)

    movl $11, %eax                      # sys_execve
    movl file_to_run, %ebx              # file to execute       
    leal -4(%ebp), %ecx                 # command line parameters
    movl $0, %edx                       # environment block
    int  $0x80              

    leave
    ret

生成文件:

NAME = asm_execve
$(NAME) : $(NAME).s
    gcc -o $(NAME) $(NAME).s

程序已執行,但未調用sys_execve:

alex@alex32:~/project$ make
gcc -o asm_execve asm_execve.s
alex@alex32:~/project$ ./asm_execve 
alex@alex32:~/project$

預期產出是:

alex@alex32:~/project$ ./asm_execve 
$ exit
alex@alex32:~/project$

這個匯編程序應該像下面的C代碼一樣工作:

char *data[2];
data[0] = "/bin/sh"; 
data[1] = NULL;
execve(data[0], data, NULL);

系統調用參數有問題嗎?

execve系統調用調用,但你確實傳遞錯誤參數。

(您可以通過使用strace運行可執行文件來查看此內容。)

有三個問題:

  1. .ascii不會終止字符串。 (你可能會很幸運,因為在這個例子中你的.data部分沒有任何內容,但是不能保證......)添加0,或者使用.asciz (或.string )代替。

  2. movl file_to_run, %edifile_to_run符號指向的值移動到%edi ,即字符串的前4個字節( 0x6e69622f )。 字符串的地址只是符號本身的值,因此您需要使用$ prefix作為文字值: movl $file_to_run, %edi 同樣,你需要說一下movl $file_to_run, %ebx幾行。 (這是AT&T語法和Intel語法之間混淆的常見原因!)

  3. 參數以錯誤的順序放置在堆棧中: -0x8(%ebp)是低於-0x4(%ebp)地址。 因此,命令字符串的地址應寫入-0x8(%ebp) ,0應寫入-0x4(%ebp) ,而leal指令應為leal -8(%ebp), %ecx


固定代碼:

.section .data
file_to_run:
.asciz       "/bin/sh"

.section .text
.globl main

main:
    pushl %ebp
    movl %esp, %ebp
    subl $0x8, %esp         # array of two pointers. array[0] = file_to_run  array[1] = 0

    movl $file_to_run, %edi
    movl %edi, -0x8(%ebp)   
    movl $0, -0x4(%ebp)

    movl $11, %eax                      # sys_execve
    movl $file_to_run, %ebx              # file to execute       
    leal -8(%ebp), %ecx                 # command line parameters
    movl $0, %edx                       # environment block
    int  $0x80              

    leave
    ret

實際上你不需要在其他參數中加載任何東西。 如果您在x86中執行此操作,則以下更簡單的代碼也將起作用:

.global _main
.section .text

.data
file_to_run:
.asciz "/bin/sh"

.section .text
.globl main

_main:
pushl %ebp
movl %esp, %ebp

movl $11, %eax                      # sys_execve
movl $file_to_run, %ebx              # file to execute       
movl $0, %ecx                       # Null value will work too
movl $0, %edx                       # Null will works too
int  $0x80              

leave
ret

這將在調用系統調用后基本上打開一個shell終端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM