linux – 为什么这段代码会因地址随机化而崩溃?
作者:互联网
我正在学习amd64汇编程序,并试图实现一个简单的Unix过滤器.由于未知原因,即使简化为最低版本(下面的代码),它也会随机崩溃.
我试图在GNU Debugger(gdb)中调试这个程序.在gdb的默认配置中,程序运行正常,但如果我启用地址随机化(设置禁用 – 随机化关闭),程序将开始崩溃(SIGSEGV).有问题的指令在清单中标出:
format ELF64 executable
sys_read = 0
sys_write = 1
sys_exit = 60
entry $
foo:
label .inbuf at rbp - 65536
label .outbuf at .inbuf - 65536
label .endvars at .outbuf
mov rbp, rsp
mov rax, sys_read
mov rdi, 0
lea rsi, [.inbuf]
mov rdx, 65536
syscall
xor ebx, ebx
cmp eax, ebx
jl .read_error
jz .exit
mov r8, rax ; r8 - count of valid bytes in input buffer
xor r9, r9 ; r9 - index of byte in input buffer, that is being processed.
xor r10, r10 ; r10 - index of next free position in output buffer.
.next_byte:
cmp r9, r8
jg .exit
mov al, [.inbuf + r9]
mov [.outbuf + r10], al ;; SIGSEGV here in GDB
inc r10
inc r9
jmp .next_byte
.read_error:
mov rax, sys_exit
mov rdi, 1
syscall
.exit:
mov rax, sys_write
mov rdi, 1
lea rsi, [.outbuf]
mov rdx, r10
syscall
mov rax, sys_exit
xor rdi, rdi
syscall
该程序旨在从stdin读取最多64kB,将其存储到堆栈中的缓冲区中,将读取的数据逐字节复制到输出缓冲区中,并将输出缓冲区的内容写入标准输出流.从本质上讲,它应该表现为猫的有限版本.
在我的计算机上,它可以按预期工作,或者与SIGSEGV崩溃,大约1次成功运行到4次崩溃.
解决方法:
amd64中的红色区域只有128个字节长,但是你使用的是低于rsp的131072个字节.向下移动堆栈指针以包含要存储在堆栈中的缓冲区.
标签:linux,x86-64,fasm 来源: https://codeday.me/bug/20190928/1825210.html