来自Assembly的execve系统调用
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
运行你的可执行文件来看到这一点。)
有三个问题:
.ascii
不会0-终止字符串。 (你可能会很幸运,因为在这个例子中你的.data
节没有任何内容,但这并不能保证......)添加一个0,或者使用.asciz
(或.string
)。
movl file_to_run, %edi
将file_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
实际上,您不需要在其他参数中加载任何内容。 如果你在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终端。
链接地址: http://www.djcxy.com/p/80339.html上一篇: execve system call from Assembly
下一篇: Recognizing stack frames in a stack using saved EBP values