为什么在启用地址随机化的情况下此代码会崩溃? [英] Why does this code crash with address randomization on?

查看:89
本文介绍了为什么在启用地址随机化的情况下此代码会崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习amd64汇编程序,并试图实现一个简单的Unix过滤器.由于未知的原因,甚至简化为最低的最低版本(下面的代码),它也会随机崩溃.

I am learning amd64 assembler, and trying to implement a simple Unix filter. For an unknown reason, even simplified to the bare minimum version (code below), it crashes at random.

我试图在GNU调试器(gdb)中调试该程序.在gdb的默认配置中,该程序运行良好,但是如果启用地址随机化(set disable-randomization off),该程序将开始崩溃(SIGSEGV).清单中标记了有问题的说明:

I tried to debug this program in GNU Debugger (gdb). In the default configuration of gdb, the program runs fine, but if I enable address randomization (set disable-randomization off), the program starts crashing (SIGSEGV). The problematic instruction is marked in the listing:

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的数据,将其存储在堆栈中的缓冲区中,将读取的数据逐字节复制到输出缓冲区中,并将输出缓冲区的内容写入标准输出流.本质上,它应该表现为cat的受限版本.

This program is meant to read at most 64kB from stdin, store it into a buffer on the stack, copy the read data byte-by-byte into the output buffer and write the content of the output buffer to the standard output stream. Essentially, it should behave as a limited version of cat.

在我的计算机上,它要么按预期运行,要么因SIGSEGV崩溃,大约成功运行1次至崩溃4次.

On my computer, it either works as intended, or crashes with SIGSEGV, with an approximate rate of 1 successful run to 4 crashes.

推荐答案

amd64中的红色区域只有128个字节长,但是您使用的rsp以下是131072个字节.向下移动堆栈指针以包含要存储在堆栈上的缓冲区.

The red zone in amd64 is only 128 bytes long, but you're using 131072 bytes below rsp. Move the stack pointer down to encompass the buffers that you want to store on the stack.

这篇关于为什么在启用地址随机化的情况下此代码会崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆