我试图打开/dev/random
,从中读取一个字节并以x86程序集中的状态退出...
这似乎返回了随机数,但我不确定它是否符合我的想法。
# Where do we get our random numbers from
.data
random: .ascii "/dev/random\0"
# Program goes here
.text
.global _start
_start:
# Get /dev/random fd
movl $5, %eax # sys_open (originally $0 by accident)
movl $random, %ebx # Filename string
movl $0, %ecx # O_RDONLY flag
int $0x80
# Read one byte onto stack
movl %eax, %ebx # The result of sys_open
movl $3, %eax # sys_read
subl $1, %esp # Make stack space
movl %esp, %ecx # Make stack our buffer
movl $1, %edx # size_t bytes? only 1
int $0x80
# Exit with a random result
movl %esp, %ebx # random result as exit status
movl $1, %eax # sys_exit
int $0x80
当我通过strace
运行时,我得到以下回复:
execve("./random", ["./random"], [/* 44 vars */]) = 0
fstat(0, NULL) = 3
close(0) = -1 EFAULT (Bad address)
write(0, NULL, 1 <unfinished ...>
+++ exited with 12 +++
注意缺少open()
和read()
!此外,exit()
去了哪里?
我做错了什么?
答案 0 :(得分:1)
要进行系统调用,您必须遵循内核的系统调用API。由于我不知道它是什么,我总是look it up online。然后我发现sys_open
应该是这样的:
mov $5, %eax ;; syscall number "open"
mov $random, %ebx ;; arg 1: char * filename
mov $0, %ecx ;; arg 2: int flags
int $0x80
答案 1 :(得分:0)
在参考文献中我有edx寄存器需要文件打开模式掩码。
此外,您在添加1后永远不会恢复sp。
我也会减去/添加4而不是1. Linux可能不适用于未对齐的esp值。
此外,您似乎正在返回esp的低字节而不是esp中的内存。将%esp放入parens中的movl指令中。
答案 2 :(得分:0)
确定。谢谢大家。
minuteman3建议使用pop
。虽然它没有直接解决我的问题,但它导致我另一个涉及在64位机器上使用32位代码。很少有汇编程序标志以后一切正常。以下是感兴趣的人的最终代码:
# Where do we get our random numbers from
.code32
.data
random: .ascii "/dev/random\0"
# Program goes here
.text
.global _start
_start:
# Get our random number
movl $5, %eax # sys_open
movl $random, %ebx # Filename string
movl $0, %ecx # O_RDONLY flag
int $0x80
# Read one random number
movl %eax, %ebx # The result of sys_open
movl $3, %eax # sys_read
pushl $0 # Make space on stack and clear it
movl %esp, %ecx # The stack is our buffer
movl $1, %edx # size_t bytes?
int $0x80
# Exit with a random result
popl %ebx # Get the number back
movl $1, %eax # sys_exit
int $0x80
用
编译as random.s --32 -W -g -o random.o && ld random.o -o random -melf_i386