首页 文章

来自Assembly的sys_execve系统调用

提问于
浏览
4

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);

系统调用参数有问题吗?

2 回答

  • 10

    正在调用 execve 系统调用,但您确实传递了错误的参数 .

    (您可以通过使用strace运行可执行文件来查看此内容 . )

    有三个问题:

    • .ascii 不会终止字符串 . (你可能会很幸运,因为在这个例子的 .data 部分中没有任何内容,但是不能保证...)添加0,或者使用 .asciz (或 .string )代替 .

    • movl file_to_run, %edifile_to_run 符号指向的值移动到 %edi ,即字符串的前4个字节( 0x6e69622f ) . 字符串的地址只是符号本身的值,因此您需要使用 $ 前缀作为文字值: movl $file_to_run, %edi . 同样,你需要说几行 movl $file_to_run, %ebx . (这是AT&T语法和Intel语法之间混淆的常见原因!)

    • 参数以错误的顺序放在堆栈中: -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
    
  • 1

    实际上你不需要在其他参数中加载任何东西 . 如果您在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终端 .

相关问题